Add tests and implement boundary smoothing and cutout functionality
- Introduced tests for boundary smoothing in `test_boundary_smoothing.py`, verifying that smoothing reduces stair-step artifacts while preserving boundary integrity. - Added tests for cutout boundary behavior in `test_cutout_boundary.py`, ensuring proper handling of boundary triangles and normal blending. - Created `test_temporary_attributes.py` to check the cleanup of temporary attributes across depth modifier branches, ensuring no warnings are raised. - Implemented point culling functionality in `test_validity.py`, confirming that invalid points are removed without affecting adjacent geometry. - Developed boundary smoothing logic in `boundary_smoothing.py`, allowing for depth smoothing while maintaining edge integrity. - Added cutout boundary management in `cutout_boundary.py`, including functions for removing boundary triangles and tapering thickness profiles. - Implemented validity checks in `validity.py` to ensure proper deletion of invalid vertices and associated wire edges.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import bpy
|
||||
import pytest
|
||||
|
||||
from anyimage.common.object import (
|
||||
modifier_input_identifier,
|
||||
@@ -17,6 +18,46 @@ def evaluated_mesh(obj):
|
||||
return evaluated, evaluated.to_mesh()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("source_count", [0, 4, 9])
|
||||
def test_material_inheritance_removes_only_source_vertices(source_count):
|
||||
from tools.nodes.common.material import inherit_material_slots
|
||||
from tools.nodes.arrangement.arrange import arrange_nodes
|
||||
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
mesh = bpy.data.meshes.new("Source")
|
||||
mesh.from_pydata([(20 + i % 3, i // 3, 0) for i in range(source_count)], [],
|
||||
[(0, 1, 3, 2)] if source_count else [])
|
||||
materials = [bpy.data.materials.new(name) for name in ("First", "Second")]
|
||||
for material in materials:
|
||||
mesh.materials.append(material)
|
||||
obj = bpy.data.objects.new("Material Source", mesh)
|
||||
bpy.context.collection.objects.link(obj)
|
||||
group = bpy.data.node_groups.new("Material Inheritance", "GeometryNodeTree")
|
||||
group.interface.new_socket(name="Geometry", in_out="INPUT", socket_type="NodeSocketGeometry")
|
||||
group.interface.new_socket(name="Geometry", in_out="OUTPUT", socket_type="NodeSocketGeometry")
|
||||
source = group.nodes.new("NodeGroupInput")
|
||||
grid = group.nodes.new("GeometryNodeMeshGrid")
|
||||
grid.inputs["Vertices X"].default_value = 3
|
||||
grid.inputs["Vertices Y"].default_value = 2
|
||||
geometry = inherit_material_slots(group, grid.outputs["Mesh"], source.outputs["Geometry"])
|
||||
group.links.new(geometry, group.nodes.new("NodeGroupOutput").inputs["Geometry"])
|
||||
obj.modifiers.new("Material Inheritance", "NODES").node_group = group
|
||||
for arranged in (False, True):
|
||||
if arranged:
|
||||
arrange_nodes(group)
|
||||
obj.update_tag(refresh={"DATA"})
|
||||
ev, result = evaluated_mesh(obj)
|
||||
try:
|
||||
assert len(result.vertices) == 6 and len(result.polygons) == 2
|
||||
assert all(abs(v.co.x) <= 0.5 for v in result.vertices)
|
||||
if source_count:
|
||||
assert [material.original for material in result.materials if material] == materials
|
||||
assert result.materials[0].original == materials[0]
|
||||
assert all(face.material_index == 0 for face in result.polygons)
|
||||
finally:
|
||||
ev.to_mesh_clear()
|
||||
|
||||
|
||||
def test_saved_image_plane_evaluation():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
mesh = create_image_plane_mesh("Image Plane", (-1.0, 1.0, -0.5, 0.5))
|
||||
|
||||
Reference in New Issue
Block a user