Добавить в корзинуПозвонить
Найти в Дзене
3DTODAY

Реверс-инжиниринг по фотографии с ИИ

Приветствую коллеги! Небольшое вступление: в прошлом году сын подарил мне на день рождения принтер (Ender 3 V3 SE). Я, как и многие, начал пробовать: печатал разные коробочки, органайзеры. Ремонтировал, что раньше не представлял как отремонтировать, супруге печатал кашпо и горшочки для цветов. Попробовал кое-что из Мультиборда. В общем всякую фигню. В этом году сын подарил мне подписку на Claude Code (далее CC) (ИИ-агент и инструмент командной строки от компании Anthropic). И решил я напечатать ещё одну фигулинку: у меня были ласты, года 3-4 как была утеряна пряжка и ласты валялись без дела. Хотел сам отреверсить её во FreeCad-е, наверное смог бы, но подумал: а чего бы искуственному интеллекту не потрудиться. Сказано - сделано. Ниже пересказ СС, как он делал модель (да, я его попросил самого рассказать). Как мы вернули к жизни пряжку от ласт: реверс-инжиниринг по фотографии Пост из серии «печатаю всё, что ломается». Сегодня — маленькая чёрная деталь, из-за которой дорогие ласты едва не

Приветствую коллеги!

Небольшое вступление: в прошлом году сын подарил мне на день рождения принтер (Ender 3 V3 SE). Я, как и многие, начал пробовать: печатал разные коробочки, органайзеры. Ремонтировал, что раньше не представлял как отремонтировать, супруге печатал кашпо и горшочки для цветов. Попробовал кое-что из Мультиборда. В общем всякую фигню. В этом году сын подарил мне подписку на Claude Code (далее CC) (ИИ-агент и инструмент командной строки от компании Anthropic). И решил я напечатать ещё одну фигулинку: у меня были ласты, года 3-4 как была утеряна пряжка и ласты валялись без дела. Хотел сам отреверсить её во FreeCad-е, наверное смог бы, но подумал: а чего бы искуственному интеллекту не потрудиться. Сказано - сделано.

Ниже пересказ СС, как он делал модель (да, я его попросил самого рассказать).

Как мы вернули к жизни пряжку от ласт: реверс-инжиниринг по фотографии

Пост из серии «печатаю всё, что ломается». Сегодня — маленькая чёрная деталь, из-за которой дорогие ласты едва не отправились на помойку. И подробный разбор> того, как вообще делать 3D-модель, когда у тебя на руках только сама деталь и фотоаппарат.Зачем это всё

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

К счастью, парная деталь со второй ласты осталась — её и пустим в дело как образец для замеров и фотографий.

Значит, печатаем. Но сначала — моделируем. Причём моделируем не «на глазок», а параметрически: так, чтобы при первой же неточной примерке можно было поправить один размер и перепечатать, а не рисовать всё заново.

Вот виновник торжества — тот самый корпус-«туфелька», который нам предстоит повторить:

А чтобы было понятно, как он работает, вот он же рядом с ответной частью — пружинной защёлкой с зубчатой планкой ремешка:

-2

Корпус (верхняя деталь) — это полый колпак с пазом в дне; защёлка с двумя «ушами» (нижняя деталь) вставляется внутрь него и фиксируется. Нас интересует именно корпус — защёлку оставляем как есть.

Шаг 1. Фотографируем деталь как улику, а не как мем

Главная ошибка новичка — сделать одно красивое фото «в три четверти» и пытаться по нему всё восстановить. По такому кадру нельзя снять ни один честный размер: перспектива врёт, ближний край крупнее дальнего.

Что нужно на самом деле — ортогональные ракурсы, по одному на каждую плоскость:

вид сверху / снизу (план — самый информативный для этой детали);вид сбоку (профиль высоты);вид с торца.

Снимать лучше с максимального удаления и зумом (так перспектива «сплющивается» и кадр становится почти ортогональным), деталь — на контрастном однотонном фоне, рядом — линейка или штангенциркуль в том же кадре.

Шаг 2. Снимаем размеры и наносим прямо на фото

