К содержимому
itmarkov

Первая сборка своего CAD и мерка, которая соврала

Собрал сегодня рабочий каркас своего собственного 3D-редактора (параметрического CAD) на языке Rust и движке OpenCASCADE. Получился джентльменский набор инженера: рабочее окно, дерево деталей, эскизы с автоматическим выравниванием линий, выдавливание объёма, вырезание пазов, аккуратные скругления углов, сохранение проекта и экспорт в ходовые форматы STEP и STL. Прогнал 75 тестов — всё собралось идеально, компилятор даже бровью не повёл. Но главный жизненный урок дня прилетел вовсе не из учебников по геометрии.

Окно MAD-CAD: три верстака, дерево модели, деталь в рабочей области

Когда контролёр сам ослеп

В любой 3D-программе есть невидимая глазу рутина: прятать линии и рёбра, которые находятся на обратной стороне детали. Мы же не должны видеть сквозь сплошной металл?

Чтобы проверить, не халтурит ли отрисовка, я написал виртуального «ревизора» (мерку глубины). Логика простая: пускаем невидимый лазерный луч из точки взгляда прямо в ребро детали. Если на пути луча есть любая другая грань или стенка — ребро считается загороженным и на экране появляться не должно.

Запускаю проверку. Ревизор бьёт тревогу: «Катастрофа! Три ребра спрятаны за стенкой, но программа зачем-то нарисовала их поверх!»

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

Когда я начал разбираться, почему инспектор сошёл с ума, нашлись сразу три забавных бага в самой мерке:

  • Эффект натянутой верёвки: Чтобы не проверять каждый микроскопический миллиметр длинного ребра, мерка считала расстояние до середины как среднее арифметическое между его концами. Но в перспективе 3D-пространства это работает не так прямолинейно! Из-за нелинейного искажения мерка «думала», что середина отрезка провалилась вглубь на пару лишних миллиметров, и объявляла её перекрытой.
  • Взгляд сквозь затылок: Мерка учитывала даже те задние стенки детали, которые отвёрнуты от наблюдателя. Программа отрисовки их давно и благополучно выкинула из памяти, а наш контролёр всё ещё пытался ими что-то загородить.
  • Битва точек и пикселей: Мерка оценивала математически идеальные бесконечно тонкие точки, а монитор отображает жирные пиксели. Луч проверки проходил вскользь по самой кромке, цеплял соседнюю грань и паниковал: «Точка закрыта!», хотя на экране этот пиксель рисовался абсолютно справедливо.

Диагностика с ошибкой: узел не посчитан после обрыва контура

Как проверить самого проверяющего

Самый опасный тест — тот, который при любых условиях радостно рапортует: «Всё чисто, босс!». Если градусник всегда показывает 36.6, он, скорее всего, просто нарисован на стене.

Чтобы убедиться, что мерка реально ловит поломки, я устроил ей стресс-тест: добавил режим, который нарочно отключает сокрытие невидимых линий. И программа проверку на честность прошла: при выключенном режиме мерка возмутилась и насчитала 91 «незаконную» точку из 115, а при включённом — образцовый ноль. Значит, теперь контролёр действительно видит брак, а не придумывает его.

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

Нужна помощь с задачей?

Напишите — отвечу с решением и оценкой в течение рабочего дня.

Оставить заявку