Refactor Cutout Tool to Use World Space Edge Length
- Replaced the Mesh Detail parameter with a new Edge Length property to define cutout sampling in physical units. - Introduced Minimum Relative Edge Length preference to control effective spacing based on the bounding box of the cutout content. - Updated tests to validate the new edge length functionality and ensure consistent behavior across different resolutions and canvas sizes. - Removed deprecated parameters and adjusted related properties to align with the new edge length implementation. - Enhanced geometry sampling logic to utilize effective world spacing for both standard and fine outline modes.
This commit is contained in:
@@ -25,8 +25,8 @@ def set_test_structure(monkeypatch, value):
|
||||
from tools.nodes.groups import image_depth_cutout
|
||||
build = image_depth_cutout.build_front_fields
|
||||
|
||||
def fields(group, rim, normal, normal_weight):
|
||||
result = build(group, rim, normal, normal_weight)
|
||||
def fields(group, volume, normal, normal_weight):
|
||||
result = build(group, volume, normal, normal_weight)
|
||||
structure = group.nodes.new("ShaderNodeValue")
|
||||
structure.outputs[0].default_value = value
|
||||
result["structure"] = structure.outputs[0]
|
||||
|
||||
@@ -67,7 +67,7 @@ def test_saved_parameter_descriptions_match_definitions():
|
||||
assert len(thickness) == 2 and len(set(thickness)) == 2
|
||||
if group.name == "O Image Depth Cutout":
|
||||
inflation = next(item for item in sockets if item.name == "Front Inflation")
|
||||
assert inflation.default_value == 0.5
|
||||
assert inflation.default_value == 0.0
|
||||
result[group.name] = [
|
||||
(item.identifier, item.name, item.description) for item in sockets
|
||||
]
|
||||
@@ -82,6 +82,35 @@ def test_saved_parameter_descriptions_match_definitions():
|
||||
assert descriptions(target.node_groups) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("source", ["definition", "asset"])
|
||||
def test_geometry_nodes_contribute_to_output(source):
|
||||
from tools.nodes.build import build_node_groups
|
||||
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
if source == "definition":
|
||||
groups = build_node_groups()
|
||||
else:
|
||||
with bpy.data.libraries.load(str(node_asset_path())) as (library, target):
|
||||
target.node_groups = list(library.node_groups)
|
||||
groups = target.node_groups
|
||||
for group in groups:
|
||||
if group.bl_idname != "GeometryNodeTree":
|
||||
continue
|
||||
pending = [node for node in group.nodes if node.bl_idname == "NodeGroupOutput"]
|
||||
used = set()
|
||||
while pending:
|
||||
node = pending.pop()
|
||||
if node in used:
|
||||
continue
|
||||
used.add(node)
|
||||
pending.extend(link.from_node for socket in node.inputs for link in socket.links)
|
||||
pending.extend(candidate for candidate in group.nodes
|
||||
if getattr(candidate, "paired_output", None) == node)
|
||||
unused = [node.name for node in group.nodes
|
||||
if node not in used and node.bl_idname != "NodeFrame"]
|
||||
assert not unused, (group.name, unused)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("source", ["definition", "asset"])
|
||||
def test_geometry_attribute_contract_includes_nested_groups(source):
|
||||
from tools.nodes.build import build_node_groups
|
||||
|
||||
Reference in New Issue
Block a user