Afina-Scala или как я софт для проектирования лестниц написал
Пару лет назад, когда понадобилось строить лестницу себе в дом, я обратился в контору. Приехали ребята, замерили, через пару недель привезли лестницу из металла, смонтировали. И вот в процессе зашёл разговор о том, как они делают чертежи для станков, производят расчёты и насколько это всё непросто. И что для этого нужны спецы, которые шарят в AutoCAD или 3ds Max.
Хм... подумал я, так тут же нефиг делать — написать программу, которая будет считать лестницы, раз плюнуть. Скажем так — я несколько ошибался в размере геморроя, который меня ждал.
В начале казалось, что всё просто — хотелось получить на выходе онлайн-сервис, в который забиваешь размеры помещения, куда нужно всунуть лестницу, выбираешь формат лестницы, прога считает, выдаёт полные чертежи для лазерной резки и 3D-модели. В рунете есть два проекта: «Житов» и «КалкПро», которые считают лестницы, но по их расчётам собрать лестницу без доработки чертежей невозможно. Как базу использовать удобно. Идея была сделать инструмент, который выдаст полные детализированные чертежи, которые берёшь и сразу — на лазер. Да так, чтобы в три клика... Забегу вперёд — всё это получилось.
Так вот, пока я смотрел на эти инструменты, закрались у меня смутные сомнения: а чего это они не делают детальных чертежей?..
То, что умеет Афина:
А теперь о грустном... Моё последнее общение с 3D было во времена DirectX 7 на православном C++ (тут должна быть песенка про мой 2007). Какие-то знания о матрицах вращения, аффинных преобразованиях ещё оставались в голове, но где-то на уровне знания, что такие есть. За годы работы в вебе и пачканья об PHP всё это бесследно испарилось. Ну, а вспоминать молодость и красноглазить на плюсах — вообще, я стар. Поэтому стэк разработки испортился о мой опыт в вебе и получился такой:
GO — на сервере считаем геометрию.
ThreeJS — основная библиотека для рендера.
Webix — набор для GUI.
PostgreSQL — как база.
Присыпаем всё это дело nginx + LibreCAD.
Добавим полтора года разработки где-то между работой и сном...
Вжух — и в браузере мы получаем 3D-редактор, который в три клика моделирует лестницы под нужные размеры.
Ключевые моменты, или почему получилось
В начале пути мне удалось подключить к проекту единомышленника — моего сэнсэя и учителя, который давно ушёл из профессии, но когда-то во времена Turbo Pascal обучал меня премудростям циклов, условий и алгоритмов сортировки. Эх, детство, детство... Пришлось его вернуть в профессию, обучить Go и современным реалиям. Без него проект бы не получился, я бы просто забил.
Неправильная оценка сроков — казалось, что тут работы на пару месяцев по вечерам. Если бы я знал, что работа займёт полтора года при отсутствии всякого финансирования, на чистом энтузиазме, я бы никгда ее не начал. В моменты когда получался хороший результат и сроки оттягивались, сново делал прогноз и снова мимо )))
Магия 3D — последние годы работы у меня прошли где-то между базами данных и бизнес-логикой. Это настолько скучно, что возможность увидеть на экране какой-то осязаемый результат очень вдохновляла. Мы делали — видели результат, и это заставляло двигаться дальше.
Новые задачи — это было интересно. Даже просто посчитать объём произвольной трёхмерной фигуры — это задачка для мозгов.
Технологии — если бы мы попытались решить эту задачу лет 15 назад, то размер геморроя был бы в разы больше. Сейчас всё сильно проще.
Отсутствие сроков — над нами никто не стоял, не требовал сделать всё ко вчерашнему дню. Можно было взять паузу в неделю или две. В целом мы работали над тем, что нас прёт.
Нам никто не сказал что это сложно - и это главное, когда появлялись задачи которые мы не могли решить, в голове появлялась мысль - ну чтож, разберусь давайка посмотрим подумаем как это можно сделать. Иногда выходили велосипеды - на них мы и ездим.
С чего все начиналось
Вообще нужно взять длинну и высоту лестницы, разбить на число ступенек, расчитать из этого размер ступеньки и вуаля.. дальше каким то образом нарисовать ее в 3Д. В первых попытках, это выглядело довольно просто и комично
Если в 2D рисовать чертежи по точкам мы худо-бедно смогли, то вот сложить это всё в 3D получилось не сразу. Первые попытки рендера...
Тут, чтобы увидеть детали лестницы нужна была фантазия. Но немного поразбиравшись, дело пошло веселее
Под капотом это работает так: на вход программы подаются габаритные размеры. Мы в 2D создаём контур детали по точкам. Из этого контура формируются 3D-модели каждого элемента лестницы, потом они собираются воедино и расставляются по своим местам, рендерим результат. Первые версии программы выглядели так:
Да, это была просто форма с небольшим набором параметров для расчёта и жёсткой логикой. По сути — некий набор функций.
Сразу всплывала куча вопросов: а что если пользователь захочет сделать вынос ступени, или изменить их размеры, или ему нужно проделать отверстия для крепления ограждений, или поменять тип ограждений, или у него черновой пол и нужно предусмотреть его размер, или высота лестницы ниже уровня перекрытия и нужно это учесть, или необходима различная толщина металла, или, или, или... В общем, набор параметров ограничивался только фантазией. Тут стало понятно, что подход, который мы используем, не позволит нам продвинуться дальше, чем вот такие модели, и именно поэтому аналоги, которые есть в интернете, не позволяют рассчитать детализированные чертежи — потому что вариативность очень высока. Как поддерживать этот набор функций, тоже было непонятно.
Пришлось взять паузу, чтобы подумать.
В итоге пришли к такой идее: у нас есть некий компонент — набор свойств, родителей и детей. Каждый компонент может обращаться к дереву компонентов по имени, классу или по другим параметрам, передавать им указания — например, «измени свои габаритные размеры на вот столько» или «используй такой тип крепежа». Интерфейс при выборе компонента автоматически отрисовывает формы ввода для свойств. У компонента может меняться набор дочерних компонентов — например, лестница может быть построена на прямых либо ломаных косоурах, тогда компонент «комната» просто получает другого ребёнка. У компонента есть эвенты (события), он может реагировать на какие-то события — например, компонент «косоур» может узнать о том, что изменился тип крепления. Компоненты связаны друг с другом не только в логическом дереве, но и геометрически: точка отсчёта координат для компонента зависит от его родителя.
Внутри компонента есть набор деталей (чертежей). Из деталей в компоненте формируются элементы (конкретные 3D-объекты) — т.е. деталь «ступенька» может наплодить десятки 3D-объектов.
В итоге я взял на себя роль разработчика фреймворка для всего этого дела и за месяц на кофе и сахаре выдал результат. Внутри серверной части получилась стройная конструкция, которая позволяла нам делать практически любую геометрию. В это же время и родилось название проекта — Afina-Scala: проектирование лестниц онлайн.
В интерфейсе это выглядит так: практически у каждого элемента в дереве компонентов своя форма с набором параметров.
Внутри кода, компонент инициализируется описанием структуры и по ней уже строится интерфейс и создаются различные свойства у объекта в памяти, к сожалению изза языка программирования полноценное ооп с наследованием и перегрузкой у нас отстутствует
Управление может показаться сложным, но из-за того что компоненты наследуются друг от друга и вложены, минимальный набор параметров можно задать по верхнему компоненту — «комната». Т.е. просто ввести 4 размера и получить детальный чертеж.
А так выглядят чертежи, это перемычка соединяющая косоуры. Вот эта перемычка это деталь в нашей логике, она представляет из себя структуру с интерфейсом определенных функций. Именно потому, что мы сначала чертим детали - в 3д получается полное соотвествие тому, что будет в реальности.
Функции, отвечающие за построение деталей, выглядят как бред сумасшедшего. Есть идея создать собственный графический язык и транслировать его в Go-код, который позволит расставлять точки и задавать их зависимости от других параметров. Например: расчертить контур, выбрать точки и указать, что они привязаны к каким-нибудь другим точкам. Спасает то, что часть кода удаётся наследовать и переиспользовать.
Дальше дело пошло быстрее, роли тоже разделились: я отвечал за внутренний фреймворк и рендер. Рендер, кстати, написан крайне плохо — можно сказать, что это просто черновик с набросками. А сэнсэй сконцентрировался на создании моделей — у него гораздо больше строительного опыта и работы со всякими снипами и ГОСТами, но меньше опыта в разработке ПО.
В итоге имеем 7 моделей лестниц.
Несколько скринов из рабочего чата








