Что такое watertight (водонепроницаемый) меш
Загрузил модель в слайсер — а на печати каша: пропущенные стенки, залитые полости, пластик, висящий в воздухе. Чаще всего виноват не слайсер и не принтер, а сам меш: он не watertight. В оболочке есть дыры, склейки или вывернутые треугольники, и программа просто не понимает, где у модели «внутри», а где «снаружи». Разберём, что такое водонепроницаемый меш, какие у него бывают дефекты и как наш движок проверяет и латает геометрию перед резкой на детали.
Коротко
- Watertight («водонепроницаемый») — замкнутая оболочка без дыр, где у каждого ребра ровно 2 грани: меш однозначно делит пространство на «внутри» и «снаружи».
- Manifold строже watertight: помимо «2 граней на ребро» запрещает склейки, самопересечения и вывернутую намотку треугольников.
- Три источника течи: дыры (ребро с 1 гранью), non-manifold рёбра (ребро с более чем 2 гранями) и перевёрнутые нормали.
- Антимиф: watertight НЕ значит «внутри есть мясо» — полая корка 1 мм формально герметична, но печатать в ней нечего.
- Наш критерий годности — is_manifold_volume, а не trimesh `is_watertight`: он строже и именно он решает, соберётся ли snap-fit замок.
Watertight и manifold: в чём разница
Watertight («водонепроницаемый») меш — это замкнутая поверхность без дыр, где у каждого ребра ровно 2 грани. Такая оболочка делит пространство на однозначное «внутри» и «снаружи» — как физический объект, в который не затечёт вода. Именно эту однозначность требует и слайсер, и наш движок резки.
Manifold (многообразие) — требование строже. Мало того что у каждого ребра ровно 2 грани: вокруг каждой вершины грани должны образовывать один связный «веер», без склеек, самопересечений и выворотов. Всякий manifold-меш водонепроницаем, но не всякий watertight-меш манифолден — и как раз в этом зазоре прячется большинство «непечатаемых» моделей.
Простая аналогия: меш — это бумажная оболочка, склеенная из треугольников. Watertight = склеена герметично, без прорех и складок. Стоит появиться дыре или вывернутому треугольнику — принтер уже не понимает, где стенка, а где пустота.
- Ребро водонепроницаемого меша принадлежит ровно 2 граням — оболочка нигде не рвётся и нигде не слипается.
- Вокруг каждой вершины manifold-меша грани образуют один связный веер, без сшитых в точку кусков.
- Такой меш делит пространство однозначно: любая точка либо внутри тела, либо снаружи — третьего не дано.
Три класса дефектов, из-за которых меш течёт
Практически вся негерметичность сводится к трём классам дефектов. Понимая их, проще читать сообщения слайсера и ремонтных утилит — и понимать, что именно чинит наш движок.
| Класс дефекта | Что это геометрически | Чем грозит |
|---|---|---|
| Дыра / открытая граница | ребро принадлежит только 1 грани | контур слоя не замыкается — слайсер не знает, что заливать |
| Non-manifold ребро | ребро принадлежит более чем 2 граням (склейка, самопересечение) | manifold3d бракует объём, булевы замки падают |
| Перевёрнутые нормали | несогласованная намотка треугольников (детект `is_winding_consistent`) | «внутри» и «снаружи» меняются местами → пропущенные стенки |
Почему слайсер спотыкается о дырявый меш
Слайсер режет модель горизонтальными плоскостями, и на каждом слое ему нужен замкнутый контур, чтобы по правилу заливки (fill rule) решить, что закрашивать пластиком, а что оставить пустым. Дыра рвёт этот контур, а вывернутая нормаль переворачивает «внутри/снаружи» — и слайсер начинает ошибаться: пропускает стенки, заливает полости, ставит «фантомный» пластик в воздухе. На выходе — мусорный G-code.
Бьёт негерметичность и по нашему движку замков. Булевы операции для snap-fit идут через библиотеку manifold3d, а она на грязном меше падает с ошибкой «Not all meshes are volumes!». Итог: 0 замков и битая деталь. Поэтому чистая геометрия для нас — не косметика, а условие того, чтобы детали вообще соединились друг с другом.
Антимиф: watertight ≠ «внутри есть мясо»
Частое заблуждение: раз меш watertight — значит, он «плотный» и точно напечатается. Это не так. Watertight и manifold описывают только поверхность-оболочку и НЕ доказывают, что внутри модели есть материал.
Полая корка толщиной 1 мм формально абсолютно герметична: у каждого ребра ровно 2 грани, дыр нет. Но печатать в ней, по сути, нечего — стенка слишком тонка, чтобы держать замок или нагрузку. Поэтому проверку «оболочка цела» нельзя путать с проверкой «деталь состоятельна».
Как мы проверяем: is_manifold_volume, а не is_watertight
Главный технический факт: критерий годности в движке — НЕ trimesh `is_watertight`, а `is_manifold_volume(mesh)`. Он возвращает True только если библиотека manifold3d принимает меш как валидный объём, то есть `Manifold(mesh).status() == NoError`.
Почему разница принципиальна. Проверка `is_watertight` смотрит ровно на одно свойство — «у каждого ребра 2 грани». Меш может её пройти и всё равно остаться непечатным: с самопересечениями, кривой намоткой, вырожденными треугольниками. `is_manifold_volume` строже — такие меши он бракует. Именно этот критерий определяет, соберётся ли snap-fit с нужным зазором и уедет ли деталь в финальный файл.
Как движок чинит меш: лестница harden, GWN и честный degraded
Если меш не проходит `is_manifold_volume`, движок не сдаётся сразу, а гонит его по лестнице ремонта harden — от дешёвого к тяжёлому, с одним и тем же выходным условием: получить валидный объём.
Отдельная ветка — для открытой входной оболочки (например, AI-генерёжка, у которой объём буквально равен нулю). Тут работает GWN-ремеш: знаковое поле строится через обобщённое winding-число (`igl.signed_distance` в режиме FAST_WINDING_NUMBER, метод Jacobson 2013 / Barill 2018, оба peer-reviewed), а затем по нему прогоняется marching cubes. На тестовом коте в 1.5 млн граней объём сохранён на 99.98%.
И финальный контур: экспорт работает fail-closed. Деталь, не прошедшая `is_manifold_volume`, исключается из 3MF, а готовый файл дополнительно проверяется через lib3mf (`IsManifoldAndOriented` на каждом теле). Это не наша прихоть — стандарт 3MF сам требует, чтобы каждое тело было манифолдным и ориентированным; подробнее в STL против 3MF. И только герметичную геометрию мы режем на цветные детали.
Водонепроницаемый 3MF на выходе даёт разрез модели по цветам — каждая деталь выходит watertight.
- (0) Уже объём — меш проходит `is_manifold_volume` как есть → возвращаем нетронутым.
- (1) Дешёвый ремонт trimesh — слить совпадающие вершины, убрать вырожденные треугольники, `fill_holes`, `fix_normals`.
- (2) pymeshfix — латает дыры и самопересечения, сохраняя исходную поверхность.
- (3) Воксельный ремеш — вокселизация → заливка нутра → marching cubes → шлифовка Taubin. Стоит последним: на тонкостенном даёт «вермишель».
На чём основан сервис
BunnySplit рассчитывает соединения не «на глаз». Зазор замка складывается из посадки (по умолчанию 0.30 мм на сторону) и компенсации усадки материала — PLA 0.3%, PETG 0.5%, ABS 0.7% — а прогиб защёлки проектируется с запасом не меньше двукратного по пределу деформации пластика (PLA около 4%, PETG около 7%). Геометрия консольных защёлок следует инженерному канону snap-fit Bayer/Covestro «Snap-Fit Joints for Plastics».
Числа — из движка сервиса и справочников FDM; величины snap-fit — по Bayer/Covestro. Разработчик и издатель: BunnySplit.
Не уверен, что модель напечатается?
Загрузи STL или 3MF в редактор BunnySplit — движок сам проверит геометрию через is_manifold_volume, залатает дыры и разрежет модель на цветные детали со snap-fit замками. Если меш починить нельзя, он честно скажет об этом, а не отдаст битую деталь.
Загрузить модель →Печатаете на заказ? Продавайте свои модели и услуги на BunnySplit →