@@ -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
|
||||
@@ -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
@@ -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']
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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']
|
||||
@@ -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",
|
||||
}
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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 @@
|
||||
{"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 @@
|
||||
{"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 @@
|
||||
{"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
@@ -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 @@
|
||||
{"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 @@
|
||||
{"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 @@
|
||||
{"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 @@
|
||||
{"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 +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 +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
@@ -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}
|
||||
Reference in New Issue
Block a user