Merge pull request #40 from PozzettiAndrea/dev

Dev
This commit is contained in:
Andrea Pozzetti
2026-02-13 01:42:40 +01:00
committed by GitHub
58 changed files with 702 additions and 1387 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Promote dev results to main
on: workflow_dispatch
jobs:
promote:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install comfy-test
- name: Checkout gh-pages
uses: actions/checkout@v4
with:
ref: gh-pages
path: gh-pages
fetch-depth: 1
- name: Copy dev results to main
run: |
rm -rf gh-pages/main
cp -r gh-pages/dev gh-pages/main
- name: Regenerate indexes
run: |
comfy-test generate-index gh-pages/main --repo-name "${{ github.repository }}"
comfy-test generate-root-index gh-pages --repo-name "${{ github.repository }}"
- name: Publish to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: gh-pages
keep_files: true
+1 -27
View File
@@ -20,33 +20,7 @@ https://github.com/user-attachments/assets/7718a5d7-cd5b-47d3-874c-29ada4320694
## Installation
```bash
cd ComfyUI/custom_nodes/
git clone https://github.com/PozzettiAndrea/ComfyUI-GeometryPack.git
cd ComfyUI-GeometryPack
pip install -r requirements.txt
```
**Automatic Blender Installation (Recommended):**
```bash
python install.py
```
This will automatically download and install a portable version of Blender for UV unwrapping and remeshing nodes. No admin rights required!
Restart ComfyUI. Nodes appear in the `geompack/` category.
**Optional Dependencies:**
- **Blender**: Auto-installed via `install.py`, or install manually from [blender.org](https://www.blender.org/download/)
- **CGAL**: Build tools for CGAL remeshing (see `cgal_tools/README.md`)
## Quick Start
**Basic workflow:**
```
Create Primitive → Mesh Info → Preview Mesh (3D)
Load Mesh → PyMeshLab Remesh → Save Mesh
```
Please always install from ComfyUI Manager.
## Community
+2 -27
View File
@@ -1,10 +1,4 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""ComfyUI GeometryPack - Geometry Processing Custom Nodes."""
import os
import sys
from pathlib import Path
print("[geompack] loading...", file=sys.stderr, flush=True)
from comfy_env import register_nodes
print("[geompack] calling register_nodes", file=sys.stderr, flush=True)
@@ -12,27 +6,8 @@ print("[geompack] calling register_nodes", file=sys.stderr, flush=True)
NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS = register_nodes()
def _generate_widget_mappings():
"""Generate widget visibility mappings from node metadata."""
try:
from comfy_dynamic_widgets import scan_specific_nodes, generate_mappings
import json
configs = scan_specific_nodes(NODE_CLASS_MAPPINGS)
if not configs:
return
mappings = generate_mappings(configs)
output_path = os.path.join(os.path.dirname(__file__), "web", "js", "mappings.json")
with open(output_path, "w") as f:
json.dump(mappings, f, indent=2)
except ImportError:
pass
except Exception:
pass
_generate_widget_mappings()
from comfy_dynamic_widgets import write_mappings
write_mappings(NODE_CLASS_MAPPINGS, __file__)
WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
+2 -1
View File
@@ -94,6 +94,7 @@ class LoadMeshBlend:
RETURN_NAMES = ("mesh", "info")
FUNCTION = "load_blend"
CATEGORY = "geompack/io"
OUTPUT_NODE = True
@classmethod
def get_blend_files(cls):
@@ -212,7 +213,7 @@ class LoadMeshBlend:
print(f"[LoadMeshBlend] Loaded: {len(loaded_mesh.vertices)} vertices, {len(loaded_mesh.faces)} faces")
return (loaded_mesh, info)
return {"ui": {"text": [info]}, "result": (loaded_mesh, info)}
# Node mappings
+2 -1
View File
@@ -94,6 +94,7 @@ class LoadMeshFBX:
RETURN_NAMES = ("mesh", "info")
FUNCTION = "load_fbx"
CATEGORY = "geompack/io"
OUTPUT_NODE = True
@classmethod
def get_fbx_files(cls):
@@ -212,7 +213,7 @@ class LoadMeshFBX:
print(f"[LoadMeshFBX] Loaded: {len(loaded_mesh.vertices)} vertices, {len(loaded_mesh.faces)} faces")
return (loaded_mesh, info)
return {"ui": {"text": [info]}, "result": (loaded_mesh, info)}
# Node mappings
+2 -1
View File
@@ -82,6 +82,7 @@ class BooleanBlenderNode:
RETURN_NAMES = ("result_mesh", "info")
FUNCTION = "boolean_op"
CATEGORY = "geompack/boolean"
OUTPUT_NODE = True
def boolean_op(self, mesh_a, mesh_b, operation):
"""
@@ -157,7 +158,7 @@ Watertight: {result.is_watertight}
"""
print(f"[Boolean Blender] Success: {len(result.vertices)} vertices, {len(result.faces)} faces")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
except Exception as e:
raise RuntimeError(f"Boolean Blender operation failed: {e}")
+128 -70
View File
@@ -2,7 +2,8 @@
# Copyright (C) 2025 ComfyUI-GeometryPack Contributors
"""
Remesh Blender Node - Blender voxel and quadriflow remeshing
Remesh Blender Node - Blender remeshing backends using bpy.
Supports: voxel, smooth, sharp, blocks.
Requires bpy (Blender Python module).
"""
@@ -10,63 +11,82 @@ import numpy as np
import trimesh as trimesh_module
def _bpy_setup_object(vertices, faces):
"""Create a Blender mesh object from vertices and faces. Returns (obj, mesh)."""
import bpy
mesh = bpy.data.meshes.new("RemeshMesh")
obj = bpy.data.objects.new("RemeshObject", mesh)
bpy.context.collection.objects.link(obj)
# Deselect everything first (default scene has a Cube selected)
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
mesh.from_pydata(vertices.tolist(), [], faces.tolist())
mesh.update()
return obj, mesh
def _bpy_extract_and_cleanup(obj):
"""Extract vertices/faces from object, then delete it. Triangulates quads/n-gons."""
import bpy
mesh = obj.data
result_vertices = [list(v.co) for v in mesh.vertices]
# Triangulate polygons with >3 verts (safety for any backend producing quads)
result_faces = []
for p in mesh.polygons:
verts = list(p.vertices)
if len(verts) == 3:
result_faces.append(verts)
elif len(verts) == 4:
# Split quad into 2 triangles
result_faces.append([verts[0], verts[1], verts[2]])
result_faces.append([verts[0], verts[2], verts[3]])
else:
# Fan triangulation for n-gons
for i in range(1, len(verts) - 1):
result_faces.append([verts[0], verts[i], verts[i + 1]])
bpy.data.objects.remove(obj, do_unlink=True)
bpy.data.meshes.remove(mesh)
return {'vertices': result_vertices, 'faces': result_faces}
def _bpy_voxel_remesh(vertices, faces, voxel_size):
"""Blender voxel remesh using bpy."""
import bpy
mesh = bpy.data.meshes.new("RemeshMesh")
obj = bpy.data.objects.new("RemeshObject", mesh)
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
mesh.from_pydata(vertices.tolist(), [], faces.tolist())
mesh.update()
obj, mesh = _bpy_setup_object(vertices, faces)
obj.data.remesh_voxel_size = voxel_size
bpy.ops.object.voxel_remesh()
mesh = obj.data
result_vertices = [list(v.co) for v in mesh.vertices]
result_faces = [list(p.vertices) for p in mesh.polygons]
bpy.data.objects.remove(obj, do_unlink=True)
bpy.data.meshes.remove(mesh)
return {'vertices': result_vertices, 'faces': result_faces}
return _bpy_extract_and_cleanup(obj)
def _bpy_quadriflow_remesh(vertices, faces, target_face_count):
"""Blender Quadriflow remesh using bpy."""
def _bpy_remesh_modifier(vertices, faces, mode, octree_depth=6, scale=0.9, sharpness=1.0):
"""Blender Remesh Modifier (Smooth/Sharp/Blocks) using bpy."""
import bpy
mesh = bpy.data.meshes.new("RemeshMesh")
obj = bpy.data.objects.new("RemeshObject", mesh)
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
obj, mesh = _bpy_setup_object(vertices, faces)
mesh.from_pydata(vertices.tolist(), [], faces.tolist())
mesh.update()
mod = obj.modifiers.new(name="Remesh", type='REMESH')
mod.mode = mode # 'SMOOTH', 'SHARP', or 'BLOCKS'
mod.octree_depth = octree_depth
mod.scale = scale
if mode == 'SHARP':
mod.sharpness = sharpness
bpy.ops.object.quadriflow_remesh(
use_mesh_symmetry=False,
use_preserve_sharp=False,
use_preserve_boundary=False,
smooth_normals=False,
mode='FACES',
target_faces=target_face_count,
seed=0
)
bpy.ops.object.modifier_apply(modifier="Remesh")
mesh = obj.data
result_vertices = [list(v.co) for v in mesh.vertices]
result_faces = [list(p.vertices) for p in mesh.polygons]
bpy.data.objects.remove(obj, do_unlink=True)
bpy.data.meshes.remove(mesh)
return {'vertices': result_vertices, 'faces': result_faces}
return _bpy_extract_and_cleanup(obj)
class RemeshBlenderNode:
@@ -75,7 +95,9 @@ class RemeshBlenderNode:
Available backends:
- blender_voxel: Voxel-based remeshing (watertight output)
- blender_quadriflow: Quadriflow quad remeshing
- blender_smooth: Smooth remesh modifier
- blender_sharp: Sharp remesh modifier (preserves edges)
- blender_blocks: Blocky remesh modifier
Requires bpy (Blender Python module) to be installed.
"""
@@ -87,10 +109,12 @@ class RemeshBlenderNode:
"trimesh": ("TRIMESH",),
"backend": ([
"blender_voxel",
"blender_quadriflow",
"blender_smooth",
"blender_sharp",
"blender_blocks",
], {
"default": "blender_voxel",
"tooltip": "Remeshing algorithm. blender_voxel=watertight output, blender_quadriflow=quad remesh"
"tooltip": "Remeshing algorithm. voxel=watertight, smooth/sharp/blocks=modifier-based"
}),
},
"optional": {
@@ -104,14 +128,32 @@ class RemeshBlenderNode:
"tooltip": "Voxel size for Blender voxel remesh. Smaller = more detail, more faces. Output is always watertight.",
"visible_when": {"backend": ["blender_voxel"]},
}),
# Quadriflow
"target_face_count": ("INT", {
"default": 500000,
"min": 1000,
"max": 5000000,
"step": 1000,
"tooltip": "Target number of output faces for quadriflow backend.",
"visible_when": {"backend": ["blender_quadriflow"]},
# Modifier-based (Smooth/Sharp/Blocks)
"octree_depth": ("INT", {
"default": 6,
"min": 1,
"max": 10,
"step": 1,
"tooltip": "Resolution of the remesh. Higher = more detail, more faces.",
"visible_when": {"backend": ["blender_smooth", "blender_sharp", "blender_blocks"]},
}),
"scale": ("FLOAT", {
"default": 0.9,
"min": 0.0,
"max": 1.0,
"step": 0.05,
"display": "number",
"tooltip": "Ratio of output size to input bounding box.",
"visible_when": {"backend": ["blender_smooth", "blender_sharp", "blender_blocks"]},
}),
"sharpness": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 5.0,
"step": 0.1,
"display": "number",
"tooltip": "Edge sharpness for Sharp mode.",
"visible_when": {"backend": ["blender_sharp"]},
}),
}
}
@@ -122,8 +164,15 @@ class RemeshBlenderNode:
CATEGORY = "geompack/remeshing"
OUTPUT_NODE = True
def remesh(self, trimesh, backend, voxel_size=1.0, target_face_count=500000):
def remesh(self, trimesh, backend, voxel_size=1.0,
octree_depth=6, scale=0.9, sharpness=1.0):
"""Apply Blender-based remeshing."""
# Sanitize hidden widget values (ComfyUI sends '' for hidden visible_when widgets)
voxel_size = float(voxel_size) if voxel_size not in (None, '') else 1.0
octree_depth = int(octree_depth) if octree_depth not in (None, '') else 6
scale = float(scale) if scale not in (None, '') else 0.9
sharpness = float(sharpness) if sharpness not in (None, '') else 1.0
initial_vertices = len(trimesh.vertices)
initial_faces = len(trimesh.faces)
@@ -134,9 +183,11 @@ class RemeshBlenderNode:
if backend == "blender_voxel":
print(f"[Remesh Blender] Parameters: voxel_size={voxel_size}")
remeshed_mesh, info = self._blender_voxel(trimesh, voxel_size)
elif backend == "blender_quadriflow":
print(f"[Remesh Blender] Parameters: target_face_count={target_face_count:,}")
remeshed_mesh, info = self._blender_quadriflow(trimesh, target_face_count)
elif backend in ("blender_smooth", "blender_sharp", "blender_blocks"):
mode = backend.replace("blender_", "").upper()
print(f"[Remesh Blender] Parameters: mode={mode}, octree_depth={octree_depth}, scale={scale}"
+ (f", sharpness={sharpness}" if backend == "blender_sharp" else ""))
remeshed_mesh, info = self._blender_modifier(trimesh, mode, octree_depth, scale, sharpness)
else:
raise ValueError(f"Unknown backend: {backend}")
@@ -188,13 +239,16 @@ After:
"""
return remeshed_mesh, info
def _blender_quadriflow(self, trimesh, target_face_count):
"""Blender Quadriflow remeshing using bpy."""
print(f"[Remesh Blender] Running Blender Quadriflow (target_faces={target_face_count})...")
result = _bpy_quadriflow_remesh(
def _blender_modifier(self, trimesh, mode, octree_depth, scale, sharpness):
"""Blender Remesh Modifier (Smooth/Sharp/Blocks)."""
print(f"[Remesh Blender] Running Blender Remesh Modifier (mode={mode}, depth={octree_depth})...")
result = _bpy_remesh_modifier(
vertices=np.asarray(trimesh.vertices, dtype=np.float32),
faces=np.asarray(trimesh.faces, dtype=np.int32),
target_face_count=target_face_count
mode=mode,
octree_depth=octree_depth,
scale=scale,
sharpness=sharpness
)
remeshed_mesh = trimesh_module.Trimesh(
@@ -205,16 +259,22 @@ After:
remeshed_mesh.metadata = trimesh.metadata.copy()
remeshed_mesh.metadata['remeshing'] = {
'algorithm': 'blender_quadriflow',
'target_face_count': target_face_count,
'algorithm': f'blender_{mode.lower()}',
'octree_depth': octree_depth,
'scale': scale,
'original_vertices': len(trimesh.vertices),
'original_faces': len(trimesh.faces)
}
info = f"""Remesh Results (Blender Quadriflow):
mode_label = mode.capitalize()
params = f"Octree Depth: {octree_depth}\nScale: {scale}"
if mode == 'SHARP':
params += f"\nSharpness: {sharpness}"
Target Face Count: {target_face_count:,}
Method: bpy
info = f"""Remesh Results (Blender {mode_label}):
{params}
Method: bpy (Remesh Modifier)
Before:
Vertices: {len(trimesh.vertices):,}
@@ -223,8 +283,6 @@ Before:
After:
Vertices: {len(remeshed_mesh.vertices):,}
Faces: {len(remeshed_mesh.faces):,}
Quadriflow creates quad-dominant meshes with good topology.
"""
return remeshed_mesh, info
+2 -1
View File
@@ -213,6 +213,7 @@ class RemeshWithTexture:
RETURN_NAMES = ("remeshed_mesh", "baked_texture", "info")
FUNCTION = "remesh_with_texture"
CATEGORY = "geompack/texture_remeshing"
OUTPUT_NODE = True
def remesh_with_texture(self, trimesh, method, remesh_method, voxel_size, target_face_count,
bake_margin):
@@ -541,7 +542,7 @@ Texture Transfer: Closest-Point Projection{placeholder_warning}
"""
print(f"[BlenderRemeshWithTexture] Complete")
return (remeshed_with_colors, comfy_image, info)
return {"ui": {"text": [info]}, "result": (remeshed_with_colors, comfy_image, info)}
finally:
# Cleanup
+5
View File
@@ -21,6 +21,9 @@ from . import remeshing
from . import reconstruction
from . import texture_remeshing
# ParaView/VTK filter nodes
from . import paraview
# CGAL nodes (moved from nodes/cgal/)
from . import boolean
from . import reconstruction_cgal
@@ -43,6 +46,7 @@ NODE_CLASS_MAPPINGS.update(repair.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(remeshing.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(reconstruction.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(texture_remeshing.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(paraview.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(boolean.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(reconstruction_cgal.NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(remeshing_cgal.NODE_CLASS_MAPPINGS)
@@ -64,6 +68,7 @@ NODE_DISPLAY_NAME_MAPPINGS.update(repair.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(remeshing.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(reconstruction.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(texture_remeshing.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(paraview.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(boolean.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(reconstruction_cgal.NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(remeshing_cgal.NODE_DISPLAY_NAME_MAPPINGS)
+2 -1
View File
@@ -36,7 +36,7 @@ class ConnectedComponentsNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("trimesh", "component_summary")
RETURN_NAMES = ("trimesh", "info")
OUTPUT_IS_LIST = (True, False) # TRIMESH is list, STRING is single summary
OUTPUT_NODE = True # Enable UI output for dynamic display
FUNCTION = "label_components"
@@ -144,6 +144,7 @@ class ConnectedComponentsNode:
return {
"result": (result_meshes, summary),
"ui": {
"text": [summary],
"component_data": ui_components
}
}
+2 -1
View File
@@ -37,7 +37,7 @@ class DegenerateFacesNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("trimesh", "degenerate_summary")
RETURN_NAMES = ("trimesh", "info")
OUTPUT_IS_LIST = (True, False)
OUTPUT_NODE = True
FUNCTION = "find_degenerate_faces"
@@ -186,6 +186,7 @@ class DegenerateFacesNode:
return {
"result": (result_meshes, summary),
"ui": {
"text": [summary],
"degenerate_data": ui_data
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ class MeshQualityNode:
}
RETURN_TYPES = ("FLOAT", "FLOAT", "STRING")
RETURN_NAMES = ("min_quality", "mean_quality", "report")
RETURN_NAMES = ("min_quality", "mean_quality", "info")
OUTPUT_NODE = True
FUNCTION = "analyze_quality"
CATEGORY = "geompack/analysis"
+2 -1
View File
@@ -35,7 +35,7 @@ class OpenEdgesNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("trimesh", "open_edges_summary")
RETURN_NAMES = ("trimesh", "info")
OUTPUT_IS_LIST = (True, False) # TRIMESH is list, STRING is single summary
OUTPUT_NODE = True # Enable UI output for dynamic display
FUNCTION = "find_open_edges"
@@ -181,6 +181,7 @@ class OpenEdgesNode:
return {
"result": (result_meshes, summary),
"ui": {
"text": [summary],
"open_edges_data": ui_data
}
}
+2 -1
View File
@@ -37,6 +37,7 @@ class BooleanCGALNode:
RETURN_NAMES = ("result_mesh", "info")
FUNCTION = "boolean_op"
CATEGORY = "geompack/boolean"
OUTPUT_NODE = True
def boolean_op(self, mesh_a, mesh_b, operation):
"""
@@ -114,7 +115,7 @@ Watertight: {result.is_watertight}
"""
print(f"[Boolean CGAL] Success: {len(result.vertices)} vertices, {len(result.faces)} faces")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
except Exception as e:
raise RuntimeError(f"Boolean CGAL operation failed: {e}")
+2 -1
View File
@@ -35,6 +35,7 @@ class CombineMeshesNode:
RETURN_NAMES = ("combined_mesh", "info")
FUNCTION = "combine"
CATEGORY = "geompack/combine"
OUTPUT_NODE = True
def combine(self, mesh_a, mesh_b=None, mesh_c=None, mesh_d=None):
"""
@@ -109,7 +110,7 @@ Components remain separate within the combined mesh.
"""
print(f"[CombineMeshes] Result: {len(result.vertices)} vertices, {len(result.faces)} faces")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
# Node mappings
+2 -1
View File
@@ -33,6 +33,7 @@ class CombineMeshesBatchNode:
RETURN_NAMES = ("combined_mesh", "info")
FUNCTION = "combine"
CATEGORY = "geompack/combine"
OUTPUT_NODE = True
DESCRIPTION = "Combine a batch of meshes into a single mesh."
def combine(self, meshes):
@@ -121,7 +122,7 @@ Components remain separate within the combined mesh.
"""
print(f"[CombineMeshesBatch] Result: {len(result.vertices)} vertices, {len(result.faces)} faces")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
# Node mappings
+3 -2
View File
@@ -34,10 +34,11 @@ class SplitByFieldNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("geometries", "summary")
RETURN_NAMES = ("geometries", "info")
OUTPUT_IS_LIST = (True, False)
FUNCTION = "split"
CATEGORY = "geompack/combine"
OUTPUT_NODE = True
def split(self, geometry, field_name: str) -> Tuple:
"""Split geometry by a discrete field."""
@@ -131,7 +132,7 @@ class SplitByFieldNode:
print(f" {field_name}={val}: {num_points} points")
summary = "\n".join(summary_lines)
return (result, summary)
return {"ui": {"text": [summary]}, "result": (result, summary)}
# Node mappings
+1
View File
@@ -20,6 +20,7 @@ pymeshfix = ">=0.17.0"
xatlas = ">=0.0.11"
skeletor = ">=1.2.0"
pynanoinstantmeshes = "*"
pyquadriflow = { url = "https://github.com/PozzettiAndrea/pyQuadriFlow/releases/download/v0.0.3/pyquadriflow-0.0.4-py3-none-any.whl" }
matplotlib = ">=3.5.0"
pillow = ">=9.0.0"
pyvista = ">=0.43.0"
+16
View File
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2025 ComfyUI-GeometryPack Contributors
"""
ParaView/VTK filter nodes using PyVista.
"""
from .pv_filter import ParaViewFilterNode, NODE_CLASS_MAPPINGS as PV_FILTER_MAPS, NODE_DISPLAY_NAME_MAPPINGS as PV_FILTER_DISP
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
NODE_CLASS_MAPPINGS.update(PV_FILTER_MAPS)
NODE_DISPLAY_NAME_MAPPINGS.update(PV_FILTER_DISP)
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
+262
View File
@@ -0,0 +1,262 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2025 ComfyUI-GeometryPack Contributors
"""
ParaView/VTK filter node using PyVista.
Applies VTK analysis filters to meshes, producing scalar fields
for visualization in the Preview Mesh (VTK) viewer.
"""
import numpy as np
import trimesh
def _trimesh_to_pyvista(mesh):
"""Convert trimesh.Trimesh to pyvista.PolyData."""
import pyvista as pv
vertices = np.array(mesh.vertices)
faces = np.array(mesh.faces)
faces_pv = np.column_stack([np.full(len(faces), 3), faces])
pv_mesh = pv.PolyData(vertices, faces_pv)
# Transfer vertex_attributes -> point_data
if hasattr(mesh, 'vertex_attributes'):
for name, data in mesh.vertex_attributes.items():
arr = np.array(data)
if arr.ndim == 1 and len(arr) == len(vertices):
pv_mesh.point_data[name] = arr.astype(np.float32)
# Transfer face_attributes -> cell_data
if hasattr(mesh, 'face_attributes'):
for name, data in mesh.face_attributes.items():
arr = np.array(data)
if arr.ndim == 1 and len(arr) == len(faces):
pv_mesh.cell_data[name] = arr.astype(np.float32)
return pv_mesh
def _pyvista_to_trimesh(pv_mesh):
"""Convert pyvista.PolyData back to trimesh.Trimesh."""
vertices = np.array(pv_mesh.points)
# Parse pyvista face format: [n, v0, v1, ..., n, v0, v1, ...]
faces = []
if pv_mesh.n_faces > 0:
faces_flat = np.array(pv_mesh.faces)
i = 0
while i < len(faces_flat):
n = faces_flat[i]
if n == 3:
faces.append(faces_flat[i + 1:i + 4])
elif n == 4:
# Triangulate quads
faces.append([faces_flat[i + 1], faces_flat[i + 2], faces_flat[i + 3]])
faces.append([faces_flat[i + 1], faces_flat[i + 3], faces_flat[i + 4]])
i += n + 1
if faces:
faces = np.array(faces, dtype=np.int32)
else:
faces = np.zeros((0, 3), dtype=np.int32)
result = trimesh.Trimesh(vertices=vertices, faces=faces, process=False)
# Transfer point_data -> vertex_attributes
for name in pv_mesh.point_data.keys():
data = np.array(pv_mesh.point_data[name])
if data.ndim == 1 and len(data) == len(vertices):
result.vertex_attributes[name] = data.astype(np.float32)
# Transfer cell_data -> face_attributes
for name in pv_mesh.cell_data.keys():
data = np.array(pv_mesh.cell_data[name])
if data.ndim == 1 and len(data) == len(faces):
result.face_attributes[name] = data.astype(np.float32)
return result
class ParaViewFilterNode:
"""
Apply VTK/ParaView analysis filters to meshes using PyVista.
Produces scalar fields for visualization in Preview Mesh (fields mode).
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"trimesh": ("TRIMESH",),
"filter_type": ([
"curvature_gaussian",
"curvature_mean",
"cell_sizes",
"elevation",
"feature_edges",
"warp_by_scalar",
], {"default": "curvature_gaussian"}),
},
"optional": {
"axis": (["X", "Y", "Z"], {
"default": "Z",
"tooltip": "Axis for elevation or warp direction"
}),
"factor": ("FLOAT", {
"default": 1.0,
"min": -100.0,
"max": 100.0,
"step": 0.1,
"tooltip": "Scale factor for warp_by_scalar"
}),
"scalar_field": ("STRING", {
"default": "",
"tooltip": "Vertex attribute name for warp_by_scalar"
}),
"angle": ("FLOAT", {
"default": 30.0,
"min": 0.0,
"max": 180.0,
"step": 1.0,
"tooltip": "Feature edge angle threshold (degrees)"
}),
},
}
RETURN_TYPES = ("TRIMESH",)
RETURN_NAMES = ("filtered_mesh",)
FUNCTION = "apply_filter"
CATEGORY = "geompack/paraview"
def apply_filter(self, trimesh, filter_type, axis="Z", factor=1.0, scalar_field="", angle=30.0):
"""
Apply a VTK filter via PyVista.
Args:
trimesh: Input trimesh.Trimesh object
filter_type: Which filter to apply
axis: Axis for elevation/warp
factor: Scale factor for warp
scalar_field: Vertex attribute name for warp_by_scalar
angle: Feature edge angle threshold
Returns:
tuple: (filtered_mesh,)
"""
try:
import pyvista as pv
except (ImportError, OSError):
raise ImportError(
"ParaView Filter requires pyvista. Install with: pip install pyvista"
)
# Validate input
if not hasattr(trimesh, 'faces') or len(trimesh.faces) == 0:
raise ValueError("ParaView Filter requires a mesh with faces, not a point cloud")
print(f"[ParaViewFilter] Applying '{filter_type}' to mesh: "
f"{len(trimesh.vertices)} vertices, {len(trimesh.faces)} faces")
# Convert to pyvista
pv_mesh = _trimesh_to_pyvista(trimesh)
# Apply filter
if filter_type == "curvature_gaussian":
pv_result = pv_mesh.curvature('gaussian')
# curvature() returns a new mesh with 'Gauss_Curvature' in point_data
result = _pyvista_to_trimesh(pv_result)
# Rename to friendlier name
if 'Gauss_Curvature' in result.vertex_attributes:
result.vertex_attributes['curvature'] = result.vertex_attributes.pop('Gauss_Curvature')
print(f"[ParaViewFilter] Computed Gaussian curvature")
elif filter_type == "curvature_mean":
pv_result = pv_mesh.curvature('mean')
result = _pyvista_to_trimesh(pv_result)
if 'Mean_Curvature' in result.vertex_attributes:
result.vertex_attributes['curvature'] = result.vertex_attributes.pop('Mean_Curvature')
print(f"[ParaViewFilter] Computed mean curvature")
elif filter_type == "cell_sizes":
pv_result = pv_mesh.compute_cell_sizes(length=False, volume=False, area=True)
result = _pyvista_to_trimesh(pv_result)
print(f"[ParaViewFilter] Computed cell sizes (face areas)")
elif filter_type == "elevation":
axis_map = {"X": 0, "Y": 1, "Z": 2}
ax = axis_map.get(axis, 2)
bounds = pv_mesh.bounds
low_point = [0.0, 0.0, 0.0]
high_point = [0.0, 0.0, 0.0]
low_point[ax] = bounds[ax * 2]
high_point[ax] = bounds[ax * 2 + 1]
pv_result = pv_mesh.elevation(
low_point=low_point,
high_point=high_point,
set_active_scalars=True
)
result = _pyvista_to_trimesh(pv_result)
print(f"[ParaViewFilter] Computed elevation along {axis} axis")
elif filter_type == "feature_edges":
pv_result = pv_mesh.extract_feature_edges(
feature_angle=angle,
boundary_edges=True,
non_manifold_edges=True,
manifold_edges=False,
)
if pv_result.n_points == 0:
print(f"[ParaViewFilter] Warning: No feature edges found at angle={angle}")
# Return original mesh with an empty marker attribute
result = trimesh.copy()
result.vertex_attributes['feature_edge'] = np.zeros(len(result.vertices), dtype=np.float32)
else:
result = _pyvista_to_trimesh(pv_result)
print(f"[ParaViewFilter] Extracted feature edges: {pv_result.n_points} points, {pv_result.n_lines} lines")
elif filter_type == "warp_by_scalar":
if not scalar_field:
available = list(trimesh.vertex_attributes.keys()) if hasattr(trimesh, 'vertex_attributes') else []
raise ValueError(
f"warp_by_scalar requires a scalar_field name. "
f"Available vertex attributes: {available}"
)
if scalar_field not in pv_mesh.point_data:
available = list(pv_mesh.point_data.keys())
raise ValueError(
f"scalar_field '{scalar_field}' not found. "
f"Available: {available}"
)
pv_result = pv_mesh.warp_by_scalar(
scalars=scalar_field,
factor=factor,
)
result = _pyvista_to_trimesh(pv_result)
print(f"[ParaViewFilter] Warped by '{scalar_field}' with factor={factor}")
else:
raise ValueError(f"Unknown filter type: {filter_type}")
print(f"[ParaViewFilter] Result: {len(result.vertices)} vertices, {len(result.faces)} faces")
# List output fields
v_attrs = list(result.vertex_attributes.keys()) if hasattr(result, 'vertex_attributes') else []
f_attrs = list(result.face_attributes.keys()) if hasattr(result, 'face_attributes') else []
if v_attrs:
print(f"[ParaViewFilter] Vertex attributes: {v_attrs}")
if f_attrs:
print(f"[ParaViewFilter] Face attributes: {f_attrs}")
return (result,)
NODE_CLASS_MAPPINGS = {
"GeomPackParaViewFilter": ParaViewFilterNode,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"GeomPackParaViewFilter": "ParaView Filter",
}
+3 -2
View File
@@ -57,9 +57,10 @@ class AlphaWrapNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("wrapped_mesh", "report")
RETURN_NAMES = ("wrapped_mesh", "info")
FUNCTION = "alpha_wrap"
CATEGORY = "geompack/reconstruction"
OUTPUT_NODE = True
def alpha_wrap(self, input_mesh, alpha_percent=0.04, offset_percent=1.1):
"""
@@ -197,7 +198,7 @@ Tips:
- Lower values = slower computation
"""
return (result_mesh, report)
return {"ui": {"text": [report]}, "result": (result_mesh, report)}
NODE_CLASS_MAPPINGS = {
+100 -4
View File
@@ -2,7 +2,7 @@
# Copyright (C) 2025 ComfyUI-GeometryPack Contributors
"""
Remesh Node - Main backends (pymeshlab, instant_meshes)
Remesh Node - Main backends (pymeshlab, instant_meshes, quadriflow)
"""
import numpy as np
@@ -125,9 +125,10 @@ class RemeshNode:
Available backends:
- pymeshlab_isotropic: PyMeshLab isotropic remeshing (fast)
- instant_meshes: Field-aligned quad remeshing
- quadriflow: QuadriFlow quad remeshing (good topology)
For CGAL isotropic remeshing, use "Remesh CGAL" node.
For Blender voxel/quadriflow remeshing, use "Remesh Blender" node.
For Blender voxel/modifier remeshing, use "Remesh Blender" node.
For GPU-accelerated remeshing, use "Remesh GPU" node.
"""
@@ -139,9 +140,10 @@ class RemeshNode:
"backend": ([
"pymeshlab_isotropic",
"instant_meshes",
"quadriflow",
], {
"default": "pymeshlab_isotropic",
"tooltip": "Remeshing algorithm. pymeshlab=fast isotropic, instant_meshes=field-aligned quads"
"tooltip": "Remeshing algorithm. pymeshlab=fast isotropic, instant_meshes=field-aligned quads, quadriflow=quad remesh with good topology"
}),
},
"optional": {
@@ -199,6 +201,25 @@ class RemeshNode:
"tooltip": "Angle threshold (degrees) for preserving sharp/crease edges in Instant Meshes. 0 = no crease preservation.",
"visible_when": {"backend": ["instant_meshes"]},
}),
# QuadriFlow specific
"target_face_count": ("INT", {
"default": 5000,
"min": 100,
"max": 5000000,
"step": 100,
"tooltip": "Target number of output faces for QuadriFlow. Creates quad-dominant mesh with good topology.",
"visible_when": {"backend": ["quadriflow"]},
}),
"preserve_sharp": (["true", "false"], {
"default": "false",
"tooltip": "Preserve sharp edges during QuadriFlow remeshing.",
"visible_when": {"backend": ["quadriflow"]},
}),
"preserve_boundary": (["true", "false"], {
"default": "true",
"tooltip": "Preserve mesh boundary edges during QuadriFlow remeshing.",
"visible_when": {"backend": ["quadriflow"]},
}),
}
}
@@ -210,8 +231,17 @@ class RemeshNode:
def remesh(self, trimesh, backend, target_edge_length=1.0, iterations=3,
feature_angle=30.0, adaptive="false",
target_vertex_count=5000, deterministic="true", crease_angle=0.0):
target_vertex_count=5000, deterministic="true", crease_angle=0.0,
target_face_count=5000, preserve_sharp="false", preserve_boundary="true"):
"""Apply remeshing based on selected backend."""
# Sanitize hidden widget values (ComfyUI sends '' for hidden visible_when widgets)
target_edge_length = float(target_edge_length) if target_edge_length not in (None, '') else 1.0
iterations = int(iterations) if iterations not in (None, '') else 3
feature_angle = float(feature_angle) if feature_angle not in (None, '') else 30.0
target_vertex_count = int(target_vertex_count) if target_vertex_count not in (None, '') else 5000
crease_angle = float(crease_angle) if crease_angle not in (None, '') else 0.0
target_face_count = int(target_face_count) if target_face_count not in (None, '') else 5000
initial_vertices = len(trimesh.vertices)
initial_faces = len(trimesh.faces)
@@ -229,6 +259,11 @@ class RemeshNode:
remeshed_mesh, info = self._instant_meshes(
trimesh, target_vertex_count, deterministic, crease_angle
)
elif backend == "quadriflow":
print(f"[Remesh] Parameters: target_face_count={target_face_count:,}, preserve_sharp={preserve_sharp}, preserve_boundary={preserve_boundary}")
remeshed_mesh, info = self._quadriflow(
trimesh, target_face_count, preserve_sharp, preserve_boundary
)
else:
raise ValueError(f"Unknown backend: {backend}")
@@ -319,6 +354,67 @@ After:
Faces: {len(remeshed_mesh.faces):,}
Instant Meshes creates flow-aligned quad meshes.
"""
return remeshed_mesh, info
def _quadriflow(self, trimesh, target_face_count, preserve_sharp, preserve_boundary):
"""QuadriFlow quad remeshing using pyQuadriFlow."""
try:
from pyQuadriFlow.pyQuadriFlow import pyquadriflow
except ImportError:
raise ImportError(
"pyQuadriFlow not installed. Install with: pip install pyQuadriFlow"
)
V = np.asarray(trimesh.vertices, dtype=np.float64).tolist()
F = np.asarray(trimesh.faces, dtype=np.int32).tolist()
print(f"[Remesh] Running QuadriFlow (target_faces={target_face_count})...")
result = pyquadriflow(
target_face_count,
0, # seed
V,
F,
preserve_sharp == "true",
preserve_boundary == "true",
False, # adaptive_scale
False, # aggressive_sat
False, # minimum_cost_flow
)
V_out = result['vertices']
F_out = result['faces']
remeshed_mesh = trimesh_module.Trimesh(
vertices=np.array(V_out, dtype=np.float32),
faces=np.array(F_out, dtype=np.int32),
process=False
)
remeshed_mesh.metadata = trimesh.metadata.copy()
remeshed_mesh.metadata['remeshing'] = {
'algorithm': 'quadriflow',
'target_face_count': target_face_count,
'preserve_sharp': preserve_sharp == "true",
'preserve_boundary': preserve_boundary == "true",
'original_vertices': len(trimesh.vertices),
'original_faces': len(trimesh.faces)
}
info = f"""Remesh Results (QuadriFlow):
Target Face Count: {target_face_count:,}
Preserve Sharp: {preserve_sharp}
Preserve Boundary: {preserve_boundary}
Before:
Vertices: {len(trimesh.vertices):,}
Faces: {len(trimesh.faces):,}
After:
Vertices: {len(remeshed_mesh.vertices):,}
Faces: {len(remeshed_mesh.faces):,}
QuadriFlow creates quad-dominant meshes with good topology.
"""
return remeshed_mesh, info
@@ -63,6 +63,7 @@ class AddNormalsToPointCloud:
RETURN_NAMES = ("pointcloud_with_normals", "info")
FUNCTION = "add_normals"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
DESCRIPTION = "Estimate and add normals to a point cloud using Open3D or PyMeshLab methods."
def add_normals(
@@ -160,7 +161,7 @@ class AddNormalsToPointCloud:
print(f"[AddNormalsToPointCloud] [OK] {info}")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
def _estimate_normals_open3d_knn(self, points, k_neighbors, orient_normals):
"""
+3 -2
View File
@@ -26,9 +26,10 @@ class CheckNormalsNode:
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("report",)
RETURN_NAMES = ("info",)
FUNCTION = "check_normals"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def check_normals(self, trimesh):
"""
@@ -98,7 +99,7 @@ Recommendations:
print(f"[CheckNormals] Winding: {is_winding_consistent}, Watertight: {is_watertight}, Degenerate: {degenerate_faces}")
return (report,)
return {"ui": {"text": [report]}, "result": (report,)}
NODE_CLASS_MAPPINGS = {
@@ -33,9 +33,10 @@ class FixSelfIntersectionsByRemovalNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("fixed_mesh", "report")
RETURN_NAMES = ("fixed_mesh", "info")
FUNCTION = "fix_by_removal"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def fix_by_removal(self, trimesh, fill_holes=True, fix_normals=True, max_hole_size=100,
re_detect_after_fix=True):
@@ -72,7 +73,7 @@ Returning mesh unchanged.
Workflow suggestion:
1. Load Mesh -> Detect Self Intersections -> Fix Self Intersections By Removal
"""
return (trimesh, warning_msg)
return {"ui": {"text": [warning_msg]}, "result": (trimesh, warning_msg)}
# Get intersecting face indices
face_field = trimesh.face_attributes['self_intersecting']
@@ -89,7 +90,7 @@ Either the mesh is already clean, or you need to run
Returning mesh unchanged.
"""
return (trimesh, report)
return {"ui": {"text": [report]}, "result": (trimesh, report)}
print(f"[FixByRemoval] Found {num_intersecting} intersecting faces to remove")
@@ -246,7 +247,7 @@ Status:
"""
print(f"[FixByRemoval] Complete: {final_vertices} vertices, {final_faces} faces")
return (result_mesh, report)
return {"ui": {"text": [report]}, "result": (result_mesh, report)}
NODE_CLASS_MAPPINGS = {
+2 -1
View File
@@ -169,6 +169,7 @@ class FixNormalsNode:
RETURN_NAMES = ("fixed_mesh", "info")
FUNCTION = "fix_normals"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def fix_normals(self, trimesh, method="trimesh"):
"""
@@ -295,7 +296,7 @@ Faces: {len(fixed_mesh.faces):,}
print(f"[FixNormals] {'[OK]' if is_consistent else '[WARN]'} Normal orientation: {was_consistent} -> {is_consistent}")
return (fixed_mesh, info)
return {"ui": {"text": [info]}, "result": (fixed_mesh, info)}
# Node mappings
+2 -1
View File
@@ -45,6 +45,7 @@ class MergeVerticesNode:
RETURN_NAMES = ("merged_mesh", "info")
FUNCTION = "merge_vertices"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def merge_vertices(self, mesh, tolerance=1e-5):
"""
@@ -123,7 +124,7 @@ After:
if components_change is not None:
print(f"[MergeVertices] Components: {components_before} -> {components_after}")
return (merged_mesh, info)
return {"ui": {"text": [info]}, "result": (merged_mesh, info)}
NODE_CLASS_MAPPINGS = {
+1 -1
View File
@@ -77,7 +77,7 @@ class MeshFixNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("repaired_mesh", "report")
RETURN_NAMES = ("repaired_mesh", "info")
FUNCTION = "repair_mesh"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
+2 -1
View File
@@ -46,6 +46,7 @@ class RemoveDegenerateFacesNode:
RETURN_NAMES = ("cleaned_mesh", "info")
FUNCTION = "remove_degenerate"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def remove_degenerate(self, mesh, min_area=1e-10):
"""
@@ -116,7 +117,7 @@ After:
print(f"[RemoveDegenerateFaces] Removed {faces_removed} degenerate faces, {verts_removed} unreferenced vertices")
return (cleaned_mesh, info)
return {"ui": {"text": [info]}, "result": (cleaned_mesh, info)}
NODE_CLASS_MAPPINGS = {
+2 -1
View File
@@ -30,6 +30,7 @@ class VisualizNormalFieldNode:
RETURN_NAMES = ("mesh_with_fields", "info")
FUNCTION = "visualize_normals"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def visualize_normals(self, trimesh):
"""
@@ -76,7 +77,7 @@ Expected Values:
print(f"[VisualizeNormals] Added 4 scalar fields to mesh")
return (result_mesh, info)
return {"ui": {"text": [info]}, "result": (result_mesh, info)}
NODE_CLASS_MAPPINGS = {
@@ -29,7 +29,7 @@ class DetectSelfIntersectionsNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("mesh_with_field", "report")
RETURN_NAMES = ("mesh_with_field", "info")
OUTPUT_NODE = True # Enable UI output for dynamic display
FUNCTION = "detect_intersections"
CATEGORY = "geompack/repair"
@@ -195,6 +195,7 @@ Use 'Preview Mesh (VTK with Fields)' node to visualize the intersection fields!
return {
"result": (result_mesh, report),
"ui": {
"text": [report],
"intersection_data": [ui_data]
}
}
@@ -211,7 +212,7 @@ Install with: pip install libigl cgal
For now, returning mesh unchanged.
"""
print(f"[DetectSelfIntersections] libigl import error: {e}")
return (trimesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (trimesh, error_msg)}
except Exception as e:
import traceback
@@ -223,7 +224,7 @@ For now, returning mesh unchanged.
Returning mesh unchanged. Check console for details.
"""
print(f"[DetectSelfIntersections] Unexpected error: {e}")
return (trimesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (trimesh, error_msg)}
NODE_CLASS_MAPPINGS = {
@@ -34,9 +34,10 @@ class FixSelfIntersectionsByPerturbationNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("fixed_mesh", "report")
RETURN_NAMES = ("fixed_mesh", "info")
FUNCTION = "fix_by_perturbation"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def fix_by_perturbation(self, trimesh, epsilon=0.001, max_iterations=10,
direction="outward", scale_by_intersection_count=True,
@@ -72,7 +73,7 @@ Returning mesh unchanged.
Workflow suggestion:
1. Load Mesh -> Detect Self Intersections -> Fix Self Intersections By Perturbation
"""
return (trimesh, warning_msg)
return {"ui": {"text": [warning_msg]}, "result": (trimesh, warning_msg)}
# Get vertices to perturb
vertex_flags = trimesh.vertex_attributes['intersection_flag']
@@ -89,7 +90,7 @@ Either the mesh is already clean, or you need to run
Returning mesh unchanged.
"""
return (trimesh, report)
return {"ui": {"text": [report]}, "result": (trimesh, report)}
print(f"[FixByPerturbation] Found {num_affected} vertices to perturb")
@@ -279,7 +280,7 @@ Important Notes:
"""
print(f"[FixByPerturbation] Complete: perturbed {num_affected} vertices over {iterations_used} iterations")
return (result_mesh, report)
return {"ui": {"text": [report]}, "result": (result_mesh, report)}
NODE_CLASS_MAPPINGS = {
@@ -32,9 +32,10 @@ class RemeshSelfIntersectionsNode:
}
RETURN_TYPES = ("TRIMESH", "STRING")
RETURN_NAMES = ("fixed_mesh", "report")
RETURN_NAMES = ("fixed_mesh", "info")
FUNCTION = "remesh_intersections"
CATEGORY = "geompack/repair"
OUTPUT_NODE = True
def remesh_intersections(self, mesh, detect_only=False, remove_unreferenced=True,
extract_outer_hull=False, stitch_all=True):
@@ -74,7 +75,7 @@ Install with: pip install cgal
Returning mesh unchanged.
"""
print("[RemeshSelfIntersections] CGAL not available")
return (mesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (mesh, error_msg)}
print("[RemeshSelfIntersections] Using libigl CGAL method")
@@ -186,7 +187,7 @@ Status:
{' Consider enabling extract_outer_hull for a clean manifold result.' if not extract_outer_hull else ''}
"""
return (result_mesh, report)
return {"ui": {"text": [report]}, "result": (result_mesh, report)}
except Exception as e:
import traceback
@@ -198,7 +199,7 @@ Status:
Returning mesh unchanged. Check console for details.
"""
print(f"[RemeshSelfIntersections] Remeshing error: {e}")
return (mesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (mesh, error_msg)}
except ImportError as e:
error_msg = f"""Error: libigl not available
@@ -211,7 +212,7 @@ Install with: pip install libigl cgal
Returning mesh unchanged.
"""
print(f"[RemeshSelfIntersections] libigl import error: {e}")
return (mesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (mesh, error_msg)}
except Exception as e:
import traceback
@@ -223,7 +224,7 @@ Returning mesh unchanged.
Returning mesh unchanged. Check console for details.
"""
print(f"[RemeshSelfIntersections] Unexpected error: {e}")
return (mesh, error_msg)
return {"ui": {"text": [error_msg]}, "result": (mesh, error_msg)}
NODE_CLASS_MAPPINGS = {
@@ -96,6 +96,7 @@ class DepthNormalsToMeshNode:
RETURN_NAMES = ("mesh", "info")
FUNCTION = "depth_normals_to_mesh"
CATEGORY = "geompack/texture_remeshing"
OUTPUT_NODE = True
def depth_normals_to_mesh(self, normal_map, resolution, depth_scale,
depth=None, depth_image=None,
@@ -265,7 +266,7 @@ Output Mesh:
{method_info}
"""
return (mesh, info)
return {"ui": {"text": [info]}, "result": (mesh, info)}
def _poisson_reconstruct(self, points, normals, depth, scale):
"""Poisson surface reconstruction using Open3D or PyMeshLab."""
+2 -1
View File
@@ -49,6 +49,7 @@ class NormalizeMeshToBBox:
RETURN_NAMES = ("normalized_mesh", "info")
FUNCTION = "normalize_to_bbox"
CATEGORY = "geompack/transforms"
OUTPUT_NODE = True
DESCRIPTION = "Center and scale mesh isotropically to fit target bounding box. Use before estimating normals for TripoSF."
def normalize_to_bbox(self, trimesh, target_size=1.0):
@@ -132,7 +133,7 @@ New Bounds:
Note: Use this BEFORE AddNormalsToPointCloud for TripoSF workflows.
"""
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
# Node registration
+2 -1
View File
@@ -152,6 +152,7 @@ class TransformMeshNode:
RETURN_NAMES = ("transformed_mesh", "info")
FUNCTION = "transform"
CATEGORY = "geompack/transforms"
OUTPUT_NODE = True
def transform(self, trimesh, operation,
translate_x=0.0, translate_y=0.0, translate_z=0.0,
@@ -203,7 +204,7 @@ class TransformMeshNode:
}
print(f"[Transform] Complete")
return (result, info)
return {"ui": {"text": [info]}, "result": (result, info)}
def _translate(self, mesh, tx, ty, tz):
"""Translate mesh by offset."""
+2 -1
View File
@@ -294,6 +294,7 @@ class UVUnwrapNode:
RETURN_NAMES = ("unwrapped_mesh", "info")
FUNCTION = "unwrap"
CATEGORY = "geompack/uv"
OUTPUT_NODE = True
def unwrap(self, trimesh, method,
chart_cone_angle=90.0, chart_refine_iterations=0,
@@ -352,7 +353,7 @@ class UVUnwrapNode:
print(f"[UVUnwrap] Output: {len(unwrapped_mesh.vertices)} vertices, {len(unwrapped_mesh.faces)} faces")
return (unwrapped_mesh, info)
return {"ui": {"text": [info]}, "result": (unwrapped_mesh, info)}
def _xatlas(self, trimesh):
"""XAtlas automatic UV unwrapping."""
+19 -1
View File
@@ -82,6 +82,18 @@ class PreviewMeshDualNode:
"mode": (["fields", "texture"], {"default": "fields"}),
"opacity_1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.1}),
"opacity_2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.1}),
"show_edges": ("BOOLEAN", {
"default": False,
"tooltip": "Show mesh edge overlay"
}),
"camera_state": ("STRING", {
"default": "",
"tooltip": "Camera position/orientation state (managed by viewer)"
}),
"selected_field": ("STRING", {
"default": "",
"tooltip": "Active scalar field for visualization (managed by viewer)"
}),
}
}
@@ -90,7 +102,7 @@ class PreviewMeshDualNode:
FUNCTION = "preview_dual"
CATEGORY = "geompack/visualization"
def preview_dual(self, mesh_1, mesh_2, layout="side_by_side", mode="fields", opacity_1=1.0, opacity_2=1.0):
def preview_dual(self, mesh_1, mesh_2, layout="side_by_side", mode="fields", opacity_1=1.0, opacity_2=1.0, show_edges=False, camera_state="", selected_field=""):
"""
Preview two meshes with chosen layout and visualization mode.
@@ -171,6 +183,9 @@ class PreviewMeshDualNode:
"is_watertight_2": [bool(mesh_2.is_watertight) if not is_point_cloud(mesh_2) else False],
"opacity_1": [float(opacity_1)],
"opacity_2": [float(opacity_2)],
"show_edges": [bool(show_edges)],
"camera_state": [camera_state],
"selected_field": [selected_field],
}
# Add mode-specific metadata
@@ -233,6 +248,9 @@ class PreviewMeshDualNode:
"opacity_2": [float(opacity_2)],
"is_watertight_1": [bool(mesh_1.is_watertight) if not is_point_cloud(mesh_1) else False],
"is_watertight_2": [bool(mesh_2.is_watertight) if not is_point_cloud(mesh_2) else False],
"show_edges": [bool(show_edges)],
"camera_state": [camera_state],
"selected_field": [selected_field],
}
# Add mode-specific metadata
+16 -1
View File
@@ -87,6 +87,18 @@ class PreviewMeshMultiNode:
"mesh_3": ("TRIMESH",),
"mesh_4": ("TRIMESH",),
"mode": (["fields", "texture"], {"default": "fields"}),
"show_edges": ("BOOLEAN", {
"default": False,
"tooltip": "Show mesh edge overlay"
}),
"camera_state": ("STRING", {
"default": "",
"tooltip": "Camera position/orientation state (managed by viewer)"
}),
"selected_field": ("STRING", {
"default": "",
"tooltip": "Active scalar field for visualization (managed by viewer)"
}),
}
}
@@ -95,7 +107,7 @@ class PreviewMeshMultiNode:
FUNCTION = "preview_multi"
CATEGORY = "geompack/visualization"
def preview_multi(self, mesh_1, mesh_2=None, mesh_3=None, mesh_4=None, mode="fields"):
def preview_multi(self, mesh_1, mesh_2=None, mesh_3=None, mesh_4=None, mode="fields", show_edges=False, camera_state="", selected_field=""):
"""
Preview multiple meshes in a grid layout.
@@ -205,6 +217,9 @@ class PreviewMeshMultiNode:
"bounds_list": [bounds_list],
"extents_list": [extents_list],
"is_watertight_list": [is_watertight_list],
"show_edges": [bool(show_edges)],
"camera_state": [camera_state],
"selected_field": [selected_field],
}
# Add mode-specific metadata
+16 -1
View File
@@ -43,6 +43,18 @@ class PreviewMeshVTKNode:
"optional": {
"trimesh": ("TRIMESH",),
"voxelgrid": ("VOXELGRID",),
"show_edges": ("BOOLEAN", {
"default": False,
"tooltip": "Show mesh edge overlay"
}),
"camera_state": ("STRING", {
"default": "",
"tooltip": "Camera position/orientation state (managed by viewer)"
}),
"selected_field": ("STRING", {
"default": "",
"tooltip": "Active scalar field for visualization (managed by viewer)"
}),
},
}
@@ -51,7 +63,7 @@ class PreviewMeshVTKNode:
FUNCTION = "preview_mesh_vtk"
CATEGORY = "geompack/visualization"
def preview_mesh_vtk(self, mode="fields", trimesh=None, voxelgrid=None):
def preview_mesh_vtk(self, mode="fields", trimesh=None, voxelgrid=None, show_edges=False, camera_state="", selected_field=""):
"""
Export mesh and prepare for VTK.js preview.
@@ -231,6 +243,9 @@ class PreviewMeshVTKNode:
"extents": [extents.tolist()],
"max_extent": [float(max_extent)],
"is_watertight": [bool(is_watertight)],
"show_edges": [bool(show_edges)],
"camera_state": [camera_state],
"selected_field": [selected_field],
}
# Add mode-specific metadata
@@ -44,6 +44,12 @@ class PreviewMeshVTKBatchNode:
"mode": (["fields", "texture"], {"default": "fields"}),
"index": ("INT", {"default": 0, "min": 0, "max": 100}),
},
"optional": {
"show_edges": ("BOOLEAN", {
"default": False,
"tooltip": "Show mesh edge overlay"
}),
},
}
RETURN_TYPES = ()
@@ -52,7 +58,7 @@ class PreviewMeshVTKBatchNode:
CATEGORY = "geompack/visualization"
INPUT_IS_LIST = True
def preview_mesh_vtk_batch(self, trimesh, mode, index):
def preview_mesh_vtk_batch(self, trimesh, mode, index, show_edges=None):
"""
Export mesh from batch and prepare for VTK.js preview.
@@ -71,6 +77,7 @@ class PreviewMeshVTKBatchNode:
# Extract values from lists (ComfyUI passes inputs as lists when INPUT_IS_LIST=True)
mode_val = mode[0] if isinstance(mode, list) else mode
index_val = index[0] if isinstance(index, list) else index
show_edges_val = (show_edges[0] if isinstance(show_edges, list) else show_edges) if show_edges is not None else False
# Validate batch
if not trimesh or len(trimesh) == 0:
@@ -205,6 +212,7 @@ class PreviewMeshVTKBatchNode:
# Batch-specific metadata
"batch_size": [batch_size],
"current_index": [actual_index],
"show_edges": [bool(show_edges_val)],
}
# Add mode-specific metadata
+2 -1
View File
@@ -18,7 +18,8 @@ viewers = [
"multi", "dual", "dual_slider", "dual_textured",
"uv", "pbr", "gaussian",
"fbx", "fbx_debug", "fbx_compare",
"bvh", "fbx_animation", "compare_smpl_bvh"
"bvh", "fbx_animation", "compare_smpl_bvh",
"text_report",
]
for viewer in viewers:
try:
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-geometrypack"
description = "CGAL - Blender - IGL - Paraview - VTK. Geometry processing nodes for ComfyUI - mesh manipulation, remeshing, hole filling, UV unwrapping, Alpha Wrapping, and 3D visualization"
version = "0.1.16"
version = "0.2.0"
license = {file = "LICENSE"}
[project.urls]
+3 -3
View File
@@ -1,7 +1,7 @@
# Main process deps (prestartup + lightweight shared libs)
comfy-env==0.1.79
comfy-dynamic-widgets==0.1.1
comfy-3d-viewers==0.2.6
comfy-env==0.1.90
comfy-dynamic-widgets==0.1.4
comfy-3d-viewers==0.2.17
numpy
trimesh[easy]>=4.0.0
scipy>=1.7.0
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"id":"b2c3d4e5-6789-01ab-cdef-234567890bcd","revision":0,"last_node_id":10,"last_link_id":12,"nodes":[{"id":6,"type":"GeomPackPreviewMeshVTKBatch","pos":[270.4873325918748,58.03082610700009],"size":[648.2642445312499,772.8686878906249],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":12},{"localized_name":"mode","name":"mode","type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"84b2d1816c08ec3cc7d3a4fffa90692669e17507","Node name for S&R":"GeomPackPreviewMeshVTKBatch","cnr_id":"comfyui-geometrypack"},"widgets_values":["fields",0,""]},{"id":4,"type":"GeomPackMeshInfo","pos":[85.91166423249982,-297.85304381487504],"size":[210,330],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":7}],"outputs":[{"localized_name":"info","name":"info","type":"STRING","links":[]}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"84b2d1816c08ec3cc7d3a4fffa90692669e17507","Node name for S&R":"GeomPackMeshInfo","cnr_id":"comfyui-geometrypack"},"widgets_values":[""]},{"id":1,"type":"GeomPackLoadMeshBatch","pos":[-635.45703125,14.94140625],"size":[320,150],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"folder_path","name":"folder_path","type":"STRING","widget":{"name":"folder_path"},"link":null},{"localized_name":"start_index","name":"start_index","type":"INT","widget":{"name":"start_index"},"link":null},{"localized_name":"max_meshes","name":"max_meshes","type":"INT","widget":{"name":"max_meshes"},"link":null}],"outputs":[{"localized_name":"meshes","name":"meshes","shape":6,"type":"TRIMESH","slot_index":0,"links":[7,11]}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMeshBatch","cnr_id":"comfyui-geometrypack"},"widgets_values":["3d",0,4]},{"id":10,"type":"GeomPackRemesh","pos":[-133.629473658125,61.91437181012475],"size":[212.744140625,328],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":11},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"feature_angle","name":"feature_angle","shape":7,"type":"FLOAT","widget":{"name":"feature_angle"},"link":null},{"localized_name":"adaptive","name":"adaptive","shape":7,"type":"COMBO","widget":{"name":"adaptive"},"link":null},{"localized_name":"target_vertex_count","name":"target_vertex_count","shape":7,"type":"INT","widget":{"name":"target_vertex_count"},"link":null},{"localized_name":"deterministic","name":"deterministic","shape":7,"type":"COMBO","widget":{"name":"deterministic"},"link":null},{"localized_name":"crease_angle","name":"crease_angle","shape":7,"type":"FLOAT","widget":{"name":"crease_angle"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[12]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"f9bba2bb5a0b42f6db8a70734e16acd25efcb485","Node name for S&R":"GeomPackRemesh"},"widgets_values":["pymeshlab_isotropic",1,3,30,"false",5000,"true",0,""]}],"links":[[7,1,0,4,0,"TRIMESH"],[11,1,0,10,0,"TRIMESH"],[12,10,0,6,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":1,"offset":[871.129473658125,345.08562818987525]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id":"b2c3d4e5-6789-01ab-cdef-234567890bcd","revision":0,"last_node_id":11,"last_link_id":15,"nodes":[{"id":4,"type":"GeomPackMeshInfo","pos":[85.91166423249982,-297.85304381487504],"size":[210,66],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":7}],"outputs":[{"localized_name":"info","name":"info","type":"STRING","links":[]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"84b2d1816c08ec3cc7d3a4fffa90692669e17507","Node name for S&R":"GeomPackMeshInfo","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":[""]},{"id":1,"type":"GeomPackLoadMeshBatch","pos":[-635.45703125,14.94140625],"size":[320,150],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"folder_path","name":"folder_path","type":"STRING","widget":{"name":"folder_path"},"link":null},{"localized_name":"start_index","name":"start_index","type":"INT","widget":{"name":"start_index"},"link":null},{"localized_name":"max_meshes","name":"max_meshes","type":"INT","widget":{"name":"max_meshes"},"link":null}],"outputs":[{"localized_name":"meshes","name":"meshes","shape":6,"type":"TRIMESH","slot_index":0,"links":[7,14]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMeshBatch","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["3d",0,4]},{"id":11,"type":"GeomPackRemesh","pos":[-144.22632486551126,161.44117614251124],"size":[212.744140625,206],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":14},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"feature_angle","name":"feature_angle","shape":7,"type":"FLOAT","widget":{"name":"feature_angle"},"link":null},{"localized_name":"adaptive","name":"adaptive","shape":7,"type":"COMBO","widget":{"name":"adaptive"},"link":null},{"localized_name":"target_vertex_count","name":"target_vertex_count","shape":7,"type":"INT","widget":{"name":"target_vertex_count"},"link":null},{"localized_name":"deterministic","name":"deterministic","shape":7,"type":"COMBO","widget":{"name":"deterministic"},"link":null},{"localized_name":"crease_angle","name":"crease_angle","shape":7,"type":"FLOAT","widget":{"name":"crease_angle"},"link":null},{"localized_name":"target_face_count","name":"target_face_count","shape":7,"type":"INT","widget":{"name":"target_face_count"},"link":null},{"localized_name":"preserve_sharp","name":"preserve_sharp","shape":7,"type":"COMBO","widget":{"name":"preserve_sharp"},"link":null},{"localized_name":"preserve_boundary","name":"preserve_boundary","shape":7,"type":"COMBO","widget":{"name":"preserve_boundary"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[15]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"f4d5713f5feef867c82be5a2d67e532e7a95933b","Node name for S&R":"GeomPackRemesh"},"widgets_values":["pymeshlab_isotropic",1,3,30,"false",5000,"true",0,5000,"false","true",""]},{"id":6,"type":"GeomPackPreviewMeshVTKBatch","pos":[198.34297321687484,-3.9126660804999145],"size":[648.2642445312499,772.8686878906249],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":15},{"localized_name":"mode","name":"mode","type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"index","name":"index","type":"INT","widget":{"name":"index"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"84b2d1816c08ec3cc7d3a4fffa90692669e17507","Node name for S&R":"GeomPackPreviewMeshVTKBatch","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["fields",0,""]}],"links":[[7,1,0,4,0,"TRIMESH"],[14,1,0,11,0,"TRIMESH"],[15,11,0,6,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7513148009015777,"offset":[515.1385904905114,382.1839371387389]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
+1 -1
View File
@@ -1 +1 @@
{"id":"58a80d52-612a-405e-b687-4696702fb5a6","revision":1,"last_node_id":23,"last_link_id":32,"nodes":[{"id":21,"type":"GeomPackPreviewMeshDual","pos":[-435.8209574638419,90.32379879585822],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":27},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":28},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual","cnr_id":"comfyui-geometrypack"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":22,"type":"GeomPackPreviewMeshVTK","pos":[393.34808550490783,-249.69329104789136],"size":[512,722],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","shape":7,"type":"TRIMESH","link":32},{"localized_name":"voxelgrid","name":"voxelgrid","shape":7,"type":"VOXELGRID","link":null},{"localized_name":"mode","name":"mode","type":"COMBO","widget":{"name":"mode"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"2e13f224560ec09663784033fcbe8565327e9726","Node name for S&R":"GeomPackPreviewMeshVTK","cnr_id":"comfyui-geometrypack"},"widgets_values":["fields",""]},{"id":1,"type":"GeomPackCreatePrimitive","pos":[-800,-200],"size":[300,150],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"shape","name":"shape","type":"COMBO","widget":{"name":"shape"},"link":null},{"localized_name":"size","name":"size","type":"FLOAT","widget":{"name":"size"},"link":null},{"localized_name":"subdivisions","name":"subdivisions","shape":7,"type":"INT","widget":{"name":"subdivisions"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[27,30]}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"8b8322e2f784d84097cd3427f097b55dc9a29d2a","Node name for S&R":"GeomPackCreatePrimitive","cnr_id":"comfyui-geometrypack"},"widgets_values":["cube",2,1]},{"id":2,"type":"GeomPackCreatePrimitive","pos":[-800,50],"size":[300,150],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"shape","name":"shape","type":"COMBO","widget":{"name":"shape"},"link":null},{"localized_name":"size","name":"size","type":"FLOAT","widget":{"name":"size"},"link":null},{"localized_name":"subdivisions","name":"subdivisions","shape":7,"type":"INT","widget":{"name":"subdivisions"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[28,31]}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"8b8322e2f784d84097cd3427f097b55dc9a29d2a","Node name for S&R":"GeomPackCreatePrimitive","cnr_id":"comfyui-geometrypack"},"widgets_values":["sphere",2.5,2]},{"id":23,"type":"GeomPackBooleanCGAL","pos":[-384.9918134931428,-190.68513609068106],"size":[270,78],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"mesh_a","name":"mesh_a","type":"TRIMESH","link":30},{"localized_name":"mesh_b","name":"mesh_b","type":"TRIMESH","link":31},{"localized_name":"operation","name":"operation","type":"COMBO","widget":{"name":"operation"},"link":null}],"outputs":[{"localized_name":"result_mesh","name":"result_mesh","type":"TRIMESH","links":[32]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"c5dfab62adf5e57a1800306b9c6d495f4dd52a43","Node name for S&R":"GeomPackBooleanCGAL"},"widgets_values":["union"]}],"links":[[27,1,0,21,0,"TRIMESH"],[28,2,0,21,1,"TRIMESH"],[30,1,0,23,0,"TRIMESH"],[31,2,0,23,1,"TRIMESH"],[32,23,0,22,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":1.0648000000000015,"offset":[1069.616918677214,587.525350215399]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id": "58a80d52-612a-405e-b687-4696702fb5a6", "revision": 1, "last_node_id": 23, "last_link_id": 32, "nodes": [{"id": 21, "type": "GeomPackPreviewMeshDual", "pos": [-435.8209574638419, 90.32379879585822], "size": [768, 834], "flags": {}, "order": 2, "mode": 0, "inputs": [{"localized_name": "mesh_1", "name": "mesh_1", "type": "TRIMESH", "link": 27}, {"localized_name": "mesh_2", "name": "mesh_2", "type": "TRIMESH", "link": 28}, {"localized_name": "layout", "name": "layout", "shape": 7, "type": "COMBO", "widget": {"name": "layout"}, "link": null}, {"localized_name": "mode", "name": "mode", "shape": 7, "type": "COMBO", "widget": {"name": "mode"}, "link": null}, {"localized_name": "opacity_1", "name": "opacity_1", "shape": 7, "type": "FLOAT", "widget": {"name": "opacity_1"}, "link": null}, {"localized_name": "opacity_2", "name": "opacity_2", "shape": 7, "type": "FLOAT", "widget": {"name": "opacity_2"}, "link": null}], "outputs": [], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "991c7a75886f50d567e5ed6d36aed06d0729a938", "Node name for S&R": "GeomPackPreviewMeshDual", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["side_by_side", "fields", 1, 1, true, "", ""]}, {"id": 22, "type": "GeomPackPreviewMeshVTK", "pos": [393.34808550490783, -249.69329104789136], "size": [512, 722], "flags": {}, "order": 4, "mode": 0, "inputs": [{"localized_name": "trimesh", "name": "trimesh", "shape": 7, "type": "TRIMESH", "link": 32}, {"localized_name": "voxelgrid", "name": "voxelgrid", "shape": 7, "type": "VOXELGRID", "link": null}, {"localized_name": "mode", "name": "mode", "type": "COMBO", "widget": {"name": "mode"}, "link": null}], "outputs": [], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "2e13f224560ec09663784033fcbe8565327e9726", "Node name for S&R": "GeomPackPreviewMeshVTK", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["fields", ""]}, {"id": 1, "type": "GeomPackCreatePrimitive", "pos": [-800, -200], "size": [300, 150], "flags": {}, "order": 0, "mode": 0, "inputs": [{"localized_name": "shape", "name": "shape", "type": "COMBO", "widget": {"name": "shape"}, "link": null}, {"localized_name": "size", "name": "size", "type": "FLOAT", "widget": {"name": "size"}, "link": null}, {"localized_name": "subdivisions", "name": "subdivisions", "shape": 7, "type": "INT", "widget": {"name": "subdivisions"}, "link": null}], "outputs": [{"localized_name": "mesh", "name": "mesh", "type": "TRIMESH", "links": [27, 30]}], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a", "Node name for S&R": "GeomPackCreatePrimitive", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["cube", 2, 1]}, {"id": 2, "type": "GeomPackCreatePrimitive", "pos": [-800, 50], "size": [300, 150], "flags": {}, "order": 1, "mode": 0, "inputs": [{"localized_name": "shape", "name": "shape", "type": "COMBO", "widget": {"name": "shape"}, "link": null}, {"localized_name": "size", "name": "size", "type": "FLOAT", "widget": {"name": "size"}, "link": null}, {"localized_name": "subdivisions", "name": "subdivisions", "shape": 7, "type": "INT", "widget": {"name": "subdivisions"}, "link": null}], "outputs": [{"localized_name": "mesh", "name": "mesh", "type": "TRIMESH", "links": [28, 31]}], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a", "Node name for S&R": "GeomPackCreatePrimitive", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["sphere", 2.5, 2]}, {"id": 23, "type": "GeomPackBooleanCGAL", "pos": [-384.9918134931428, -190.68513609068106], "size": [270, 78], "flags": {}, "order": 3, "mode": 0, "inputs": [{"localized_name": "mesh_a", "name": "mesh_a", "type": "TRIMESH", "link": 30}, {"localized_name": "mesh_b", "name": "mesh_b", "type": "TRIMESH", "link": 31}, {"localized_name": "operation", "name": "operation", "type": "COMBO", "widget": {"name": "operation"}, "link": null}], "outputs": [{"localized_name": "result_mesh", "name": "result_mesh", "type": "TRIMESH", "links": [32]}, {"localized_name": "info", "name": "info", "type": "STRING", "links": null}], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "c5dfab62adf5e57a1800306b9c6d495f4dd52a43", "Node name for S&R": "GeomPackBooleanCGAL"}, "widgets_values": ["union"]}], "links": [[27, 1, 0, 21, 0, "TRIMESH"], [28, 2, 0, 21, 1, "TRIMESH"], [30, 1, 0, 23, 0, "TRIMESH"], [31, 2, 0, 23, 1, "TRIMESH"], [32, 23, 0, 22, 0, "TRIMESH"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 1.0648000000000015, "offset": [1069.616918677214, 587.525350215399]}, "frontendVersion": "1.30.6", "workflowRendererVersion": "LG"}, "version": 0.4}
+1 -1
View File
@@ -1 +1 @@
{"id":"f1e2d3c4-5b6a-7890-abcd-ef1234567890","revision":0,"last_node_id":6,"last_link_id":10,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-502,-58],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[5,9]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/camelhead.off"]},{"id":4,"type":"GeomPackPreviewMeshDual","pos":[153.61197916666663,-96.7200520833334],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":5},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":8},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":6,"type":"GeomPackFillHoles","pos":[-171.29036458333348,47.93098958333326],"size":[270,126],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","link":9},{"localized_name":"method","name":"method","type":"COMBO","widget":{"name":"method"},"link":null},{"localized_name":"perimeter","name":"perimeter","shape":7,"type":"FLOAT","widget":{"name":"perimeter"},"link":null},{"localized_name":"maxholesize","name":"maxholesize","shape":7,"type":"INT","widget":{"name":"maxholesize"},"link":null}],"outputs":[{"localized_name":"filled_mesh","name":"filled_mesh","type":"TRIMESH","links":[8]},{"localized_name":"info","name":"info","type":"STRING","links":[]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackFillHoles"},"widgets_values":["igl_fan",0.03,1000]}],"links":[[5,1,0,4,0,"TRIMESH"],[8,6,0,4,1,"TRIMESH"],[9,1,0,6,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":1,"offset":[668.4192708333335,261.92838541666674]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id":"f1e2d3c4-5b6a-7890-abcd-ef1234567890","revision":0,"last_node_id":6,"last_link_id":10,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-502,-58],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[5,9]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/camelhead.off"]},{"id":4,"type":"GeomPackPreviewMeshDual","pos":[153.61197916666663,-96.7200520833334],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":5},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":8},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null},{"localized_name":"camera_state","name":"camera_state","shape":7,"type":"STRING","widget":{"name":"camera_state"},"link":null},{"localized_name":"selected_field","name":"selected_field","shape":7,"type":"STRING","widget":{"name":"selected_field"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,true,"{\"position\":[-0.6681526257034239,-1.8611185662971887,0.48246462543800994],\"focalPoint\":[0.000001996755599975586,-0.0636419951915741,-0.03211300075054169],\"viewUp\":[-0.8176470407253343,0.4174384049100435,0.39648265397021126]}","",""]},{"id":6,"type":"GeomPackFillHoles","pos":[-171.29036458333348,47.93098958333326],"size":[210,134],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","link":9},{"localized_name":"method","name":"method","type":"COMBO","widget":{"name":"method"},"link":null},{"localized_name":"perimeter","name":"perimeter","shape":7,"type":"FLOAT","widget":{"name":"perimeter"},"link":null},{"localized_name":"maxholesize","name":"maxholesize","shape":7,"type":"INT","widget":{"name":"maxholesize"},"link":null}],"outputs":[{"localized_name":"filled_mesh","name":"filled_mesh","type":"TRIMESH","links":[8]},{"localized_name":"info","name":"info","type":"STRING","links":[]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackFillHoles"},"widgets_values":["pymeshlab",0.03,1000,""]}],"links":[[5,1,0,4,0,"TRIMESH"],[8,6,0,4,1,"TRIMESH"],[9,1,0,6,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":1,"offset":[636.1302083333335,280.33854166666674]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
+1 -266
View File
@@ -1,266 +1 @@
{
"id": "f3e4d5c6-7b8a-9012-cdef-123456789012",
"revision": 0,
"last_node_id": 7,
"last_link_id": 12,
"nodes": [
{
"id": 4,
"type": "GeomPackPreviewMeshDual",
"pos": [
114.71875000000023,
226.32812500000006
],
"size": [
768,
834
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "mesh_1",
"type": "TRIMESH",
"link": 12
},
{
"name": "mesh_2",
"type": "TRIMESH",
"link": 11
}
],
"outputs": [],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "991c7a75886f50d567e5ed6d36aed06d0729a938",
"Node name for S&R": "GeomPackPreviewMeshDual"
},
"widgets_values": [
"side_by_side",
"fields",
1,
1,
""
]
},
{
"id": 1,
"type": "GeomPackLoadMesh",
"pos": [
-502,
-58
],
"size": [
270,
78
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "mesh",
"type": "TRIMESH",
"links": [
1,
9
]
},
{
"name": "texture",
"type": "IMAGE",
"links": null
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "0.1.1",
"Node name for S&R": "GeomPackLoadMesh"
},
"widgets_values": [
"3d/truck.obj"
]
},
{
"id": 6,
"type": "GeomPackComputeNormals",
"pos": [
-347.74999999999943,
187.20312500000009
],
"size": [
292.056640625,
58
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "trimesh",
"type": "TRIMESH",
"link": 9
}
],
"outputs": [
{
"name": "mesh_with_normals",
"type": "TRIMESH",
"links": [
12
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "991c7a75886f50d567e5ed6d36aed06d0729a938",
"Node name for S&R": "GeomPackComputeNormals"
},
"widgets_values": [
"true"
]
},
{
"id": 7,
"type": "GeomPackComputeNormals",
"pos": [
-360.8229166666663,
291.45312499999994
],
"size": [
292.056640625,
58
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "trimesh",
"type": "TRIMESH",
"link": 10
}
],
"outputs": [
{
"name": "mesh_with_normals",
"type": "TRIMESH",
"links": [
11
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "991c7a75886f50d567e5ed6d36aed06d0729a938",
"Node name for S&R": "GeomPackComputeNormals"
},
"widgets_values": [
"true"
]
},
{
"id": 2,
"type": "GeomPackFixNormals",
"pos": [
-175,
-63
],
"size": [
270,
78
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "trimesh",
"type": "TRIMESH",
"link": 1
}
],
"outputs": [
{
"name": "fixed_mesh",
"type": "TRIMESH",
"links": [
10
]
},
{
"name": "info",
"type": "STRING",
"links": [
8
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "0.1.1",
"Node name for S&R": "GeomPackFixNormals"
},
"widgets_values": [
"igl_bfs"
]
}
],
"links": [
[
1,
1,
0,
2,
0,
"TRIMESH"
],
[
9,
1,
0,
6,
0,
"TRIMESH"
],
[
10,
2,
0,
7,
0,
"TRIMESH"
],
[
11,
7,
0,
4,
1,
"TRIMESH"
],
[
12,
6,
0,
4,
0,
"TRIMESH"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.75,
"offset": [
934.9999999999997,
146.08333333333334
]
},
"frontendVersion": "1.30.6"
},
"version": 0.4
}
{"id":"f3e4d5c6-7b8a-9012-cdef-123456789012","revision":0,"last_node_id":8,"last_link_id":14,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-502,-58],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[1,9]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/truck.obj"]},{"id":2,"type":"GeomPackFixNormals","pos":[-175,-63],"size":[270,110],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":1},{"localized_name":"method","name":"method","type":"COMBO","widget":{"name":"method"},"link":null}],"outputs":[{"localized_name":"fixed_mesh","name":"fixed_mesh","type":"TRIMESH","links":[10]},{"localized_name":"info","name":"info","type":"STRING","links":[8]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"0.1.1","Node name for S&R":"GeomPackFixNormals"},"widgets_values":["igl_bfs",""]},{"id":6,"type":"GeomPackComputeNormals","pos":[-347.74999999999943,187.20312500000009],"size":[292.056640625,58],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":9},{"localized_name":"smooth_vertex_normals","name":"smooth_vertex_normals","type":"COMBO","widget":{"name":"smooth_vertex_normals"},"link":null}],"outputs":[{"localized_name":"mesh_with_normals","name":"mesh_with_normals","type":"TRIMESH","links":[13]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackComputeNormals"},"widgets_values":["true"]},{"id":7,"type":"GeomPackComputeNormals","pos":[-360.8229166666663,291.45312499999994],"size":[292.056640625,58],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":10},{"localized_name":"smooth_vertex_normals","name":"smooth_vertex_normals","type":"COMBO","widget":{"name":"smooth_vertex_normals"},"link":null}],"outputs":[{"localized_name":"mesh_with_normals","name":"mesh_with_normals","type":"TRIMESH","links":[14]}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackComputeNormals"},"widgets_values":["true"]},{"id":8,"type":"GeomPackPreviewMeshDual","pos":[64.0885416666671,143.14583333333331],"size":[768,826],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":13},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":14},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null},{"localized_name":"camera_state","name":"camera_state","shape":7,"type":"STRING","widget":{"name":"camera_state"},"link":null},{"localized_name":"selected_field","name":"selected_field","shape":7,"type":"STRING","widget":{"name":"selected_field"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"2bc968b6282e2754cef4b5507346e0a9ebdbf32a","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,false,"{\"position\":[2.1230389037522457,2.254177889080077,-2.3107558874613097],\"focalPoint\":[0,0,0],\"viewUp\":[-0.37864046226114645,0.8119761508244989,0.4442140596952062]}","normal_x",""]}],"links":[[1,1,0,2,0,"TRIMESH"],[9,1,0,6,0,"TRIMESH"],[10,2,0,7,0,"TRIMESH"],[13,6,0,8,0,"TRIMESH"],[14,7,0,8,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.75,"offset":[935.9947916666663,198.18750000000003]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"id":"r6e7d8c9-0b1a-2345-f678-456789012345","revision":0,"last_node_id":4,"last_link_id":6,"nodes":[{"id":3,"type":"GeomPackPreviewMeshDual","pos":[120.60416666666666,144.38541666666669],"size":[802,848],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":6},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":5},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"0.1.1","Node name for S&R":"GeomPackPreviewMeshDual","cnr_id":"comfyui-geometrypack"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":1,"type":"GeomPackLoadMesh","pos":[-502,-58],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[4,6]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"0.1.1","Node name for S&R":"GeomPackLoadMesh","cnr_id":"comfyui-geometrypack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":4,"type":"RefineMesh","pos":[-315.1250000000004,148.578125],"size":[286.501953125,198],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":4},{"localized_name":"operation","name":"operation","type":"COMBO","widget":{"name":"operation"},"link":null},{"localized_name":"target_face_count","name":"target_face_count","shape":7,"type":"INT","widget":{"name":"target_face_count"},"link":null},{"localized_name":"decimation_method","name":"decimation_method","shape":7,"type":"COMBO","widget":{"name":"decimation_method"},"link":null},{"localized_name":"subdivision_iterations","name":"subdivision_iterations","shape":7,"type":"INT","widget":{"name":"subdivision_iterations"},"link":null},{"localized_name":"smoothing_iterations","name":"smoothing_iterations","shape":7,"type":"INT","widget":{"name":"smoothing_iterations"},"link":null},{"localized_name":"lambda_factor","name":"lambda_factor","shape":7,"type":"FLOAT","widget":{"name":"lambda_factor"},"link":null}],"outputs":[{"localized_name":"refined_mesh","name":"refined_mesh","type":"TRIMESH","links":[5]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"c5dfab62adf5e57a1800306b9c6d495f4dd52a43","Node name for S&R":"RefineMesh"},"widgets_values":["decimation",5000,"trimesh",1,5,0.5]}],"links":[[4,1,0,4,0,"TRIMESH"],[5,4,0,3,1,"TRIMESH"],[6,1,0,3,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.75,"offset":[865.7916666666675,261.421875]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id": "r6e7d8c9-0b1a-2345-f678-456789012345", "revision": 0, "last_node_id": 4, "last_link_id": 6, "nodes": [{"id": 3, "type": "GeomPackPreviewMeshDual", "pos": [120.60416666666666, 144.38541666666669], "size": [802, 848], "flags": {}, "order": 2, "mode": 0, "inputs": [{"localized_name": "mesh_1", "name": "mesh_1", "type": "TRIMESH", "link": 6}, {"localized_name": "mesh_2", "name": "mesh_2", "type": "TRIMESH", "link": 5}, {"localized_name": "layout", "name": "layout", "shape": 7, "type": "COMBO", "widget": {"name": "layout"}, "link": null}, {"localized_name": "mode", "name": "mode", "shape": 7, "type": "COMBO", "widget": {"name": "mode"}, "link": null}, {"localized_name": "opacity_1", "name": "opacity_1", "shape": 7, "type": "FLOAT", "widget": {"name": "opacity_1"}, "link": null}, {"localized_name": "opacity_2", "name": "opacity_2", "shape": 7, "type": "FLOAT", "widget": {"name": "opacity_2"}, "link": null}], "outputs": [], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "0.1.1", "Node name for S&R": "GeomPackPreviewMeshDual", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["side_by_side", "fields", 1, 1, true, "", ""]}, {"id": 1, "type": "GeomPackLoadMesh", "pos": [-502, -58], "size": [270, 78], "flags": {}, "order": 0, "mode": 0, "inputs": [{"localized_name": "file_path", "name": "file_path", "type": "COMBO", "widget": {"name": "file_path"}, "link": null}], "outputs": [{"localized_name": "mesh", "name": "mesh", "type": "TRIMESH", "links": [4, 6]}, {"localized_name": "texture", "name": "texture", "type": "IMAGE", "links": null}], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "0.1.1", "Node name for S&R": "GeomPackLoadMesh", "cnr_id": "comfyui-geometrypack"}, "widgets_values": ["3d/Stanford_Bunny.stl"]}, {"id": 4, "type": "RefineMesh", "pos": [-315.1250000000004, 148.578125], "size": [286.501953125, 198], "flags": {}, "order": 1, "mode": 0, "inputs": [{"localized_name": "trimesh", "name": "trimesh", "type": "TRIMESH", "link": 4}, {"localized_name": "operation", "name": "operation", "type": "COMBO", "widget": {"name": "operation"}, "link": null}, {"localized_name": "target_face_count", "name": "target_face_count", "shape": 7, "type": "INT", "widget": {"name": "target_face_count"}, "link": null}, {"localized_name": "decimation_method", "name": "decimation_method", "shape": 7, "type": "COMBO", "widget": {"name": "decimation_method"}, "link": null}, {"localized_name": "subdivision_iterations", "name": "subdivision_iterations", "shape": 7, "type": "INT", "widget": {"name": "subdivision_iterations"}, "link": null}, {"localized_name": "smoothing_iterations", "name": "smoothing_iterations", "shape": 7, "type": "INT", "widget": {"name": "smoothing_iterations"}, "link": null}, {"localized_name": "lambda_factor", "name": "lambda_factor", "shape": 7, "type": "FLOAT", "widget": {"name": "lambda_factor"}, "link": null}], "outputs": [{"localized_name": "refined_mesh", "name": "refined_mesh", "type": "TRIMESH", "links": [5]}, {"localized_name": "info", "name": "info", "type": "STRING", "links": null}], "properties": {"aux_id": "PozzettiAndrea/ComfyUI-GeometryPack", "ver": "c5dfab62adf5e57a1800306b9c6d495f4dd52a43", "Node name for S&R": "RefineMesh"}, "widgets_values": ["decimation", 5000, "trimesh", 1, 5, 0.5]}], "links": [[4, 1, 0, 4, 0, "TRIMESH"], [5, 4, 0, 3, 1, "TRIMESH"], [6, 1, 0, 3, 0, "TRIMESH"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 0.75, "offset": [865.7916666666675, 261.421875]}, "frontendVersion": "1.30.6", "workflowRendererVersion": "LG"}, "version": 0.4}
+1 -1
View File
@@ -1 +1 @@
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":25,"last_link_id":29,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-502.81561847832234,-58.160239777583065],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[24,29]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":25,"type":"GeomPackPreviewMeshDual","pos":[-344.64489975927364,265.1754548878005],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":29},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":28},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":23,"type":"GeomPackRemesh","pos":[-150.60754064166025,-111.70359969148042],"size":[214.77734375,400],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":24},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"feature_angle","name":"feature_angle","shape":7,"type":"FLOAT","widget":{"name":"feature_angle"},"link":null},{"localized_name":"adaptive","name":"adaptive","shape":7,"type":"COMBO","widget":{"name":"adaptive"},"link":null},{"localized_name":"target_vertex_count","name":"target_vertex_count","shape":7,"type":"INT","widget":{"name":"target_vertex_count"},"link":null},{"localized_name":"deterministic","name":"deterministic","shape":7,"type":"COMBO","widget":{"name":"deterministic"},"link":null},{"localized_name":"crease_angle","name":"crease_angle","shape":7,"type":"FLOAT","widget":{"name":"crease_angle"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[28]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"01a1fb3f161fe989dc1486b6064a395302d93af3","Node name for S&R":"GeomPackRemesh"},"widgets_values":["instant_meshes",10,3,30,"false",5000,"true",0,""]}],"links":[[24,1,0,23,0,"TRIMESH"],[28,23,0,25,1,"TRIMESH"],[29,1,0,25,0,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.751314800901578,"offset":[1235.385454446773,318.5928263621994]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":27,"last_link_id":35,"nodes":[{"id":25,"type":"GeomPackPreviewMeshDual","pos":[-344.64489975927364,265.1754548878005],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":29},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":35},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,true,""]},{"id":1,"type":"GeomPackLoadMesh","pos":[-502.81561847832234,-58.160239777583065],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[29,34]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":27,"type":"GeomPackRemesh","pos":[-674.8316849155233,165.8287830128005],"size":[214.34375,182],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":34},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"feature_angle","name":"feature_angle","shape":7,"type":"FLOAT","widget":{"name":"feature_angle"},"link":null},{"localized_name":"adaptive","name":"adaptive","shape":7,"type":"COMBO","widget":{"name":"adaptive"},"link":null},{"localized_name":"target_vertex_count","name":"target_vertex_count","shape":7,"type":"INT","widget":{"name":"target_vertex_count"},"link":null},{"localized_name":"deterministic","name":"deterministic","shape":7,"type":"COMBO","widget":{"name":"deterministic"},"link":null},{"localized_name":"crease_angle","name":"crease_angle","shape":7,"type":"FLOAT","widget":{"name":"crease_angle"},"link":null},{"localized_name":"target_face_count","name":"target_face_count","shape":7,"type":"INT","widget":{"name":"target_face_count"},"link":null},{"localized_name":"preserve_sharp","name":"preserve_sharp","shape":7,"type":"COMBO","widget":{"name":"preserve_sharp"},"link":null},{"localized_name":"preserve_boundary","name":"preserve_boundary","shape":7,"type":"COMBO","widget":{"name":"preserve_boundary"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[35]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"f4d5713f5feef867c82be5a2d67e532e7a95933b","Node name for S&R":"GeomPackRemesh"},"widgets_values":["quadriflow",1,3,30,"false",5000,"true",0,5000,"false","true",""]}],"links":[[29,1,0,25,0,"TRIMESH"],[34,1,0,27,0,"TRIMESH"],[35,27,0,25,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.751314800901578,"offset":[1042.894778665523,-10.642501762800515]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
+1 -1
View File
@@ -1 +1 @@
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":26,"last_link_id":32,"nodes":[{"id":25,"type":"GeomPackPreviewMeshDual","pos":[-288.0410052280236,142.2919197315505],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":31},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":32},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":1,"type":"GeomPackLoadMesh","pos":[-502.81561847832234,-58.160239777583065],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[30,32]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":26,"type":"GeomPackRemeshCGAL","pos":[-173.53963526716967,-268.5574315566234],"size":[274.009765625,126],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":30},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"protect_boundaries","name":"protect_boundaries","shape":7,"type":"COMBO","widget":{"name":"protect_boundaries"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[31]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"d0a698d6d5d375dc1e50b1146d4f5fbe9e819d16","Node name for S&R":"GeomPackRemeshCGAL","aux_id":"PozzettiAndrea/ComfyUI-GeometryPack"},"widgets_values":[1,3,"true"]}],"links":[[30,1,0,26,0,"TRIMESH"],[31,26,0,25,0,"TRIMESH"],[32,1,0,25,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6830134553650705,"offset":[1287.828398939045,577.7913651503734]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":27,"last_link_id":34,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-502.81561847832234,-58.160239777583065],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[30,33]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","cnr_id":"comfyui-geometrypack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":26,"type":"GeomPackRemeshCGAL","pos":[-469.8082770640447,136.13467820900172],"size":[274.009765625,158],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":30},{"localized_name":"target_edge_length","name":"target_edge_length","shape":7,"type":"FLOAT","widget":{"name":"target_edge_length"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"protect_boundaries","name":"protect_boundaries","shape":7,"type":"COMBO","widget":{"name":"protect_boundaries"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[34]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"d0a698d6d5d375dc1e50b1146d4f5fbe9e819d16","Node name for S&R":"GeomPackRemeshCGAL","cnr_id":"comfyui-geometrypack"},"widgets_values":[1,3,"true",""]},{"id":27,"type":"GeomPackPreviewMeshDual","pos":[-115.79919151716959,-52.67131124412321],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":33},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":34},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null},{"localized_name":"camera_state","name":"camera_state","shape":7,"type":"STRING","widget":{"name":"camera_state"},"link":null},{"localized_name":"selected_field","name":"selected_field","shape":7,"type":"STRING","widget":{"name":"selected_field"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"abe9ed9726622d0f29e3936feaf6c1aa446914a3","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,true,"{\"position\":[-131.66068270640417,-232.56748089092218,189.20482021602103],\"focalPoint\":[30.322647094726562,1.8909549713134766,59.22096252441406],\"viewUp\":[0.2535224962298691,0.329135569638136,0.9096131709162725]}","",""]}],"links":[[30,1,0,26,0,"TRIMESH"],[33,1,0,27,0,"TRIMESH"],[34,26,0,27,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6830134553650705,"offset":[1094.6015137827944,690.2125124159984]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
+1 -1
View File
@@ -1 +1 @@
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":28,"last_link_id":37,"nodes":[{"id":25,"type":"GeomPackPreviewMeshDual","pos":[-288.0410052280236,276.0522205128005],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":35},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":37},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"991c7a75886f50d567e5ed6d36aed06d0729a938","Node name for S&R":"GeomPackPreviewMeshDual","cnr_id":"comfyui-geometrypack"},"widgets_values":["side_by_side","fields",1,1,""]},{"id":1,"type":"GeomPackLoadMesh","pos":[-553.8798563116762,-69.44822756818182],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[35,36]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","cnr_id":"comfyui-geometrypack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":28,"type":"GeomPackRemeshBlender","pos":[-54.034114326584614,-70.78213153854568],"size":[210,102],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":36},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"voxel_size","name":"voxel_size","shape":7,"type":"FLOAT","widget":{"name":"voxel_size"},"link":null},{"localized_name":"target_face_count","name":"target_face_count","shape":7,"type":"INT","widget":{"name":"target_face_count"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[37]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"ecb6110ecd36476ca03b7ed8bdb80d47e60ac388","Node name for S&R":"GeomPackRemeshBlender"},"widgets_values":["blender_quadriflow",1,500000]}],"links":[[35,1,0,25,0,"TRIMESH"],[36,1,0,28,0,"TRIMESH"],[37,28,0,25,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7935011461883303,"offset":[982.6914055475675,277.94845957682213]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
{"id":"fc31dc6e-fd82-4f42-9d3a-57283ccfadba","revision":0,"last_node_id":32,"last_link_id":48,"nodes":[{"id":1,"type":"GeomPackLoadMesh","pos":[-553.8798563116762,-69.44822756818182],"size":[270,78],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"file_path","name":"file_path","type":"COMBO","widget":{"name":"file_path"},"link":null}],"outputs":[{"localized_name":"mesh","name":"mesh","type":"TRIMESH","links":[43,47]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"253a956368261760da54dc96750c2ab0224e2b1f","Node name for S&R":"GeomPackLoadMesh","cnr_id":"comfyui-geometrypack"},"widgets_values":["3d/Stanford_Bunny.stl"]},{"id":32,"type":"GeomPackPreviewMeshDual","pos":[-210.04648980414163,40.2496015193593],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":47},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":48},{"localized_name":"layout","name":"layout","shape":7,"type":"COMBO","widget":{"name":"layout"},"link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null},{"localized_name":"opacity_1","name":"opacity_1","shape":7,"type":"FLOAT","widget":{"name":"opacity_1"},"link":null},{"localized_name":"opacity_2","name":"opacity_2","shape":7,"type":"FLOAT","widget":{"name":"opacity_2"},"link":null},{"localized_name":"show_edges","name":"show_edges","shape":7,"type":"BOOLEAN","widget":{"name":"show_edges"},"link":null},{"localized_name":"camera_state","name":"camera_state","shape":7,"type":"STRING","widget":{"name":"camera_state"},"link":null},{"localized_name":"selected_field","name":"selected_field","shape":7,"type":"STRING","widget":{"name":"selected_field"},"link":null}],"outputs":[],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"abe9ed9726622d0f29e3936feaf6c1aa446914a3","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,true,"{\"position\":[-104.03222092116789,-54.74525049655604,122.61947175655823],\"focalPoint\":[30.321775436401367,1.9068737030029297,59.235236167907715],\"viewUp\":[0.18685523349867636,0.5017895827965837,0.8445663599214603]}","",""]},{"id":31,"type":"GeomPackRemeshBlender","pos":[-486.88728378090264,115.45362409343684],"size":[210,182],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":43},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"voxel_size","name":"voxel_size","shape":7,"type":"FLOAT","widget":{"name":"voxel_size"},"link":null},{"localized_name":"octree_depth","name":"octree_depth","shape":7,"type":"INT","widget":{"name":"octree_depth"},"link":null},{"localized_name":"scale","name":"scale","shape":7,"type":"FLOAT","widget":{"name":"scale"},"link":null},{"localized_name":"sharpness","name":"sharpness","shape":7,"type":"FLOAT","widget":{"name":"sharpness"},"link":null}],"outputs":[{"localized_name":"remeshed_mesh","name":"remeshed_mesh","type":"TRIMESH","links":[48]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"aux_id":"PozzettiAndrea/ComfyUI-GeometryPack","ver":"a57da232130b20d93f36248ed810254035c6226c","Node name for S&R":"GeomPackRemeshBlender","cnr_id":"comfyui-geometrypack"},"widgets_values":["blender_sharp",1,7,0.9,1,""]}],"links":[[43,1,0,31,0,"TRIMESH"],[47,1,0,32,0,"TRIMESH"],[48,31,0,32,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7742202296679138,"offset":[905.6203370297437,319.52771290121194]},"frontendVersion":"1.30.6","workflowRendererVersion":"LG"},"version":0.4}
+1 -149
View File
@@ -1,149 +1 @@
{
"id": "99d7a206-3afe-4ab6-ad84-842258739192",
"revision": 0,
"last_node_id": 7,
"last_link_id": 11,
"nodes": [
{
"id": 2,
"type": "GeomPackCreatePrimitive",
"pos": [
-385.07737412512756,
169.36276444668482
],
"size": [
300,
150
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "mesh",
"type": "TRIMESH",
"links": [
11
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a",
"Node name for S&R": "GeomPackCreatePrimitive"
},
"widgets_values": [
"sphere",
2.5,
2
]
},
{
"id": 1,
"type": "GeomPackCreatePrimitive",
"pos": [
-406.7715890011608,
-54.81078927232348
],
"size": [
300,
150
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "mesh",
"type": "TRIMESH",
"links": [
10
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a",
"Node name for S&R": "GeomPackCreatePrimitive"
},
"widgets_values": [
"cube",
2,
1
]
},
{
"id": 7,
"type": "GeomPackPreviewMeshDual",
"pos": [
290.82090195958176,
-94.5593042516624
],
"size": [
768,
834
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "mesh_1",
"type": "TRIMESH",
"link": 10
},
{
"name": "mesh_2",
"type": "TRIMESH",
"link": 11
}
],
"outputs": [],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "a22feb725fe9afaf6cdcfa75002a514292fcec9a",
"Node name for S&R": "GeomPackPreviewMeshDual"
},
"widgets_values": [
"side_by_side",
"fields",
1,
1,
""
]
}
],
"links": [
[
10,
1,
0,
7,
0,
"TRIMESH"
],
[
11,
2,
0,
7,
1,
"TRIMESH"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.9680000000000015,
"offset": [
616.5832173585986,
348.8529509458769
]
},
"frontendVersion": "1.30.6"
},
"version": 0.4
}
{"id": "99d7a206-3afe-4ab6-ad84-842258739192", "revision": 0, "last_node_id": 7, "last_link_id": 11, "nodes": [{"id": 2, "type": "GeomPackCreatePrimitive", "pos": [-385.07737412512756, 169.36276444668482], "size": [300, 150], "flags": {}, "order": 0, "mode": 0, "inputs": [], "outputs": [{"name": "mesh", "type": "TRIMESH", "links": [11]}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a", "Node name for S&R": "GeomPackCreatePrimitive"}, "widgets_values": ["sphere", 2.5, 2]}, {"id": 1, "type": "GeomPackCreatePrimitive", "pos": [-406.7715890011608, -54.81078927232348], "size": [300, 150], "flags": {}, "order": 1, "mode": 0, "inputs": [], "outputs": [{"name": "mesh", "type": "TRIMESH", "links": [10]}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "8b8322e2f784d84097cd3427f097b55dc9a29d2a", "Node name for S&R": "GeomPackCreatePrimitive"}, "widgets_values": ["cube", 2, 1]}, {"id": 7, "type": "GeomPackPreviewMeshDual", "pos": [290.82090195958176, -94.5593042516624], "size": [768, 834], "flags": {}, "order": 2, "mode": 0, "inputs": [{"name": "mesh_1", "type": "TRIMESH", "link": 10}, {"name": "mesh_2", "type": "TRIMESH", "link": 11}], "outputs": [], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "a22feb725fe9afaf6cdcfa75002a514292fcec9a", "Node name for S&R": "GeomPackPreviewMeshDual"}, "widgets_values": ["side_by_side", "fields", 1, 1, true, "", ""]}], "links": [[10, 1, 0, 7, 0, "TRIMESH"], [11, 2, 0, 7, 1, "TRIMESH"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 0.9680000000000015, "offset": [616.5832173585986, 348.8529509458769]}, "frontendVersion": "1.30.6"}, "version": 0.4}
+1 -226
View File
@@ -1,226 +1 @@
{
"id": "58a80d52-612a-405e-b687-4696702fb5a6",
"revision": 1,
"last_node_id": 28,
"last_link_id": 39,
"nodes": [
{
"id": 21,
"type": "GeomPackMeshToPointCloud",
"pos": [
-250.96144566438386,
-55.75910409670366
],
"size": [
270,
106
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "trimesh",
"type": "TRIMESH",
"link": 26
}
],
"outputs": [
{
"name": "point_cloud",
"type": "TRIMESH",
"links": [
27
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d",
"Node name for S&R": "GeomPackMeshToPointCloud"
},
"widgets_values": [
"surface_sampling",
10000,
"uniform",
"true"
]
},
{
"id": 22,
"type": "GeomPackReconstructSurface",
"pos": [
83.7654396661942,
-50.29923193761277
],
"size": [
270,
222
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "points",
"type": "TRIMESH",
"link": 27
}
],
"outputs": [
{
"name": "reconstructed_mesh",
"type": "TRIMESH",
"links": [
39
]
},
{
"name": "info",
"type": "STRING",
"links": null
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d",
"Node name for S&R": "GeomPackReconstructSurface"
},
"widgets_values": [
"poisson",
4,
1.0,
0,
0,
"true",
0.2
]
},
{
"id": 20,
"type": "GeomPackLoadMesh",
"pos": [
-582.83935113959,
-50.27501964422433
],
"size": [
270,
78
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "mesh",
"type": "TRIMESH",
"links": [
26,
38
]
},
{
"name": "texture",
"type": "IMAGE",
"links": null
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d",
"Node name for S&R": "GeomPackLoadMesh"
},
"widgets_values": [
"3d/Stanford_Bunny.stl"
]
},
{
"id": 28,
"type": "GeomPackPreviewMeshDual",
"pos": [
-196.6668574739802,
247.0682656414106
],
"size": [
768,
826
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "mesh_1",
"type": "TRIMESH",
"link": 38
},
{
"name": "mesh_2",
"type": "TRIMESH",
"link": 39
}
],
"outputs": [],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "991c7a75886f50d567e5ed6d36aed06d0729a938",
"Node name for S&R": "GeomPackPreviewMeshDual"
},
"widgets_values": [
"side_by_side",
"fields",
1,
1,
""
]
}
],
"links": [
[
26,
20,
0,
21,
0,
"TRIMESH"
],
[
27,
21,
0,
22,
0,
"TRIMESH"
],
[
38,
20,
0,
28,
0,
"TRIMESH"
],
[
39,
22,
0,
28,
1,
"TRIMESH"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.8000000000000014,
"offset": [
1161.036974661478,
152.78036717108867
]
},
"frontendVersion": "1.30.6"
},
"version": 0.4
}
{"id": "58a80d52-612a-405e-b687-4696702fb5a6", "revision": 1, "last_node_id": 28, "last_link_id": 39, "nodes": [{"id": 21, "type": "GeomPackMeshToPointCloud", "pos": [-250.96144566438386, -55.75910409670366], "size": [270, 106], "flags": {}, "order": 1, "mode": 0, "inputs": [{"name": "trimesh", "type": "TRIMESH", "link": 26}], "outputs": [{"name": "point_cloud", "type": "TRIMESH", "links": [27]}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d", "Node name for S&R": "GeomPackMeshToPointCloud"}, "widgets_values": ["surface_sampling", 10000, "uniform", "true"]}, {"id": 22, "type": "GeomPackReconstructSurface", "pos": [83.7654396661942, -50.29923193761277], "size": [270, 222], "flags": {}, "order": 2, "mode": 0, "inputs": [{"name": "points", "type": "TRIMESH", "link": 27}], "outputs": [{"name": "reconstructed_mesh", "type": "TRIMESH", "links": [39]}, {"name": "info", "type": "STRING", "links": null}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d", "Node name for S&R": "GeomPackReconstructSurface"}, "widgets_values": ["poisson", 4, 1.0, 0, 0, "true", 0.2]}, {"id": 20, "type": "GeomPackLoadMesh", "pos": [-582.83935113959, -50.27501964422433], "size": [270, 78], "flags": {}, "order": 0, "mode": 0, "inputs": [], "outputs": [{"name": "mesh", "type": "TRIMESH", "links": [26, 38]}, {"name": "texture", "type": "IMAGE", "links": null}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "d616ab2f28493cf34f723ed59ea6747b61519c9d", "Node name for S&R": "GeomPackLoadMesh"}, "widgets_values": ["3d/Stanford_Bunny.stl"]}, {"id": 28, "type": "GeomPackPreviewMeshDual", "pos": [-196.6668574739802, 247.0682656414106], "size": [768, 826], "flags": {}, "order": 3, "mode": 0, "inputs": [{"name": "mesh_1", "type": "TRIMESH", "link": 38}, {"name": "mesh_2", "type": "TRIMESH", "link": 39}], "outputs": [], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "991c7a75886f50d567e5ed6d36aed06d0729a938", "Node name for S&R": "GeomPackPreviewMeshDual"}, "widgets_values": ["side_by_side", "fields", 1, 1, true, "", ""]}], "links": [[26, 20, 0, 21, 0, "TRIMESH"], [27, 21, 0, 22, 0, "TRIMESH"], [38, 20, 0, 28, 0, "TRIMESH"], [39, 22, 0, 28, 1, "TRIMESH"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 0.8000000000000014, "offset": [1161.036974661478, 152.78036717108867]}, "frontendVersion": "1.30.6"}, "version": 0.4}
+1 -170
View File
@@ -1,170 +1 @@
{
"id": "c3d4e5f6-7890-12ab-cdef-345678901cde",
"revision": 0,
"last_node_id": 6,
"last_link_id": 10,
"nodes": [
{
"id": 5,
"type": "GeomPackCreatePrimitive",
"pos": [
-802.9354063816817,
5.4249805979248436
],
"size": [
270,
106
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "mesh",
"type": "TRIMESH",
"links": [
5,
9
]
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "84b2d1816c08ec3cc7d3a4fffa90692669e17507",
"Node name for S&R": "GeomPackCreatePrimitive"
},
"widgets_values": [
"cube",
1,
2
]
},
{
"id": 6,
"type": "GeomPackPreviewMeshDual",
"pos": [
94.65433943293444,
-69.57587262019403
],
"size": [
768,
834
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "mesh_1",
"type": "TRIMESH",
"link": 9
},
{
"name": "mesh_2",
"type": "TRIMESH",
"link": 10
}
],
"outputs": [],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "84b2d1816c08ec3cc7d3a4fffa90692669e17507",
"Node name for S&R": "GeomPackPreviewMeshDual"
},
"widgets_values": [
"overlay",
"fields",
1,
1,
""
]
},
{
"id": 2,
"type": "GeomPackTransformMesh",
"pos": [
-400,
0
],
"size": [
320,
150
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "trimesh",
"type": "TRIMESH",
"link": 5
}
],
"outputs": [
{
"name": "transformed_mesh",
"type": "TRIMESH",
"links": [
10
]
},
{
"name": "info",
"type": "STRING",
"links": []
}
],
"properties": {
"cnr_id": "comfyui-geometrypack",
"ver": "0.1.1",
"Node name for S&R": "GeomPackTransformMesh"
},
"widgets_values": [
"translate",
0.5,
0.5,
2
]
}
],
"links": [
[
5,
5,
0,
2,
0,
"TRIMESH"
],
[
9,
5,
0,
6,
0,
"TRIMESH"
],
[
10,
2,
0,
6,
1,
"TRIMESH"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.8230486452640794,
"offset": [
952.132815408061,
279.4146957873131
]
},
"frontendVersion": "1.30.6"
},
"version": 0.4
}
{"id": "c3d4e5f6-7890-12ab-cdef-345678901cde", "revision": 0, "last_node_id": 6, "last_link_id": 10, "nodes": [{"id": 5, "type": "GeomPackCreatePrimitive", "pos": [-802.9354063816817, 5.4249805979248436], "size": [270, 106], "flags": {}, "order": 0, "mode": 0, "inputs": [], "outputs": [{"name": "mesh", "type": "TRIMESH", "links": [5, 9]}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "84b2d1816c08ec3cc7d3a4fffa90692669e17507", "Node name for S&R": "GeomPackCreatePrimitive"}, "widgets_values": ["cube", 1, 2]}, {"id": 6, "type": "GeomPackPreviewMeshDual", "pos": [94.65433943293444, -69.57587262019403], "size": [768, 834], "flags": {}, "order": 2, "mode": 0, "inputs": [{"name": "mesh_1", "type": "TRIMESH", "link": 9}, {"name": "mesh_2", "type": "TRIMESH", "link": 10}], "outputs": [], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "84b2d1816c08ec3cc7d3a4fffa90692669e17507", "Node name for S&R": "GeomPackPreviewMeshDual"}, "widgets_values": ["overlay", "fields", 1, 1, true, "", ""]}, {"id": 2, "type": "GeomPackTransformMesh", "pos": [-400, 0], "size": [320, 150], "flags": {}, "order": 1, "mode": 0, "inputs": [{"name": "trimesh", "type": "TRIMESH", "link": 5}], "outputs": [{"name": "transformed_mesh", "type": "TRIMESH", "links": [10]}, {"name": "info", "type": "STRING", "links": []}], "properties": {"cnr_id": "comfyui-geometrypack", "ver": "0.1.1", "Node name for S&R": "GeomPackTransformMesh"}, "widgets_values": ["translate", 0.5, 0.5, 2]}], "links": [[5, 5, 0, 2, 0, "TRIMESH"], [9, 5, 0, 6, 0, "TRIMESH"], [10, 2, 0, 6, 1, "TRIMESH"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 0.8230486452640794, "offset": [952.132815408061, 279.4146957873131]}, "frontendVersion": "1.30.6"}, "version": 0.4}