Перейти к содержимому
← Все проекты

JewelWeight

Плагин для Rhino 8, который считает вес металла в ювелирных моделях. Сделал для своей работы в ювелирной мастерской, теперь им пользуются и коллеги.

Роль
Один. ТЗ, продуктовые решения и тестирование мои; код написан с Claude Code
Стек
Python 3.9, RhinoCommon, Eto.Forms, unittest
Платформа
Rhino 8, Windows
Статус
v1.0.0, ежедневно используется в мастерской
Выделяешь объекты, жмёшь сплав, получаешь граммы. Лента сохраняет все результаты, поэтому сплавы можно сравнить на одном выделении.

Проблема

В ювелирке вес — это цена. Клиенты задают бюджет в граммах, и стоимость заказа идёт от металла.

До JewelWeight вес модели узнавали одним из двух способов:

  • команда Volume в Rhino и умножение на плотность сплава на калькуляторе, заново для каждого сплава;
  • или вообще без расчёта: вес становился известен после отливки, когда модель уже не исправить.

Решение

Одно окно внутри Rhino: выдели объекты → нажми сплав → вес в граммах.

  • 8 стандартных сплавов (585 и 750 красное / жёлтое / белое, 999, серебро 925) и свои сплавы; любую плотность можно изменить.
  • Проверка перед каждым расчётом: открытая или non-manifold геометрия блокируется, проблемные объекты подсвечиваются во viewport, а сообщение говорит, как исправить.
  • STL, которые печатаются, но формально non-manifold, очищаются в памяти и всё равно считаются; сама модель не меняется.
  • Любые единицы документа переводятся в мм³; вес округляется half-up до 0.01 г.
  • Выделение остаётся рабочим, пока модель меняется: удалённые объекты и смена документа определяются при каждом клике.

Доказательство: пара на 9 грамм

расчёт
8.99 г
лимит
9.00 г
сплав
585 жёлтое
  • Заказ: пара колец из 585 жёлтого золота, не больше 9 г за обе.
  • JewelWeight: 2 объекта, 666.71 мм³ → 8.99 г в 585 жёлтом.
  • После отливки: вес совпал с расчётом. Обработка и полировка снимают немного металла, поэтому готовая пара вышла чуть легче и спокойно уложилась в 9 г.
  • Почему отдельная кнопка на каждый сплав: та же пара в 585 белом весит 9.17 г, это больше лимита. Один только сплав меняет ответ на 0.18 г.
В Rhino выделены два кольца. JewelWeight показывает 2 объекта и 666.71 мм³, предупреждение, что пересекающиеся тела считаются дважды, и 585 белое: 9.17 г.
Те же два кольца в 585 белом: 9.17 г, больше лимита в 9 г. Предупреждение напоминает, что пересекающиеся тела считаются дважды.
Окно JewelWeight в Rhino: вес одного выделенного кольца в 585 красном, 750 жёлтом и серебре 925.

Инженерные задачи

  1. Печатный STL отклонялся как non-manifold. Дублированные и вырожденные треугольники ломают IsManifold, но не добавляют объёма. Закрытые меши перепроверяются на очищенной копии в памяти (сварка вершин, удаление вырожденных и дублированных граней); если копия проходит, берётся её объём и показывается заметка.
  2. Правильные граммы в любых единицах. Масштаб единиц возводится в куб до мм³; документы без надёжных единиц отклоняются; округление через Decimal half-up, поэтому 4.365 всегда становится 4.37. Покрыто unit-тестами.
  3. Выделение, которое переживает правки. Хранятся ID объектов и serial документа; каждый клик по сплаву заново проверяет объекты, исключает удалённые с уведомлением и подсвечивает проблемные.
  4. Своя тёмная тема из Python внутри Rhino. Eto.Forms через pythonnet: кнопки отрисованы вручную с hover и pressed (нативные WPF-кнопки ломали тему), отложенный клик, чтобы работал выбор во viewport, одно окно на сессию Rhino.
  5. Настройки переживают обновления и битые файлы. UTF-8 JSON в %APPDATA% с версией схемы и миграциями, атомарная запись, бэкап повреждённого файла с меткой времени. Хранятся только изменения пользователя, поэтому улучшенные значения по умолчанию доходят до неизменённых сплавов.

Логика без Rhino (расчёт, хранение, тема) вынесена в чистые модули с тестами вне Rhino.

Цифры

строки Python, 21 файл
2 543
unit-тестов
65
встроенных сплавов + сколько угодно своих
8
сторонних зависимостей
0
от первого коммита до релиза v1.0.0 за один вечер
5 коммитов

Как я сделал это с ИИ

Я написал ТЗ и промпты и разбил работу на три фазы: ядро расчёта, настройки и UI, установщик. Продуктовые решения мои: только вес, без цены, потому что цена золота меняется каждый день и называется клиенту позже; только Rhino 8; интерфейс на русском, потому что пользователи — мастерская. Каждую фазу я проверял в Rhino на реальных моделях, включая STL, который не проходил проверку; из-за него появилась очистка мешей. Код и unit-тесты по ТЗ написал Claude Code.

Что дальше

  • Пакет .yak для food4Rhino
  • Поддержка SubD через конвертацию в Brep
  • Автоматическая установка toolbar (.rui)

Ссылки

github.com/Khanapin-T/rhino-jewelweight

Learnt. Built. Shipped.