javascript

Будни разработки моего онлайн-САПР КонтрБагCAD

  • четверг, 26 марта 2026 г. в 00:00:04
https://habr.com/ru/companies/timeweb/articles/1006682/

Про начало разработки я писал в предыдущей статье. Напомню — я разрабатываю простенький 3D-редактор для моделирования под 3D-печать. С простым интерфейсом и, самое главное, работой прямо в браузере. Естественно, это будет не полноценная САПР, но для обучения и простенького проектирования функционала должно хватать.

Целился я в нечто среднее между Tinkercad и Fusion360. Одной из задач было обойтись без сервера, т.е. работа на стороне клиента, а также быстрая работа. Поэтому в качестве основы я выбрал популярную библиотеку 3D-графики Three.js.

На момент написания статьи уже 0.9.11 версия
На момент написания статьи уже 0.9.11 версия


Изначально проект планировался как простенький 3D-редактор, а-ля Tinkercad, но на стероидах, с чертежами, фасками и другими продвинутыми операциями.

После предыдущей статьи вектор разработки немного сменился. Народ захотел полноценный САПР, прямо в браузере, прям как onshape. Правда onshape (и большинство подобных решений) работает не совсем в браузере, это тонкий клиент, который работает на серверах, а пользователю выводит просто картинку.

У меня на данный момент сервера нет. Для работы моего редактора он практически не нужен. Но об этом чуть позже.

В общем, вектор развития из «сделано на коленке» перешел к «народ начал пользоваться, надо сделать нормально». Поэтому я решил сделать несколько глобальных изменений, чтобы обеспечить моему редактору будущее.

❯ Архитектура редактора

КонтрБагCAD работает целиком на клиенте, со всеми преимуществами и недостатками. В качестве геометрии, в отличии от большинства САПР, используются сетки, а не BREP. Это сделано в угоду легкости и скорости работы (у Tinkercad, кстати, тоже сетки). Благодаря этому STL и прочие сеточные форматы поддерживаются напрямую, и нет никаких проблем их редактировать (в отличии от того же Fusion 360). Ядро работает напрямую на Three.js. Начиная с версии 0.8, для бинарных операций внедрена библиотека manifold, а начиная с 0.9 ядро переписано на параметрическую работу.

Итак, после предыдущей статьи многое произошло...

Для начала, я занялся поиском проблемы дырявых моделей. Я долгое время думал, что дело в экспорте, но оказалось, беда в той самой «крутой» библиотеке THREE_BVH_CSG, которую я в прошлый раз расхваливал. Проблема в том, что при применении бинарной операции она гарантированно строит сломанную модель из несвязанных треугольников, в редакторе этого не видно, но на экспорте проявляется. И алгоритм обводки граней из-за этого правильно не работает.

Слева модель после экспорта, справа результат обводки
Слева модель после экспорта, справа результат обводки

Проблема решилась использованием уже по-настоящему крутой библиотеки Manifold.

Manifold — это высокопроизводительная библиотека для создания и обработки трёхмерной геометрии, ориентированная на твердотельное моделирование.

Основные особенности:

  • Ядро на C++ с WebAssembly-сборкой, что обеспечивает скорость работы в браузере и Node.js.

  • Гарантия манифолдности — все модели всегда замкнуты (watertight) и корректны с топологической точки зрения.

  • Булевы операции (объединение, пересечение, вычитание) с высокой надёжностью.

  • Построение геометрии: экструзия, вращение (revolve), создание примитивов.

  • Работа с mesh — импорт/экспорт, редактирование, упрощение.

На данный момент — это быстрейшая библиотека для бинарных операций над сеточной геометрией. Она значительно быстрее OpenSCAD и большинства аналогичных библиотек. При этом гарантированно строит водонепроницаемую геометрию. У меня она пока используется только для бинарных операций. Благодаря этому скорость бинарных операций значительно выросла и заметно обходит Tinkercad.

Из минусов: библиотека требует манифольдные (водонепроницаемые) меши для работы, а множество stl в сети такими не являются. Для решения этой проблемы я занялся написанием инструмента для ремонта геометрии, но пока он чинит только простые случаи.

❯ Про параметрическую работу

Итак, до версии 0.9 история у меня хранилась слепками сцены. Это было сложнее, чем сейчас (скрипты были здоровыми, и с проблемами), и жрало много памяти. Проект сохранялся по сути полной геометрией сцены. А из-за того, что история хранила слепки сцены, в сохранении она занимала какие-то неадекватные размеры. Я даже добавил опцию «не сохранять историю», дабы файлы сохранений меньше занимали.

Оценив все недостатки этого подхода, я решил всё-таки перейти на параметрическую работу, и для каждой операции использовать отдельный исполнитель, который совершает эту операцию по переданным параметрам. Это потребовало переписывания практически всего проекта, но зато история у меня теперь хранится просто списком операций с параметрами. А для сохранения, по сути, этот список просто экспортируется. Благодаря этому, файлы проекта похудели в десятки раз (на самом деле все немного сложнее, но в целом так как я описал :)

А бонусом появилась куча дополнительных возможностей, вроде изменения параметров уже сделанных операций, вставка и удаление операций, простого объединения проектов или вообще совместной работы нескольких пользователей. Но это все ещё в будущем, а пока только можно просто удалить любую операцию. Ещё можно вставлять операции в любое место истории, но это пока выключено.

