Refactor comparison operations in geometry nodes

- Introduced a new `compare_node` function to streamline comparison operations across various geometry nodes.
- Replaced instances of mathematical comparison nodes with the new `compare_node` function in multiple files, enhancing code readability and maintainability.
- Updated related logic in cutout, depth surface, and image processing groups to utilize the new comparison method.
- Ensured consistent handling of boolean logic through the introduction of a `boolean_node` function for combining boolean inputs.
This commit is contained in:
2026-09-16 21:42:02 +08:00
parent c62ec2cd48
commit 78bbff6351
19 changed files with 282 additions and 200 deletions

View File

@@ -37,9 +37,21 @@ def test_camera_projection_and_reference_depth(surface, strength):
base = evaluated(obj)
uv = (base[0][:, [0, 2]] + (2, 1)) / (4, 2)
texel = np.clip(uv * (16, 8), (0.5, 0.5), (15.5, 7.5))
camera = np.column_stack(((texel[:, 0] - 5) / 8,
(2 + texel[:, 0] / 16) * 0.5 - 1.2,
(texel[:, 1] - 3) / 8))
depth = 2 + texel[:, 0] / 16
# Outline vertices keep the border ray and adopt the adjacent face-centre
# depth, the same rule cut edges use to inherit their face sample.
face_depth = np.zeros((len(base[0]), 2))
for face in base[1]:
center = np.mean(base[0][list(face)], axis=0)
value = 2 + np.clip((center[0] + 2) / 4 * 16, 0.5, 15.5) / 16
for index in face:
face_depth[index] += (value, 1)
face_depth = face_depth[:, 0] / face_depth[:, 1]
on_outline = np.isclose(uv, 0).any(axis=1) | np.isclose(uv, 1).any(axis=1)
ratio = np.where(on_outline, face_depth / depth, 1.0)
camera = np.column_stack(((texel[:, 0] - 5) / 8 * ratio,
(depth * 0.5) * ratio - 1.2,
(texel[:, 1] - 3) / 8 * ratio))
expected = base[0] * (1 - strength) + camera * strength
set_value("Depth Scale", float(strength))
projected = evaluated(obj)
@@ -297,7 +309,7 @@ def test_relief_direction_adjusts_depth_and_keeps_base(relief, thickness, direct
("valid", 1.0), ("invalid", 0.0), ("invalid", 0.9),
("partial", 0.4), ("partial", 0.9), ("half", 0.9), ("stripe", 0.9),
])
def test_valid_only_deletes_invalid_points_and_wire_edges(surface, pattern, threshold):
def test_valid_only_keeps_faces_covering_valid_samples(surface, pattern, threshold):
obj, set_value, _, inputs, _ = surface
set_value("Mask Threshold", threshold)
depth_image = obj.modifiers[0][inputs["Depth Image"].identifier]
@@ -315,13 +327,16 @@ def test_valid_only_deletes_invalid_points_and_wire_edges(surface, pattern, thre
pixels[..., 3] = alpha
depth_image.pixels.foreach_set(pixels.ravel())
depth_image.update()
def sampled(x):
return np.interp((x + 2) / 4 * 16 - 0.5, np.arange(16), alpha)
for subdivisions in (0, 2, 5):
set_value("Subdivide", subdivisions)
set_value("Depth Mask", False)
base = evaluated(obj)
u = (base[0][:, 0] + 2) / 4
sampled = np.interp(u * 16 - 0.5, np.arange(16), alpha)
expected = [face for face in base[1] if np.all(sampled[list(face)] >= threshold)]
expected = [face for face in base[1]
if sampled(np.mean(base[0][list(face)][:, 0])) >= threshold]
set_value("Depth Mask", True)
culled = evaluated(obj)
assert len(culled[1]) == len(expected)