Refactor depth-related tests and improve parameter handling in image cutout symmetry
This commit is contained in:
@@ -49,12 +49,15 @@ def evaluated(obj):
|
||||
result.to_mesh_clear()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dome", [1.0, 50.0])
|
||||
@pytest.mark.parametrize("subdivide", [0, 4])
|
||||
def test_quad_sphere_topology_and_radial_endpoints(subdivide):
|
||||
def test_quad_sphere_topology_and_radial_endpoints(subdivide, dome):
|
||||
obj, set_value = panorama(subdivide=subdivide)
|
||||
set_value("Dome Radius", dome)
|
||||
inputs = [s for s in obj.modifiers[0].node_group.interface.items_tree if s.item_type == "SOCKET" and s.in_out == "INPUT"]
|
||||
assert [s.name for s in inputs if s.socket_type == "NodeSocketImage"] == ["Depth Image"]
|
||||
for scale, radius in ((0, 1), (0.5, 2), (1, 3)):
|
||||
# Depth Scale blends between the dome sphere and the estimated distance.
|
||||
for scale, radius in ((0, dome), (0.5, dome + 0.5 * (3 - dome)), (1, 3)):
|
||||
set_value("Depth Scale", scale)
|
||||
points, faces, uv = evaluated(obj)
|
||||
assert len(faces) == 6 * 4 ** subdivide
|
||||
@@ -68,7 +71,7 @@ def test_quad_sphere_topology_and_radial_endpoints(subdivide):
|
||||
assert np.max(np.ptp(uv.reshape(-1, 4, 2)[..., 0], axis=1)) <= 0.5 + 1e-5
|
||||
|
||||
|
||||
def test_depth_alpha_culls_faces_without_double_multiplication():
|
||||
def test_mask_threshold_culls_faces():
|
||||
obj, set_value = panorama(alpha=0.5)
|
||||
assert not len(evaluated(obj)[0])
|
||||
set_value("Depth Mask", False)
|
||||
@@ -112,39 +115,45 @@ def test_linear_depth_reconstructs_flat_floor_without_sampling_rings():
|
||||
assert np.max(abs(error)) < 0.004
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sky_alpha", [0, 1])
|
||||
def test_invalid_distance_removes_faces_between_valid_and_invalid_regions(sky_alpha):
|
||||
depth = np.full((64, 128), 3.0)
|
||||
depth[:, 64:] = 1e-7
|
||||
def test_masked_area_falls_back_to_the_dome_radius():
|
||||
"""The mask decides validity; what Depth Mask keeps lands on the dome sphere."""
|
||||
alpha = np.ones((64, 128))
|
||||
alpha[:, 64:] = sky_alpha
|
||||
alpha[:, 64:] = 0
|
||||
depth = np.where(alpha, 3.0, 1e-7)
|
||||
obj, set_value = panorama(depth, alpha, subdivide=4)
|
||||
points, original_faces, _ = evaluated(obj)
|
||||
assert np.linalg.norm(points, axis=1).min() > 1
|
||||
assert np.linalg.norm(points, axis=1).max() < 3.01
|
||||
set_value("Invalid Distance", 250)
|
||||
assert evaluated(obj)[1] == original_faces
|
||||
points, faces, _ = evaluated(obj)
|
||||
# Depth Mask removes the masked half; the cut ring keeps its face depth.
|
||||
assert len(faces) == 768
|
||||
np.testing.assert_allclose(np.linalg.norm(points, axis=1), 3, atol=1e-3)
|
||||
set_value("Depth Mask", False)
|
||||
for background in (100, 250):
|
||||
set_value("Invalid Distance", background)
|
||||
points, faces, _ = evaluated(obj)
|
||||
radii = np.linalg.norm(points, axis=1)
|
||||
assert np.any(np.isclose(radii, background))
|
||||
assert np.any(np.isclose(radii, 3))
|
||||
assert len(original_faces) < len(faces) < 6 * 4 ** 4
|
||||
assert all(np.all(radii[list(face)] > 10) or np.all(radii[list(face)] < 10) for face in faces)
|
||||
for dome in (10.0, 50.0):
|
||||
set_value("Dome Radius", dome)
|
||||
radii = np.linalg.norm(evaluated(obj)[0], axis=1)
|
||||
on_dome = np.isclose(radii, dome, atol=1e-3)
|
||||
assert on_dome.any() and np.isclose(radii, 3, atol=1e-3).any()
|
||||
assert np.all(on_dome | np.isclose(radii, 3, atol=1e-3))
|
||||
set_value("Dome Radius", 50.0)
|
||||
set_value("Depth Scale", 0)
|
||||
np.testing.assert_allclose(np.linalg.norm(evaluated(obj)[0], axis=1), 1, atol=1e-5)
|
||||
np.testing.assert_allclose(np.linalg.norm(evaluated(obj)[0], axis=1), 50, atol=1e-3)
|
||||
set_value("Depth Mask", True)
|
||||
assert len(evaluated(obj)[1]) == 768
|
||||
np.testing.assert_allclose(np.linalg.norm(evaluated(obj)[0], axis=1), 50, atol=1e-3)
|
||||
|
||||
|
||||
def test_controls_and_material_slot_inheritance():
|
||||
obj, set_value = panorama()
|
||||
group = obj.modifiers[0].node_group
|
||||
inputs = {s.name: s for s in group.interface.items_tree if s.item_type == "SOCKET" and s.in_out == "INPUT"}
|
||||
names = [item.name for item in group.interface.items_tree
|
||||
if item.item_type == "SOCKET" and item.in_out == "INPUT"]
|
||||
assert names[names.index("Subdivide"):names.index("Depth Scale") + 1] == [
|
||||
"Subdivide", "Dome Radius", "Depth Scale",
|
||||
]
|
||||
assert inputs["Dome Radius"].parent == inputs["Subdivide"].parent
|
||||
assert inputs["Dome Radius"].default_value == 50
|
||||
assert (inputs["Dome Radius"].min_value, inputs["Dome Radius"].max_value) == (1, 100)
|
||||
assert inputs["Dome Radius"].subtype == "DISTANCE"
|
||||
assert inputs["Mask Threshold"].parent.name == "Options"
|
||||
assert inputs["Invalid Distance"].parent.name == "Options"
|
||||
assert inputs["Invalid Distance"].default_value == 100
|
||||
assert inputs["Invalid Distance"].subtype == "DISTANCE"
|
||||
assert inputs["Boundary Smooth"].parent.name == "Options"
|
||||
assert "Smooth Weight" not in inputs
|
||||
assert inputs["Depth Mask"].parent == inputs["Subdivide"].parent
|
||||
|
||||
Reference in New Issue
Block a user