feat(ml): auto-commit con 7 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: comfyui_make_watertight
|
||||
kind: function
|
||||
lang: py
|
||||
domain: ml
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def comfyui_make_watertight(in_path: str, *, method: str = \"voxel\", pitch: float | None = None, out_path: str | None = None) -> dict"
|
||||
description: "Hace estanca (watertight) una malla 3D GLB/OBJ/PLY de ComfyUI/Hunyuan3D. method='voxel' (default) voxeliza el solido, rellena el interior y reconstruye con marching cubes (trimesh) -> is_watertight=True garantizado, a costa de mas caras y de descartar la apariencia; necesita scikit-image. method='repair' hace limpieza ligera (trimesh.repair fill_holes + fix_normals + fix_winding) conservando el detalle, pero no garantiza estanqueidad en mallas muy rotas. La via de raiz es generar con el nodo VoxelToMesh algorithm='surface net' (report 0088). Impura: lee y escribe en disco."
|
||||
tags: [comfyui, 3d, mesh, hunyuan3d, watertight, voxel, remesh, trimesh, ml]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: error_go_core
|
||||
imports: []
|
||||
params:
|
||||
- name: in_path
|
||||
desc: "Ruta de la malla de entrada (.glb/.obj/.ply/.gltf/.stl/.off). Scene GLB con varias geometrias se concatena en una sola malla."
|
||||
- name: method
|
||||
desc: "'voxel' (default, garantiza is_watertight=True via voxeliza+fill+marching cubes) o 'repair' (fill_holes + fix_normals, conserva detalle pero no siempre estanca). keyword-only."
|
||||
- name: pitch
|
||||
desc: "Solo para method='voxel'. Tamano de voxel absoluto. Si None, se calcula como diagonal_bbox / 200. Mas pequeno = mas caras y mas detalle, mas lento. keyword-only."
|
||||
- name: out_path
|
||||
desc: "Ruta de salida. Si None, escribe '<in>_watertight.glb' junto al original (NO sobrescribe). keyword-only."
|
||||
output: "dict {ok, was_watertight, is_watertight, out_path, method, pitch, out_faces, error}. was/is_watertight = estanqueidad antes/despues medida con trimesh.is_watertight. out_faces = caras del resultado (el voxel-remesh suele aumentarlas). Si falla, ok=False y error explica (dependencia ausente, method invalido, archivo no existe, carga o remesh)."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/ml/comfyui_make_watertight.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
|
||||
from ml.comfyui_make_watertight import comfyui_make_watertight
|
||||
|
||||
# Cierra una malla decimada no estanca (80k caras) por voxel-remesh.
|
||||
res = comfyui_make_watertight(
|
||||
"/tmp/character_simplified.glb",
|
||||
method="voxel",
|
||||
out_path="/tmp/character_watertight.glb",
|
||||
)
|
||||
# res == {"ok": True, "was_watertight": False, "is_watertight": True,
|
||||
# "method": "voxel", "pitch": 0.01596, "out_faces": 250672,
|
||||
# "out_path": "/tmp/character_watertight.glb", "error": ""}
|
||||
```
|
||||
|
||||
Lanzar con el python del venv del registry (import de arriba o heredoc). `./fn run`
|
||||
directo no aplica: la firma usa `*` (keyword-only), no soportado por el runner de `fn run`.
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando una malla de ComfyUI/Hunyuan3D sale NO estanca (`is_watertight=False`, tipico
|
||||
del nodo DEPRECATED `VoxelToMeshBasic`) y la necesitas cerrada para imprimir en 3D,
|
||||
calcular volumen, boolean ops o simulacion. Usa `method="voxel"` cuando exiges
|
||||
estanqueidad garantizada (la silueta se conserva, el detalle fino se suaviza).
|
||||
Usa `method="repair"` cuando la malla solo tiene huecos pequenos y quieres conservar
|
||||
caras/detalle. Para malla ligera Y estanca, decima antes con `comfyui_simplify_mesh`
|
||||
y luego pasa el resultado por aqui con `method="voxel"`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Impura: lee `in_path` y escribe `out_path`. Nunca sobrescribe el original salvo
|
||||
que apuntes `out_path` a el.
|
||||
- `method="voxel"` DESCARTA la apariencia (UV / vertex colors): el marching cubes
|
||||
genera geometria nueva sin atributos. Si quieres color, aplicalo despues del
|
||||
remesh, o usa la via de raiz (`VoxelToMesh surface net`) que preserva el flujo de
|
||||
texturizado.
|
||||
- `method="voxel"` necesita `scikit-image` en el venv (marching cubes). Sin el
|
||||
devuelve ok=False con la instruccion `uv add scikit-image`.
|
||||
- `method="repair"` NO garantiza `is_watertight=True`: en mallas muy rotas
|
||||
(cube-soup con muchos huecos grandes) devuelve `is_watertight=False`. Es
|
||||
esperado; para garantia usa `method="voxel"`.
|
||||
- El voxel-remesh aumenta el numero de caras (densidad del marching cubes). Si
|
||||
necesitas ligero Y estanco, vuelve a decimar el resultado con
|
||||
`comfyui_simplify_mesh` (el report 0088 logra 80k caras + estanco re-cerrando).
|
||||
- `euler_number` puede quedar negativo aunque sea estanco: indica genus alto real
|
||||
(tuneles de la geometria), no un fallo. Estanco != genus 0.
|
||||
- `pitch` muy pequeno sobre mallas grandes es lento (corre en CPU, no usa VRAM).
|
||||
Reference in New Issue
Block a user