Это сердце всего метода. Берём штангенциркуль и меряем всё, что меряется, а потом подписываем размеры поверх фотографии. Такой размеченный кадр становится «источником истины»: к нему возвращаешься каждый раз, когда в модели что-то не сходится.

Вид снизу — самый богатый на размеры. Здесь видно главную особенность детали: сквозной замочный паз в форме «восьмёрки» (через него корпус надевается на грибковый штырь на ласте и сдвигается до фиксации):

-3

Что мы отсюда сняли:

ЧтоРазмерПолная длина46,2 ммМакс. ширина (широкие «плечи») 33,4 ммШирина в талии20,5 ммШирина язычка26,4 ммБольшое отверстие пазаø 15,12 мм

Малое отверстие паза

ø 8,8 мм

И вид сбоку — он даёт профиль высоты и положение бокового окна под «ухо» защёлки:

-4

💡 Правило, которое спасает нервы: замеры — это закон, их не трогаем. Всё, что не удалось померить (скругления, радиусы фасок), выносим в отдельные> «параметры формы» и подбираем уже их. Так подгонка формы никогда случайно не испортит выверенные габариты.Шаг 3. Понимаем топологию — что это вообще за фигура

Прежде чем писать код, нужно проговорить деталь словами. Если не можешь описать её в трёх фразах — рано садиться моделировать. У нас получилось так:

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

Вот теперь можно моделировать.

Шаг 4. Почему параметрический OpenSCAD, и как он собирается

Для таких деталей я беру OpenSCAD: это не рисовалка мышкой, а код. Меняешь число — меняется модель. Идеально для итеративной подгонки «по фото».

Вся деталь собирается из простых идей. Сначала — силуэт в плане. Его я не рисую сплайнами, а складываю из трёх скруглённых тел (широкий конец + талия + круглый купол) и вырезаю по бокам две дуги, чтобы получить «талию»:

module plan() {

union() {

rrect(0, 22, W_max, corner_r); // широкие плечи

rrect(16, 36, W_waist, corner_r); // перемычка-талия

translate([L - W_dome/2, 0]) circle(d = W_dome); // купол

}

// ...и вырезаем боковые дуги талии

}

Дальше — огранка купола по высоте. Боковой профиль (как на размеченном фото) я задаю просто списком точек `[X, Z]`, делаю из него призму поперёк детали и пересекаю с выдавленным планом. Пересечение двух тел и даёт плавно заваливающийся купол:

PROFILE_OUT = [[0,0],[0,12.5],[10,13.4],[20,14.2],[28,H],

[34,14.5],[40,13.5],[43.5,10.5],[45.5,6],[46.2,2.2],[46.2,0]];

module outer_solid() {

intersection() { linear_extrude(H) plan(); prism(PROFILE_OUT); }

}

А полость — это тот же план, ужатый внутрь на толщину стенки (`offset(r=-wall)`), поднятый на высоту дна и пересечённый уже с *внутренним* профилем (внешний минус стенка). Потом из готового тела булевыми вычитаниями убираем рот полости, паз, окна. В конце добавляем направляющие. Вся сборка — буквально один блок:

union() {

difference() {

outer_solid();

cavity(); // полость

mouth_cut(); // открыть торец язычка

keyhole_cut(); // паз-восьмёрка в дне

window_cut(); // боковые окна под уши защёлки

}

intersection() { guides(); outer_solid(); } // направляющие на потолке

}

Шаг 5. Один трюк, ради которого стоит читать дальше

Паз-«восьмёрка» — не два кружка с прямой перемычкой. На фото между отверстиями видны плавные касательные обводы (перешеек). Рисовать их вручную — мучение. Решается одной идиомой — морфологическим замыканием: расширяем объединение двух кругов на радиус `key_blend`, а потом сжимаем обратно на тот же радиус.

Внешний контур возвращается на место, а вот вогнутые стыки между кругами скругляются сами собой:

module keyhole2d()

offset(r = -key_blend) offset(r = key_blend) // closing: +r, затем −r

union() {

translate([hole_big_x, 0]) circle(d = hole_big_d);

translate([hole_sml_x, 0]) circle(d = hole_sml_d);

}

