Add soft min and max constraints for frame resolution and cutout edge length properties

This commit is contained in:
2026-09-13 11:22:20 +08:00
parent 18799e8828
commit 2a00ed0ee6
21 changed files with 3834 additions and 1293 deletions

View File

@@ -175,7 +175,7 @@ def test_cutout_cleanup_value_scales_the_ui_without_changing_node_area():
def test_cutout_domain_adapts_boundary_spacing_for_a_small_valid_selection():
components = ((((2046, 2046), (2050, 2046), (2050, 2050), (2046, 2050)),),)
domain = cutout_geometry.cutout_domain(
domain = quality_domain(
SelectionContours(components, (4096, 4096)),
(-1.0, 1.0, -1.0, 1.0),
0.5,
@@ -189,7 +189,7 @@ def test_cutout_domain_adapts_boundary_spacing_for_a_small_valid_selection():
def test_cutout_domain_builds_a_full_image_at_minimum_detail():
components = ((((0, 0), (4096, 0), (4096, 4096), (0, 4096)),),)
domain = cutout_geometry.cutout_domain(
domain = quality_domain(
SelectionContours(components, (4096, 4096)),
(-1.0, 1.0, -1.0, 1.0),
0.5,
@@ -203,7 +203,7 @@ def test_cutout_domain_builds_a_full_image_at_minimum_detail():
def test_cutout_domain_centers_vertices_on_crop_bounds():
components = ((((0, 0), (100, 0), (100, 50), (0, 50)),),)
vertices, _faces, uv, _boundary, _planar, _profile = cutout_geometry.cutout_domain(
vertices, _faces, uv, _boundary, _planar, _profile = quality_domain(
SelectionContours(components, (100, 50)),
(2.0, 6.0, -3.0, 1.0),
0.5,
@@ -224,7 +224,7 @@ def test_cutout_domain_keeps_overlapping_selection_components_disconnected():
),
(((0, 20), (40, 20), (40, 50), (0, 50)),),
)
domain = cutout_geometry.cutout_domain(
domain = quality_domain(
SelectionContours(components, (120, 80)),
(0.0, 1.0, 0.0, 1.0),
0.025,
@@ -286,3 +286,19 @@ class CutoutContourTest(unittest.TestCase):
return float(np.std(points[selected, 1] - points[selected, 0]))
self.assertLess(diagonal_noise(smooth), 0.05)
def quality_domain(selection, bounds, spacing, metric):
from anyimage.operators.cutout_tool import mesh
ps, fs, cs = [], [], []
offset = 0
width, height = selection.image_size
pixel_scale = max((bounds[1]-bounds[0])/width, (bounds[3]-bounds[2])/height)
for component in selection.components:
contours = [np.array(c, dtype=float) for c in component]
p, f = mesh.triangulate(contours, spacing/pixel_scale)
p, f = mesh.support_mesh(p, f)
ps.append(p);fs.append(f+offset)
cs.append((offset, offset+len(p), f, contours[0]));offset += len(p)
p, f = np.concatenate(ps), np.concatenate(fs)
return cutout_geometry.cutout_domain((p, f, cutout_geometry.boundary_vertices_from_faces(len(p), f), cs, selection.image_size), bounds, metric)