added some workflows for automated testing
This commit is contained in:
Executable
+26322
File diff suppressed because it is too large
Load Diff
Executable
+35108
File diff suppressed because it is too large
Load Diff
Executable
+19422
File diff suppressed because it is too large
Load Diff
Executable
+25912
File diff suppressed because it is too large
Load Diff
Executable
+19422
File diff suppressed because it is too large
Load Diff
Executable
+25912
File diff suppressed because it is too large
Load Diff
Executable
+72672
File diff suppressed because it is too large
Load Diff
Executable
BIN
Binary file not shown.
Executable
+111089
File diff suppressed because it is too large
Load Diff
+15576
File diff suppressed because it is too large
Load Diff
+15576
File diff suppressed because it is too large
Load Diff
@@ -59,18 +59,20 @@ class LoadMesh:
|
||||
|
||||
@classmethod
|
||||
def get_mesh_files(cls):
|
||||
"""Get list of available mesh files in input/3d and input folders."""
|
||||
"""Get list of available mesh files in input/3d (recursively) and input folders."""
|
||||
mesh_files = []
|
||||
|
||||
if COMFYUI_INPUT_FOLDER is not None:
|
||||
# Scan input/3d first
|
||||
# Scan input/3d recursively
|
||||
input_3d = os.path.join(COMFYUI_INPUT_FOLDER, "3d")
|
||||
if os.path.exists(input_3d):
|
||||
for file in os.listdir(input_3d):
|
||||
if any(file.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS):
|
||||
mesh_files.append(f"3d/{file}")
|
||||
for root, _dirs, files in os.walk(input_3d):
|
||||
for file in files:
|
||||
if any(file.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS):
|
||||
rel = os.path.relpath(os.path.join(root, file), COMFYUI_INPUT_FOLDER)
|
||||
mesh_files.append(rel)
|
||||
|
||||
# Then scan input root
|
||||
# Then scan input root (non-recursive, top-level files only)
|
||||
for file in os.listdir(COMFYUI_INPUT_FOLDER):
|
||||
file_path = os.path.join(COMFYUI_INPUT_FOLDER, file)
|
||||
if os.path.isfile(file_path):
|
||||
|
||||
@@ -6,6 +6,7 @@ Smoothing nodes
|
||||
"""
|
||||
|
||||
from .smooth import NODE_CLASS_MAPPINGS as SMOOTH_MAPS, NODE_DISPLAY_NAME_MAPPINGS as SMOOTH_DISP
|
||||
from .sharpen import NODE_CLASS_MAPPINGS as SHARPEN_MAPS, NODE_DISPLAY_NAME_MAPPINGS as SHARPEN_DISP
|
||||
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
@@ -13,4 +14,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
NODE_CLASS_MAPPINGS.update(SMOOTH_MAPS)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(SMOOTH_DISP)
|
||||
|
||||
NODE_CLASS_MAPPINGS.update(SHARPEN_MAPS)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(SHARPEN_DISP)
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# Copyright (C) 2025 ComfyUI-GeometryPack Contributors
|
||||
|
||||
"""
|
||||
Sharpen Mesh Node - Edge-recovering sharpening via pymeshlab.
|
||||
|
||||
Available backends:
|
||||
- two_step: Two-phase bilateral normal filtering. Smooths face normals
|
||||
(respecting dihedral angle thresholds), then repositions vertices to
|
||||
match. Sharpens creases while keeping faces flat. Best for CAD-like
|
||||
geometry from marching cubes, scanning, or neural SDF extraction.
|
||||
- unsharp_mask: Geometric unsharp masking. Subtracts a smoothed version
|
||||
from the original to amplify ridges and valleys.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import numpy as np
|
||||
import trimesh as trimesh_module
|
||||
|
||||
log = logging.getLogger("geometrypack")
|
||||
|
||||
|
||||
def _pymeshlab_two_step_sharpen(mesh, smooth_steps, normal_threshold,
|
||||
normal_iterations, fit_iterations, selected_only):
|
||||
"""Two-step bilateral normal sharpening via PyMeshLab."""
|
||||
try:
|
||||
import pymeshlab
|
||||
except (ImportError, OSError):
|
||||
return None, "pymeshlab is not installed. Install with: pip install pymeshlab"
|
||||
|
||||
ms = pymeshlab.MeshSet()
|
||||
pml_mesh = pymeshlab.Mesh(
|
||||
vertex_matrix=np.asarray(mesh.vertices, dtype=np.float64),
|
||||
face_matrix=np.asarray(mesh.faces, dtype=np.int32),
|
||||
)
|
||||
ms.add_mesh(pml_mesh)
|
||||
|
||||
try:
|
||||
ms.apply_coord_two_steps_smoothing(
|
||||
stepsmoothnum=smooth_steps,
|
||||
normalthr=normal_threshold,
|
||||
stepnormalnum=normal_iterations,
|
||||
stepfitnum=fit_iterations,
|
||||
selected=selected_only,
|
||||
)
|
||||
except AttributeError:
|
||||
try:
|
||||
ms.two_steps_smooth(
|
||||
stepsmoothnum=smooth_steps,
|
||||
normalthr=normal_threshold,
|
||||
stepnormalnum=normal_iterations,
|
||||
stepfitnum=fit_iterations,
|
||||
selected=selected_only,
|
||||
)
|
||||
except AttributeError:
|
||||
return None, (
|
||||
"PyMeshLab two-step smoothing filter not available. "
|
||||
"Ensure pymeshlab >= 2023.12 is installed."
|
||||
)
|
||||
|
||||
out = ms.current_mesh()
|
||||
result = trimesh_module.Trimesh(
|
||||
vertices=out.vertex_matrix(),
|
||||
faces=out.face_matrix(),
|
||||
process=False,
|
||||
)
|
||||
return result, ""
|
||||
|
||||
|
||||
def _pymeshlab_unsharp_mask_sharpen(mesh, weight, weight_original, iterations):
|
||||
"""Geometric unsharp mask sharpening via PyMeshLab."""
|
||||
try:
|
||||
import pymeshlab
|
||||
except (ImportError, OSError):
|
||||
return None, "pymeshlab is not installed. Install with: pip install pymeshlab"
|
||||
|
||||
ms = pymeshlab.MeshSet()
|
||||
pml_mesh = pymeshlab.Mesh(
|
||||
vertex_matrix=np.asarray(mesh.vertices, dtype=np.float64),
|
||||
face_matrix=np.asarray(mesh.faces, dtype=np.int32),
|
||||
)
|
||||
ms.add_mesh(pml_mesh)
|
||||
|
||||
try:
|
||||
ms.apply_coord_unsharp_mask(
|
||||
weight=weight,
|
||||
weightorig=weight_original,
|
||||
iterations=iterations,
|
||||
)
|
||||
except AttributeError:
|
||||
try:
|
||||
ms.coord_unsharp_mask(
|
||||
weight=weight,
|
||||
weightorig=weight_original,
|
||||
iterations=iterations,
|
||||
)
|
||||
except AttributeError:
|
||||
return None, (
|
||||
"PyMeshLab coordinate unsharp mask filter not available. "
|
||||
"Ensure pymeshlab >= 2023.12 is installed."
|
||||
)
|
||||
|
||||
out = ms.current_mesh()
|
||||
result = trimesh_module.Trimesh(
|
||||
vertices=out.vertex_matrix(),
|
||||
faces=out.face_matrix(),
|
||||
process=False,
|
||||
)
|
||||
return result, ""
|
||||
|
||||
|
||||
class SharpenMeshNode:
|
||||
"""
|
||||
Sharpen Mesh - Edge-recovering sharpening algorithms.
|
||||
|
||||
Available backends:
|
||||
- two_step: Bilateral normal filtering then vertex repositioning.
|
||||
Sharpens creases while flattening faces. Best for CAD-like geometry.
|
||||
The normal_threshold is the key parameter: edges with dihedral angle
|
||||
sharper than this are preserved as features.
|
||||
- unsharp_mask: Geometric unsharp masking. Subtracts smoothed from
|
||||
original to amplify ridges and valleys. Good for general enhancement.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"trimesh": ("TRIMESH",),
|
||||
"backend": ([
|
||||
"two_step",
|
||||
"unsharp_mask",
|
||||
], {
|
||||
"default": "two_step",
|
||||
"tooltip": (
|
||||
"Sharpening algorithm. "
|
||||
"two_step=bilateral normal filtering (recommended for CAD-like edges), "
|
||||
"unsharp_mask=geometric unsharp masking (general enhancement)"
|
||||
),
|
||||
}),
|
||||
},
|
||||
"optional": {
|
||||
"smooth_steps": ("INT", {
|
||||
"default": 3,
|
||||
"min": 1,
|
||||
"max": 50,
|
||||
"step": 1,
|
||||
"tooltip": (
|
||||
"Number of two-step smoothing passes. "
|
||||
"More steps = stronger sharpening effect."
|
||||
),
|
||||
"visible_when": {"backend": ["two_step"]},
|
||||
}),
|
||||
"normal_threshold": ("FLOAT", {
|
||||
"default": 60.0,
|
||||
"min": 0.0,
|
||||
"max": 180.0,
|
||||
"step": 0.5,
|
||||
"tooltip": (
|
||||
"Dihedral angle threshold in degrees. "
|
||||
"Edges sharper than this angle are preserved as features. "
|
||||
"Lower = more aggressive (more edges treated as creases). "
|
||||
"60 is a good default for most CAD models."
|
||||
),
|
||||
"visible_when": {"backend": ["two_step"]},
|
||||
}),
|
||||
"weight": ("FLOAT", {
|
||||
"default": 0.3,
|
||||
"min": 0.0,
|
||||
"max": 3.0,
|
||||
"step": 0.01,
|
||||
"tooltip": (
|
||||
"Unsharp mask weight controlling sharpening strength. "
|
||||
"Higher = more pronounced sharpening."
|
||||
),
|
||||
"visible_when": {"backend": ["unsharp_mask"]},
|
||||
}),
|
||||
"iterations": ("INT", {
|
||||
"default": 5,
|
||||
"min": 1,
|
||||
"max": 50,
|
||||
"step": 1,
|
||||
"tooltip": (
|
||||
"Smoothing iterations for the reference smooth mesh. "
|
||||
"More iterations = larger-scale sharpening."
|
||||
),
|
||||
"visible_when": {"backend": ["unsharp_mask"]},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("TRIMESH", "STRING")
|
||||
RETURN_NAMES = ("sharpened_mesh", "info")
|
||||
FUNCTION = "sharpen"
|
||||
CATEGORY = "geompack/smoothing"
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def sharpen(
|
||||
self,
|
||||
trimesh,
|
||||
backend,
|
||||
smooth_steps=3,
|
||||
normal_threshold=60.0,
|
||||
weight=0.3,
|
||||
iterations=5,
|
||||
):
|
||||
"""Apply mesh sharpening based on selected backend."""
|
||||
# Sanitize hidden widget values
|
||||
smooth_steps = int(smooth_steps) if smooth_steps not in (None, "") else 3
|
||||
normal_threshold = float(normal_threshold) if normal_threshold not in (None, "") else 60.0
|
||||
weight = float(weight) if weight not in (None, "") else 0.3
|
||||
iterations = int(iterations) if iterations not in (None, "") else 5
|
||||
|
||||
initial_vertices = len(trimesh.vertices)
|
||||
initial_faces = len(trimesh.faces)
|
||||
|
||||
log.info("Sharpen backend: %s", backend)
|
||||
log.info("Input: %s vertices, %s faces",
|
||||
f"{initial_vertices:,}", f"{initial_faces:,}")
|
||||
|
||||
if backend == "two_step":
|
||||
log.info("Parameters: smooth_steps=%d, normal_threshold=%.1f",
|
||||
smooth_steps, normal_threshold)
|
||||
sharpened, error = _pymeshlab_two_step_sharpen(
|
||||
trimesh, smooth_steps, normal_threshold,
|
||||
normal_iterations=20, fit_iterations=20,
|
||||
selected_only=False,
|
||||
)
|
||||
elif backend == "unsharp_mask":
|
||||
log.info("Parameters: weight=%.3f, iterations=%d", weight, iterations)
|
||||
sharpened, error = _pymeshlab_unsharp_mask_sharpen(
|
||||
trimesh, weight, weight_original=1.0, iterations=iterations,
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unknown backend: {backend}")
|
||||
|
||||
if sharpened is None:
|
||||
raise ValueError(f"Sharpening failed ({backend}): {error}")
|
||||
|
||||
# Copy metadata
|
||||
if hasattr(trimesh, "metadata") and trimesh.metadata:
|
||||
sharpened.metadata = trimesh.metadata.copy()
|
||||
sharpened.metadata["sharpening"] = {
|
||||
"algorithm": backend,
|
||||
"original_vertices": initial_vertices,
|
||||
"original_faces": initial_faces,
|
||||
}
|
||||
|
||||
# Compute displacement stats
|
||||
disp = np.linalg.norm(
|
||||
np.asarray(sharpened.vertices) - np.asarray(trimesh.vertices), axis=1
|
||||
)
|
||||
avg_disp = float(np.mean(disp))
|
||||
max_disp = float(np.max(disp))
|
||||
|
||||
log.info("Output: %d vertices, %d faces",
|
||||
len(sharpened.vertices), len(sharpened.faces))
|
||||
log.info("Avg vertex displacement: %.6f, max: %.6f", avg_disp, max_disp)
|
||||
|
||||
# Build backend-specific param block
|
||||
if backend == "two_step":
|
||||
param_text = (
|
||||
f"Smooth Steps: {smooth_steps}\n"
|
||||
f"Normal Threshold: {normal_threshold}\u00b0"
|
||||
)
|
||||
elif backend == "unsharp_mask":
|
||||
param_text = (
|
||||
f"Weight: {weight}\n"
|
||||
f"Iterations: {iterations}"
|
||||
)
|
||||
else:
|
||||
param_text = ""
|
||||
|
||||
info = f"""Sharpen Mesh Results ({backend}):
|
||||
|
||||
{param_text}
|
||||
|
||||
Vertices: {initial_vertices:,} (unchanged)
|
||||
Faces: {initial_faces:,} (unchanged)
|
||||
|
||||
Displacement:
|
||||
Average: {avg_disp:.6f}
|
||||
Maximum: {max_disp:.6f}
|
||||
"""
|
||||
return {"ui": {"text": [info]}, "result": (sharpened, info)}
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"GeomPackSharpenMesh": SharpenMeshNode,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"GeomPackSharpenMesh": "Sharpen Mesh",
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
# Nodes Without Workflow Coverage
|
||||
|
||||
35 of 74 nodes (~47%) have no workflow JSON. Checked against `workflows/*.json`.
|
||||
|
||||
## IO (5 missing)
|
||||
- [ ] `GeomPackLoadMeshPath` — Load Mesh (Path)
|
||||
- [ ] `GeomPackLoadMeshGlob` — Load Mesh Batch (Glob)
|
||||
- [ ] `GeomPackSaveMesh` — Save Mesh
|
||||
- [ ] `GeomPackSaveMeshBatch` — Save Meshes to Folder
|
||||
- [ ] `GeomPackGetMeshFilename` — Get Mesh Filename
|
||||
|
||||
## Analysis (4 missing)
|
||||
- [ ] `GeomPackConnectedComponents` — Connected Components
|
||||
- [ ] `GeomPackOpenEdges` — Open Edges
|
||||
- [ ] `GeomPackDegenerateFaces` — Degenerate Faces
|
||||
- [ ] `ScrambleIntField` — Scramble Int Field
|
||||
|
||||
## Conversion (1 missing)
|
||||
- [ ] `GeomPackSubsamplePointCloud` — Subsample Point Cloud
|
||||
|
||||
## Transforms (1 missing)
|
||||
- [ ] `GeomPackNormalizeMeshToBBox` — Normalize to BBox
|
||||
|
||||
## Visualization (3 missing)
|
||||
- [ ] `GeomPackBackdraftView` — Backdraft View
|
||||
- [ ] `GeomPackPreviewGaussian` — Preview Gaussian
|
||||
- [ ] `GeomPackPreviewMeshAnalysis` — Preview Mesh (Analysis)
|
||||
|
||||
## Repair (6 missing)
|
||||
- [ ] `GeomPackAddNormalsToPointCloud` — Add Normals to PointCloud
|
||||
- [ ] `GeomPackVisualizeNormalField` — Visualize Normal Field
|
||||
- [ ] `GeomPackMergeVertices` — Merge Vertices
|
||||
- [ ] `GeomPackFixSelfIntersectionsByRemoval` — Fix Self Intersections (Removal)
|
||||
- [ ] `GeomPackRemoveDegenerateFaces` — Remove Degenerate Faces
|
||||
- [ ] `GeomPackMeshFix` — MeshFix
|
||||
|
||||
## Texture Remeshing (1 missing)
|
||||
- [ ] `GeomPackDepthNormalsToMesh` — Depth + Normals to Mesh
|
||||
|
||||
## Combine (2 missing)
|
||||
- [ ] `GeomPackCombineMeshesBatch` — Combine Meshes (Batch)
|
||||
- [ ] `GeomPackSplitByField` — Split By Field
|
||||
|
||||
## Boolean (1 missing)
|
||||
- [ ] `GeomPackBooleanBlender` — Boolean Blender
|
||||
|
||||
## ParaView (1 missing)
|
||||
- [ ] `GeomPackParaViewFilter` — ParaView Filter
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"b2f31842-cb16-4652-a0bb-ef347acd2c27","revision":0,"last_node_id":3,"last_link_id":3,"nodes":[{"id":2,"type":"GeomPackLoadMesh","pos":[-475.3018486006804,-89.92481471968625],"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,2]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/spot_the_cow.obj"]},{"id":1,"type":"GeomPackDecimateMesh","pos":[-341.89427205099804,42.18256877884877],"size":[214.34375,222],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":1},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"target_face_count","name":"target_face_count","shape":7,"type":"INT","widget":{"name":"target_face_count"},"link":null},{"localized_name":"target_reduction","name":"target_reduction","shape":7,"type":"FLOAT","widget":{"name":"target_reduction"},"link":null},{"localized_name":"quality_threshold","name":"quality_threshold","shape":7,"type":"FLOAT","widget":{"name":"quality_threshold"},"link":null},{"localized_name":"preserve_boundary","name":"preserve_boundary","shape":7,"type":"COMBO","widget":{"name":"preserve_boundary"},"link":null},{"localized_name":"preserve_normal","name":"preserve_normal","shape":7,"type":"COMBO","widget":{"name":"preserve_normal"},"link":null},{"localized_name":"preserve_topology","name":"preserve_topology","shape":7,"type":"COMBO","widget":{"name":"preserve_topology"},"link":null},{"localized_name":"planar_quadric","name":"planar_quadric","shape":7,"type":"COMBO","widget":{"name":"planar_quadric"},"link":null},{"localized_name":"aggressiveness","name":"aggressiveness","shape":7,"type":"INT","widget":{"name":"aggressiveness"},"link":null},{"localized_name":"cluster_threshold","name":"cluster_threshold","shape":7,"type":"FLOAT","widget":{"name":"cluster_threshold"},"link":null},{"localized_name":"cost_strategy","name":"cost_strategy","shape":7,"type":"COMBO","widget":{"name":"cost_strategy"},"link":null},{"localized_name":"feature_angle","name":"feature_angle","shape":7,"type":"FLOAT","widget":{"name":"feature_angle"},"link":null}],"outputs":[{"localized_name":"decimated_mesh","name":"decimated_mesh","type":"TRIMESH","links":[3]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackDecimateMesh"},"widgets_values":["quadric_edge_collapse",1004,0.5,0.3,"true","true","true","false",7,1,"lindstrom_turk",15]},{"id":3,"type":"GeomPackPreviewMeshDual","pos":[-76.10573591330262,-130.49691411299682],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":2},{"localized_name":"mesh_2","name":"mesh_2","type":"TRIMESH","link":3},{"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":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,"{\"show_edges\":true,\"camera_state\":\"{\\\"position\\\":[-1.7780235403811753,1.6766117516965702,-3.559892704773735],\\\"focalPoint\\\":[0,0,0],\\\"viewUp\\\":[0.10922451112503215,0.9191915766556414,0.3783607426449175]}\",\"selected_field\":\"\"}"]}],"links":[[1,2,0,1,0,"TRIMESH"],[2,2,0,3,0,"TRIMESH"],[3,1,0,3,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"workflowRendererVersion":"LG","ds":{"scale":0.564473930053778,"offset":[1015.1636836243922,437.7471233117878]}},"version":0.4}
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"3a030446-090e-4dec-aa56-ff2245e5c752","revision":0,"last_node_id":5,"last_link_id":8,"nodes":[{"id":3,"type":"GeomPackLoadMesh","pos":[-122.94664697897677,-247.07890552869162],"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,7]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/cow.off"]},{"id":1,"type":"GeomPackPreviewMeshDual","pos":[360.9494657084009,-269.09765927991236],"size":[768,834],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":1},{"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":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackPreviewMeshDual"},"widgets_values":["side_by_side","fields",1,1,"{\"show_edges\":true,\"camera_state\":\"{\\\"position\\\":[-1.264590737186599,0.4315551722479547,-0.95689822713445],\\\"focalPoint\\\":[0,0,0],\\\"viewUp\\\":[0.3414289225328609,0.9395050612781046,-0.027505102996978413]}\",\"selected_field\":\"\"}"]},{"id":5,"type":"GeomPackSmoothMesh","pos":[19.308970746690356,8.031904442981274],"size":[210,150],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":7},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null},{"localized_name":"lambda_","name":"lambda_","shape":7,"type":"FLOAT","widget":{"name":"lambda_"},"link":null},{"localized_name":"mu","name":"mu","shape":7,"type":"FLOAT","widget":{"name":"mu"},"link":null},{"localized_name":"cotangent_weight","name":"cotangent_weight","shape":7,"type":"COMBO","widget":{"name":"cotangent_weight"},"link":null}],"outputs":[{"localized_name":"smoothed_mesh","name":"smoothed_mesh","type":"TRIMESH","links":[8]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackSmoothMesh"},"widgets_values":["taubin",5,1,-0.8,"true"]}],"links":[[1,3,0,1,0,"TRIMESH"],[7,3,0,5,0,"TRIMESH"],[8,5,0,1,1,"TRIMESH"]],"groups":[],"config":{},"extra":{"workflowRendererVersion":"LG","ds":{"scale":0.7513148009015788,"offset":[360.4697500785045,392.5990955570182]}},"version":0.4}
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"1420e2f4-15c5-4bb4-b298-69fb0d5f6356","revision":0,"last_node_id":8,"last_link_id":8,"nodes":[{"id":6,"type":"GeomPackLoadMesh","pos":[-719.4819699886815,-132.5789047560572],"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":[6]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/noisy/Fandisk0.3/Original.obj"]},{"id":4,"type":"GeomPackLoadMesh","pos":[-765.4619884518163,129.58774960185292],"size":[270,78],"flags":{},"order":1,"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,7]},{"localized_name":"texture","name":"texture","type":"IMAGE","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackLoadMesh"},"widgets_values":["3d/noisy/Fandisk0.3/Noisy.obj"]},{"id":7,"type":"GeomPackSharpenMesh","pos":[-424.4191210268283,273.2249762472692],"size":[210,126],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"trimesh","name":"trimesh","type":"TRIMESH","link":5},{"localized_name":"backend","name":"backend","type":"COMBO","widget":{"name":"backend"},"link":null},{"localized_name":"smooth_steps","name":"smooth_steps","shape":7,"type":"INT","widget":{"name":"smooth_steps"},"link":null},{"localized_name":"normal_threshold","name":"normal_threshold","shape":7,"type":"FLOAT","widget":{"name":"normal_threshold"},"link":null},{"localized_name":"weight","name":"weight","shape":7,"type":"FLOAT","widget":{"name":"weight"},"link":null},{"localized_name":"iterations","name":"iterations","shape":7,"type":"INT","widget":{"name":"iterations"},"link":null}],"outputs":[{"localized_name":"sharpened_mesh","name":"sharpened_mesh","type":"TRIMESH","links":[8]},{"localized_name":"info","name":"info","type":"STRING","links":null}],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackSharpenMesh"},"widgets_values":["two_step",2,60,0,5]},{"id":8,"type":"GeomPackPreviewMeshMulti","pos":[-93.23315435742478,-231.02465627340337],"size":[768,702],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"mesh_1","name":"mesh_1","type":"TRIMESH","link":6},{"localized_name":"mesh_2","name":"mesh_2","shape":7,"type":"TRIMESH","link":7},{"localized_name":"mesh_3","name":"mesh_3","shape":7,"type":"TRIMESH","link":8},{"localized_name":"mesh_4","name":"mesh_4","shape":7,"type":"TRIMESH","link":null},{"localized_name":"mode","name":"mode","shape":7,"type":"COMBO","widget":{"name":"mode"},"link":null}],"outputs":[],"properties":{"cnr_id":"comfyui-geometrypack","ver":"283cfbc4414b0b9343c6562793f7b42f80dd32dd","Node name for S&R":"GeomPackPreviewMeshMulti"},"widgets_values":["fields","{\"show_edges\":true,\"camera_state\":\"{\\\"position\\\":[11.988365833801835,17.82450062324679,9.744545997398912],\\\"focalPoint\\\":[2.4225937947630882,15.191427230834961,-1.2984154149889946],\\\"viewUp\\\":[-0.5732642974885914,-0.5317644442147023,0.6233735806833175]}\",\"selected_field\":\"\"}"]}],"links":[[5,4,0,7,0,"TRIMESH"],[6,6,0,8,0,"TRIMESH"],[7,4,0,8,1,"TRIMESH"],[8,7,0,8,2,"TRIMESH"]],"groups":[],"config":{},"extra":{"workflowRendererVersion":"LG","ds":{"scale":0.6209213230591556,"offset":[948.190060342013,447.314044719686]}},"version":0.4}
|
||||
Reference in New Issue
Block a user