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_simplify_mesh
|
||||
kind: function
|
||||
lang: py
|
||||
domain: ml
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def comfyui_simplify_mesh(in_path: str, *, target_faces: int = 80000, weld: bool = True, out_path: str | None = None) -> dict"
|
||||
description: "Decima (simplifica) una malla 3D GLB/OBJ/PLY a target_faces conservando su apariencia. Post-proceso de las mallas densas de Hunyuan3D/ComfyUI (60 MB / ~1.67 M caras). Suelda los vertices duplicados ANTES del quadric edge collapse (pymeshlab) — las mallas cube-soup de VoxelToMeshBasic no decimar sin soldar primero. Conserva vertex colors (ColorVisuals, los interpola pymeshlab a traves del collapse) o textura+UV (TextureVisuals, reproyecta UV por vertice mas cercano con scipy y readjunta la imagen). Impura: lee y escribe en disco con trimesh + pymeshlab + scipy."
|
||||
tags: [comfyui, 3d, mesh, hunyuan3d, decimation, simplify, pymeshlab, 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). Si es un GLB Scene con varias geometrias, se concatenan en una sola malla."
|
||||
- name: target_faces
|
||||
desc: "Numero de caras objetivo tras la decimacion. Si es >= a las caras soldadas, no decima (decimate_status lo indica). keyword-only. Default 80000."
|
||||
- name: weld
|
||||
desc: "Si True (default), suelda vertices duplicados (meshing_remove_duplicate_vertices) antes del collapse. CLAVE para las mallas cube-soup de VoxelToMeshBasic: sin el, el quadric edge collapse devuelve las caras intactas. keyword-only."
|
||||
- name: out_path
|
||||
desc: "Ruta de salida. Si None, escribe '<in>_simplified.glb' junto al original (NO sobrescribe el original). keyword-only."
|
||||
output: "dict {ok, in_faces, out_faces, in_mb, out_mb, out_path, welded_faces, decimate_status, appearance, error}. in/out_faces = caras antes/despues; in/out_mb = tamano de archivo en MB; welded_faces = caras tras soldar; decimate_status = 'ok' o 'skipped_target_ge_welded(N)'; appearance = 'vertex_color'|'texture'|'none'. Si falla, ok=False y error explica (dependencia ausente, archivo no existe, carga o export)."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/ml/comfyui_simplify_mesh.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
|
||||
from ml.comfyui_simplify_mesh import comfyui_simplify_mesh
|
||||
|
||||
# Decima la malla densa de un personaje (964k caras, 34.7 MB) a 80k caras,
|
||||
# conservando los vertex colors. No toca el original.
|
||||
res = comfyui_simplify_mesh(
|
||||
os.path.expanduser("~/ComfyUI/output/character_3d_00001_.glb"),
|
||||
target_faces=80000,
|
||||
out_path="/tmp/character_simplified.glb",
|
||||
)
|
||||
# res == {"ok": True, "in_faces": 964332, "out_faces": 80000,
|
||||
# "in_mb": 34.718, "out_mb": 1.429, "appearance": "vertex_color",
|
||||
# "decimate_status": "ok", "out_path": "/tmp/character_simplified.glb", ...}
|
||||
```
|
||||
|
||||
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 3D de ComfyUI/Hunyuan3D sale demasiado densa (decenas de MB,
|
||||
millones de caras) y necesitas una version ligera para visor web, repo, deploy o
|
||||
texturizado posterior. Es el post-proceso de los .glb que baja
|
||||
`comfyui_fetch_output_mesh`. Para hacerla ademas estanca, encadena con
|
||||
`comfyui_make_watertight`. Si la malla ya es ligera (caras <= target_faces) no hace
|
||||
nada destructivo: el campo `decimate_status` lo refleja.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Impura: lee `in_path` y escribe `out_path` en disco. Nunca sobrescribe el
|
||||
original salvo que pases `out_path` apuntando a el.
|
||||
- `weld=True` es imprescindible para las mallas cube-soup de `VoxelToMeshBasic`
|
||||
(4 vertices por cara sin compartir aristas). Con `weld=False` sobre una cube-soup
|
||||
el quadric edge collapse no reduce caras. Solo pon `weld=False` si sabes que la
|
||||
malla ya tiene topologia soldada y quieres preservarla exacta.
|
||||
- Vertex colors: pymeshlab los interpola a traves del collapse y se readjuntan
|
||||
fielmente (verificado). Textura+UV: la reproyeccion de UV es por vertice mas
|
||||
cercano (scipy cKDTree), aproximada — fiel para mallas densas, puede mostrar
|
||||
ligero corrimiento en bordes de isla UV; la imagen de textura se readjunta sin
|
||||
recortar. La via de raiz para malla texturizada estanca es generar con
|
||||
`VoxelToMesh algorithm='surface net'` (ver report 0088), no este post-proceso.
|
||||
- El voxel-remesh de `comfyui_make_watertight` descarta la apariencia; si quieres
|
||||
malla ligera Y con color, decima con esta funcion y NO la pases por watertight
|
||||
voxel (o reproyecta el color despues).
|
||||
- Requiere trimesh + pymeshlab + scipy en el venv del registry (`cd python && uv
|
||||
add trimesh pymeshlab scipy`). Sin ellas devuelve ok=False con el detalle.
|
||||
Reference in New Issue
Block a user