Один и тот же приём работает и в OpenSCAD, и в FreeCAD — что нам ещё пригодится.

Шаг 6. Проверка: модель обязана совпасть с замерами

«Тестов» в привычном смысле тут нет. Критерий правильности один: габариты напечатанной (пока виртуально) модели совпадают с замерами на фото. Поэтому я веду деталь в двух параметрических вариантах:

OpenSCAD (`.scad`) — быстрый, для подгонки формы; FreeCAD/Part (headless-скрипт на Python) — даёт `.FCStd`, `.STEP` и `.STL`, а в конце печатает объём и bbox. Эти числа я глазами сверяю с блоком замеров: 46,2 × 33,4 × 14,63 мм. Сошлось — значит, геометрия не врёт.

Рендер из OpenSCAD после всех итераций (виден боковой профиль купола, талия иокно под ухо защёлки):

-5

Команды, которыми всё гоняется:

# Рендер STL из OpenSCAD

openscad -o out/strap_buckle.stl ai/strap_buckle.scad

# FreeCAD headless → .FCStd + .STEP + .STL, с печатью bbox для сверки

/tmp/freecadcmd freecadcmd ai/strap_buckle_freecad.py

Шаг 7. Печать, примерка — и happy end

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

Вот она, свежая, прямо со стола принтера:

-6

Видно всё главное: сквозной паз-«восьмёрка» в дне, боковое окно под «ухо» защёлки и плоскую крышку с тем самым дуговым вырезом передней кромки — ровно как на замерах.

И финальная проверка — деталь на штатном месте: надевается на грибок ласты, принимает пружинную защёлку с зубчатым ремешком и держит. Ремешок регулируется, защёлка щёлкает:

-7

Копеечная фитюлька повторена, ласта снова в строю — и теперь, если что, печатается за вечер из остатков филамента.

Грабли, на которые мы наступили (чтобы вы не наступали)Перспектива на фото. Первые замеры по «красивому» кадру дали косую длину. Лечится съёмкой с зумом издалека и ортогональными ракурсами.Окна резали направляющие. Боковые вырезы под «уши» по неосторожности срезали потолочные рёбра. Пришлось ограничить вырез по ширине (`win_inner`), оставив центральную зону нетронутой.Высоту окна меряем от низа детали (z = 0), а не от стенки. Мелочь, но из-за неё окно «уехало» по высоте на целую итерацию.FreeCAD как AppImage молча уходит в GUI и виснет, если не передать `freecadcmd` первым аргументом. Бинарник выбирается по аргументу, а не по имени симлинка.Итого: рецепт «модель по фотографии» в шести строчкахСнять деталь ортогонально, с линейкой в кадре.Померить штангенциркулем и подписать размеры прямо на фото.Описать топологию словами.Собрать форму из примитивов и булевых операций в параметрическом коде.Сверить bbox модели с замерами; что не меряется — подбирать отдельными параметрами.Печатать, примерять, править один параметр, повторять.

Маленькая чёрная фитюлька спасена, ласты живут. А у вас теперь есть готовый маршрут, чтобы повторить это с любой сломанной деталью. Удачной печати! 🐟

P.S.: Не большой комментарий:

Перед созданием модели, обязательно сказать, что бы СС подробно рассазал как понял задачу;Сказать CC вывести все исползуемые размерности с соответствующими идентификаторами (что бы при последующих корректировках точно указывать изменённые размеры)CC соврал - печатал с поддержками :)

PPS: на всё ушло примерно 11 часов, из них: ~ 1-1,5 часа подготовка фотографий и картинок, ~ 3 часа печать моделей (4 модели по 45 мин.), оставшееся время (~ 6.5-7 часов) общение с CC, из которого чистого времени на общение непосредственно с СС примерно 1 час, остальное время CC работал сам.

И в заключение: скорее всего, специалист, хорошо знакомый с софтом для 3D моделирования и имеющий опыт в реверс-инжиниринге, сделал бы такую модель раза в 2-3 быстрее, но целью данного действа (помимо восстановления функцилонала ласт) было получение нового опыта.