feat(selection): separate selection geometry from image content processing
- Introduced a new design for selection rasterization that decouples the selection geometry from the image content, ensuring that the SelectionMask is independent of the source image's alpha and color. - Updated the `rasterize_selection_path` function to only accept selection paths and image dimensions, removing parameters related to source alpha and alpha thresholds. - Implemented a new approach for handling selection paths using non-zero winding fill, ensuring overlapping areas are preserved. - Enhanced performance by utilizing a scanline algorithm for rasterization, significantly reducing processing time for high-resolution images. - Updated internal documentation and added comprehensive tests to validate the new behavior and performance improvements. - Ensured backward compatibility by maintaining existing interfaces where necessary while introducing breaking changes in the selection processing logic.
This commit is contained in:
@@ -27,21 +27,15 @@ def evaluated_mesh(obj):
|
||||
return evaluated, evaluated.to_mesh()
|
||||
|
||||
|
||||
def modifier_input_value(modifier, identifier):
|
||||
inputs = getattr(getattr(modifier, "properties", None), "inputs", None)
|
||||
if inputs is not None:
|
||||
return getattr(inputs, identifier).value
|
||||
return modifier[identifier]
|
||||
|
||||
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
mesh = create_mesh_plane_mesh("Mesh Plane", (-1.0, 1.0, -0.5, 0.5))
|
||||
assert len(mesh.polygons) == 1
|
||||
material = bpy.data.materials.new("Mesh Plane Material")
|
||||
mesh.materials.append(material)
|
||||
obj = bpy.data.objects.new("Mesh Plane", mesh)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
modifier = add_mesh_plane_processing(obj, material)
|
||||
modifier = add_mesh_plane_processing(obj)
|
||||
group = modifier.node_group
|
||||
assert group.name == "O Mesh Plane"
|
||||
assert group.is_modifier
|
||||
@@ -50,15 +44,15 @@ def main():
|
||||
for item in group.interface.items_tree
|
||||
if item.item_type == "SOCKET" and item.in_out == "INPUT"
|
||||
}
|
||||
assert list(inputs) == ["Geometry", "Subdivide", "Thickness", "Material"]
|
||||
assert list(inputs) == ["Geometry", "Subdivide", "Thickness"]
|
||||
assert inputs["Subdivide"].default_value == 0
|
||||
assert inputs["Subdivide"].max_value == 10
|
||||
assert inputs["Thickness"].default_value == 0.0
|
||||
assert inputs["Material"].hide_in_modifier
|
||||
assert modifier_input_value(modifier, inputs["Material"].identifier) == material
|
||||
assert obj.data.materials[0] == material
|
||||
|
||||
evaluated, result = evaluated_mesh(obj)
|
||||
try:
|
||||
assert result.materials[0].original == material
|
||||
assert len(result.polygons) == 2
|
||||
assert len(result.vertices) == 6
|
||||
assert "UVMap" in result.attributes
|
||||
@@ -75,6 +69,7 @@ def main():
|
||||
(1.0, 1.0),
|
||||
}
|
||||
assert all(abs(vertex.co.z) < 1e-6 for vertex in result.vertices)
|
||||
assert all(polygon.material_index == 0 for polygon in result.polygons)
|
||||
finally:
|
||||
evaluated.to_mesh_clear()
|
||||
|
||||
@@ -92,6 +87,7 @@ def main():
|
||||
obj.update_tag(refresh={"DATA"})
|
||||
evaluated, result = evaluated_mesh(obj)
|
||||
try:
|
||||
assert result.materials[0].original == material
|
||||
assert len(result.polygons) == 184
|
||||
z_values = [vertex.co.z for vertex in result.vertices]
|
||||
assert abs(min(z_values) + 0.6) < 1e-6
|
||||
@@ -102,6 +98,17 @@ def main():
|
||||
for edge_key in polygon.edge_keys:
|
||||
edge_users[edge_key] += 1
|
||||
assert all(users == 2 for users in edge_users.values())
|
||||
assert all(polygon.material_index == 0 for polygon in result.polygons)
|
||||
finally:
|
||||
evaluated.to_mesh_clear()
|
||||
|
||||
set_modifier_input(modifier, modifier_input_identifier(group, "Subdivide"), 0)
|
||||
set_modifier_input(modifier, modifier_input_identifier(group, "Thickness"), 0.01)
|
||||
obj.update_tag(refresh={"DATA"})
|
||||
evaluated, result = evaluated_mesh(obj)
|
||||
try:
|
||||
z_values = {round(vertex.co.z, 6) for vertex in result.vertices}
|
||||
assert len(z_values) >= 4
|
||||
finally:
|
||||
evaluated.to_mesh_clear()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user