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:
@@ -33,12 +33,6 @@ def mesh_component_count(faces):
|
||||
return count
|
||||
|
||||
|
||||
def test_cutout_mesh_limit_caps_actual_sampling_resolution():
|
||||
assert cutout_geometry.limit_cutout_point_spacing(32, (4096, 1024), 1024) == 32
|
||||
assert cutout_geometry.limit_cutout_point_spacing(32, (4096, 1024), 64) == 64
|
||||
assert cutout_geometry.limit_cutout_point_spacing(4, (8192, 4096), 1024) == 8
|
||||
|
||||
|
||||
def test_cutout_node_groups_are_loaded_from_the_asset():
|
||||
loaded = object()
|
||||
with patch.object(
|
||||
@@ -147,7 +141,7 @@ def test_blender_cutout_alpha_pipeline_does_not_import_pillow():
|
||||
assert np.any((antialiased > 0.0) & (antialiased < 1.0))
|
||||
|
||||
|
||||
def test_blender_cutout_contour_resolution_tracks_mesh_detail():
|
||||
def test_blender_cutout_contour_resolution_tracks_sampling_resolution():
|
||||
expected = SelectionContours(
|
||||
components=(((((0, 0), (1, 0), (0, 1))),),),
|
||||
image_size=(1, 1),
|
||||
@@ -155,53 +149,12 @@ def test_blender_cutout_contour_resolution_tracks_mesh_detail():
|
||||
values = SimpleNamespace(shape=(1024, 1024))
|
||||
with patch.object(cutout_geometry, "extract_selection_contours", return_value=expected) as trace:
|
||||
assert cutout_geometry.extract_cutout_contours(values, 32) == expected
|
||||
assert cutout_geometry.extract_cutout_contours(values, 4) == expected
|
||||
assert cutout_geometry.extract_cutout_contours(values, 256) == expected
|
||||
|
||||
assert trace.call_args_list[0].kwargs["max_resolution"] == 512
|
||||
assert trace.call_args_list[1].kwargs["max_resolution"] == 1024
|
||||
|
||||
|
||||
def test_cutout_sampling_spacing_uses_the_complete_source_plane():
|
||||
source = SimpleNamespace(
|
||||
data=SimpleNamespace(size=(400, 200)),
|
||||
matrix_world=object(),
|
||||
)
|
||||
with (
|
||||
patch.object(cutout_geometry, "image_empty_bounds", return_value=(-2.0, 2.0, -1.0, 1.0)),
|
||||
patch.object(
|
||||
cutout_geometry,
|
||||
"world_plane_metric",
|
||||
return_value=(((1.0, 0.0), (0.0, 1.0)), 1.0),
|
||||
),
|
||||
):
|
||||
spacing = cutout_geometry.cutout_sampling_spacing(source, 32)
|
||||
|
||||
assert spacing == 0.32
|
||||
|
||||
|
||||
def test_cutout_sampling_spacing_tracks_upscaled_source_pixels():
|
||||
original = SimpleNamespace(
|
||||
data=SimpleNamespace(size=(2048, 1024)),
|
||||
matrix_world=object(),
|
||||
)
|
||||
upscaled = SimpleNamespace(
|
||||
data=SimpleNamespace(size=(8192, 4096)),
|
||||
matrix_world=object(),
|
||||
)
|
||||
with (
|
||||
patch.object(cutout_geometry, "image_empty_bounds", return_value=(-2.0, 2.0, -1.0, 1.0)),
|
||||
patch.object(
|
||||
cutout_geometry,
|
||||
"world_plane_metric",
|
||||
return_value=(((1.0, 0.0), (0.0, 1.0)), 1.0),
|
||||
),
|
||||
):
|
||||
original_spacing = cutout_geometry.cutout_sampling_spacing(original, 32)
|
||||
upscaled_spacing = cutout_geometry.cutout_sampling_spacing(upscaled, 32)
|
||||
|
||||
assert upscaled_spacing == original_spacing / 4
|
||||
|
||||
|
||||
def test_cutout_cleanup_value_scales_the_ui_without_changing_node_area():
|
||||
assert np.isclose(
|
||||
cutout_geometry.cutout_cleanup_value(
|
||||
|
||||
Reference in New Issue
Block a user