Подумаю, как лучше реализовать изменения параметров операций и надо ли оно вообще.

❯ Изменения

Переход на новую архитектуру, естественно, вызвал кучу багов (большинство которых уже были решены в прошлом), и занял полную неделю работы (даже более, на самом деле я их до сих пор фикшу).

Определение регионов вытягивания переехало в скетч, и теперь происходит сразу после добавления элементов чертежей. А заодно появилась подсветка этих регионов, и был доработан алгоритм определения (но над этой задачей я все ещё бьюсь).

В старом инструменте вращения неправильно формировались крышки фигуры и отверстия, это тоже было доработано. Но надо ещё поработать над спаиванием.


В выдавливании появилось визуальное отображение операции: красный — вырезать, желтый — добавить, зелёный — новый объект. Как светофор.

Самое крутое — я убрал этот позорный крест навигации и сделал великолепный куб :D
Он поддерживает смену темы, смену языка и просто красиво выглядит. Для этого пришлось делать менеджер камеры, зато теперь все настройки камеры управляются из одного места.

А, да, появилась смена языка. Причём локализации являются просто json-файлом и нет никакой проблемы добавить в редактор любой язык (даже русский матерный, или старославянский).

❯ ES6 архитектура

Я не фронтендер — за современное развитие js не шарил. Поэтому начал писать проект на старом стеке с подключением всех файлов глобально. Когда этих файлов стало больше 120, это стало уже неудобно, и развивать проект в таком виде было не рационально. К тому же, все современные библиотеки поддерживают подключение только модулями (кто бы мог подумать).
Короче, я решил переписать проект на ES6 модельную архитектуру, заодно сделать рефакторинг и ещё немного приблизить его к принципам SOLID.

В целом это было не особо сложно, проект уже был модульным (неспроста было 120+ файлов). Оставалось просто дописать все подключения, и переписать пару скриптов. С этим я справился за пару дней.

Пожалуй, больше заморочек вызвало обновление с three150 на three182. Возникло несколько проблем:

  • Cмена цветового пространства с linearRGB на sRGB в three 152, из за этого все цвета стали темными и блеклыми, пришлось долго играться с настройками.

  • Многие библиотеки вынесли из основной сборки Three, в отдельные библиотеки, что в целом логично.

  • И в 3D-тексте они зачем-то переименовали параметр толщины, с heights на depth. Из-за чего перестало работать изменение толщины, а я с этим долго разбирался.

❯ Инструменты

Чертеж теперь можно строить сразу на гранях объектов.

При клике сразу открывается режим чертежа и обводится грань, на которой вы его строите. Все замкнутые фигуры, которые можно вытянуть, теперь закрашиваются. Для тестирования я сделал цвет заливки рандомный, но аудитории в ТГ зашло, поэтому решил оставить, но сделать зависимым от площади, чтобы не менялся).

Пока над распознаванием регионов я ещё работаю, это не самый простой алгоритм, в котором надо слишком много всего учесть. Кстати, при вытягивании надо наоборот правильно соединить фигуры, и там тоже довольно сложный алгоритм (может про это когда-нибудь напишу отдельную статью).

Еще я заморочился над инструментом бинарных операций. У старого варианта не было предпросмотра, для объединения и пересечения это приемлемо, но с вычитанием не особо понятно, что из чего вычитается.

Теперь получилось прям круто, включить инструмент можно без выделенных объектов, кликом на ЛКМ фигура добавляется в операцию, повторным кликом исключается.

В вычитании ещё задействована ПКМ для добавления вычитаемых фигур.

Прокачал библиотеку, теперь каждая категория грузится только при переходе на нее и из отдельного каталога. В каждом каталоге лежит json со списком моделей, а каталоги и категории прописаны в отдельном «главном» json.

Поддерживается работа с удаленными каталогами, и объединение несколько категорий в одну (собственно, категория «все» так и сделана. Но она временная, пока моделей не много). Заодно подтянул немного дизайн, теперь на экран помещается больше моделей и библиотека немного больше напоминает Tinkercad.

Также, специально по просьбам пользователей Tinkercad, добавил инструмент выравнивания.

По выровненным осям маркеры гаснут
По выровненным осям маркеры гаснут

И доработал параметрическую операцию создания примитивов. Раньше половина примитивов были обычными stl, теперь для них написаны отдельные параметрические генераторы. Заодно добавил в параметрическую модель метод изменения параметров операции. Правда пока это работает только для примитивов.

Для каждого примитива можно изменить высоту, ширину и прочие параметры
Для каждого примитива можно изменить высоту, ширину и прочие параметры

На этом все изменения за февраль и начало марта, на самом деле ещё куча всяких мелких изменений, про которые я не написал. В тг-канале сообщения об обновлениях выходят практически каждый день.

Была проделана действительно большая работа, особенно в части основ редактора.

Редактор доступен online, без регистрации и совершенно бесплатно.

Обратите внимание! Редактор находится на стадии активной разработки, постоянно становится лучше и пополняется новыми функциями.

Буду благодарен за обратную связь, сообщения об ошибках и предложения по развитию :)


Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале 

Перейти ↩