Optimize Cutout Geometry Nodes

- Refactor Depth Cutout to reuse the projected outline field, reducing redundant boundary calculations and improving performance.
- Derive the center field from shared low-frequency fields, eliminating an unnecessary blur operation.
- Implement triangle-only strip cleanup for Depth Cutout, as the input is confirmed to be triangulated.
- Short-circuit zero-thickness branches in both Cutout and Depth Cutout to avoid unnecessary geometry generation.
- Standardize internal attribute naming with a new `_o_` prefix and implement wildcard cleanup for temporary attributes.
- Update relevant tests to ensure functionality remains consistent and validate changes against existing behavior.
This commit is contained in:
2026-09-16 08:42:13 +08:00
parent cf512dc013
commit 7f878a2f3f
22 changed files with 584 additions and 135 deletions

View File

@@ -1,5 +1,6 @@
"""Evaluate opposite-boundary cleanup on explicit mesh topology."""
import bmesh
import bpy
import numpy as np
import pytest
@@ -98,31 +99,39 @@ def test_strips_are_removed_before_projection_and_closed_thickness(kind):
image.update()
set_value("Depth Scale", 1.0)
set_value("Reference Depth", 11.0)
assert len(evaluated(obj)[1]) == 8
if kind == "cutout":
bm = bmesh.new()
bm.from_mesh(obj.data)
bmesh.ops.triangulate(bm, faces=list(bm.faces))
bm.to_mesh(obj.data)
bm.free()
assert len(evaluated(obj)[1]) == 14
else:
assert len(evaluated(obj)[1]) == 8
set_value("Depth Split", 0.5)
vertices, faces = evaluated(obj)
assert len(faces) == 4 and len(vertices) == 9
if kind == "cutout":
assert len(faces) == 6 and len(vertices) == 7
else:
assert len(faces) == 4 and len(vertices) == 9
assert component_count(faces) == 1
set_value("Thickness", 0.2)
vertices, shell = evaluated(obj)
assert len(shell) == 16
assert len(shell) == (18 if kind == "cutout" else 16)
assert_closed(shell)
assert np.isfinite(vertices).all()
assert component_count(shell) == 1
set_value("Thickness", 0.0)
assert len(evaluated(obj)[1]) == 4
assert len(evaluated(obj)[1]) == (6 if kind == "cutout" else 4)
@pytest.mark.parametrize("kind", ["plane", "cutout"])
@pytest.mark.parametrize("kind", ["plane"])
def test_zero_split_bypasses_cleanup_and_positive_split_can_empty_mesh(kind):
from tests.support.depth_surface import surface, evaluated
from tests.support.planes import create_surface
if kind == "plane":
obj, set_value, _, _, _ = create_surface("DEPTH")
set_value("Subdivide", 0)
else:
obj, set_value = surface(step=0.0, resolution=1)
obj, set_value, _, _, _ = create_surface("DEPTH")
set_value("Subdivide", 0)
original, faces = evaluated(obj)
assert len(faces) == 2
set_value("Depth Split", 0.001)