Всё это мы опробовали вживую: разработали лестницу (3 минуты на проектирование), заказали лазерную резку (примерно за 10 тысяч рублей), а ребята в автосервисе её сварили и покрасили.




Технолоджия
И как же обойтись без дополненной реальности? Выглядит это, конечно, эффектно, но реализация на ThreeJS занимает буквально десять строк кода — всё уже готово «из коробки». В текущей версии «Афины» дополненная реальность сделана несколько кривовато — нужно будет это поправить.
Как обстоят дела сейчас
Вчера открыл доступ к сайту — появилось 4 пользователя. Это, конечно, не YouTube, но уже близко :)
Никаких денег проект сейчас не приносит — можно бесплатно смоделировать себе лестницу и скачать результат.
Внутри огромное число багов и ещё больше новых идей. Например, сделать редактор контуров, чтобы можно было самостоятельно вычерчивать любые детали, а не только по заданным параметрам.
Поэтому если кому‑то интересен проект Afina‑Scala или хочется потыкать и покрутить лестницы — можно это сделать тут: https://afina-scala.ru/
Сервис работает только на десктопе, с мобильного устройства не пустит.
А если кто‑либо построит себе лестницу благодаря Афине — я буду только рад.
Кажется, у нас получается отличный инструмент. Я смотрю на аналоги и понимаю, что они не могут выдать такой же результат, хотя в начале пути я даже не знал, как нарисовать 3D‑куб в браузере.
Что касается AutoCAD, Компас‑3D и других — это очень взрослые программы, и на их поле я не лезу и даже не смотрю. Афина — всё‑таки сервис, который упрощает жизнь во многих случаях, но и имеет кучу ограничений. Её задача — рассчитать типовую лестницу по заданным параметрам, сделать это быстро и с детальными чертежами.
Всем добра!
































