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:
2026-09-12 23:03:24 +08:00
parent 938d95db0f
commit 18799e8828
28 changed files with 505 additions and 279 deletions

View File

@@ -69,7 +69,7 @@ class CutoutOperatorsTest(BlenderTestCase):
),
shape=shape,
gesture="POLYLINE",
point_spacing=32,
edge_length=0.1,
alpha_threshold=0.25,
fine_outline=False,
generate_normal=False,
@@ -98,11 +98,6 @@ class CutoutOperatorsTest(BlenderTestCase):
"configured_max_ai_input_size",
return_value=2048,
),
patch.object(
self.cutout_main,
"configured_max_cutout_mesh_resolution",
return_value=1024,
),
patch.object(
self.cutout_main,
"_cutout_content_values",
@@ -128,13 +123,14 @@ class CutoutOperatorsTest(BlenderTestCase):
context,
source,
shape,
32.0,
0.1,
selection_mask.values,
selection_mask.bounds,
alpha_threshold=0.25,
fine_outline=False,
color_image="Color",
gesture="POLYLINE",
report=operator.report,
)
@@ -161,7 +157,8 @@ class CutoutOperatorsTest(BlenderTestCase):
{"points": [[1, 1], [7, 1], [7, 3], [1, 3]]}
)
operator.shape = "DEPTH_SOLID"
operator.point_spacing = 32
operator.report = lambda *_args: None
operator.edge_length = 0.1
operator.generate_normal = False
operator.report = lambda *_args: None
@@ -187,11 +184,6 @@ class CutoutOperatorsTest(BlenderTestCase):
"configured_max_ai_input_size",
return_value=2048,
),
patch.object(
self.cutout_main,
"configured_max_cutout_mesh_resolution",
return_value=1024,
),
patch.object(
self.cutout_main,
"invoke_ai_setup_if_needed",
@@ -241,7 +233,7 @@ class CutoutOperatorsTest(BlenderTestCase):
{"points": [[1, 1], [7, 1], [7, 3], [1, 3]]}
),
shape="FLAT",
point_spacing=32,
edge_length=0.1,
generate_normal=False,
report=lambda level, message: reports.append((level, message)),
)
@@ -377,7 +369,7 @@ class CutoutOperatorsTest(BlenderTestCase):
layout.events,
[
("prop", "cutout_gesture", True),
("prop", "cutout_mesh_detail", True),
("prop", "cutout_edge_length", True),
("prop", "cutout_fine_outline", True),
("prop", "cutout_alpha_threshold", True),
setup,
@@ -413,7 +405,8 @@ class CutoutOperatorsTest(BlenderTestCase):
operator.color_path = __file__
operator.shape = "FLAT"
operator.gesture = "POLYLINE"
operator.point_spacing = 32
operator.report = lambda *_args: None
operator.edge_length = 0.1
operator.generate_normal = True
operator._selection_mask = selection_mask
result = SimpleNamespace(value={}, file=lambda _key: Path(__file__))