Add tests for foreground preservation and refactor geometry node asset

- Implement test to ensure foreground preserves source RGB and Ben2 alpha in WorkerTest.
- Remove outdated tests related to background distance and original background depth.
- Update geometry node asset to reflect new naming conventions and structure.
- Introduce validation for depth plane asset, ensuring correct input/output configurations and attribute handling.
- Adjust confidence and edge parameters in geometry node asset to support a wider range of values.
This commit is contained in:
2026-08-11 23:25:51 +08:00
parent 07d836d9ad
commit 7cd5681a8b
15 changed files with 1296 additions and 660 deletions

View File

@@ -231,9 +231,30 @@ class AddonTest(unittest.TestCase):
self.assertTrue(all(name.startswith("o_") for name in names))
self.assertTrue(image_mesh.node_asset_path().is_file())
self.assertEqual(image_mesh.NODE_GROUP_NAME, "O Refine DA3 Mesh")
self.assertEqual(image_mesh.NODE_GROUP_NAME, "O Refine DA3 Surface")
self.assertEqual(image_mesh.NODE_ASSET_NAME, "O_SnapForm.blend")
def test_depth_plane_uses_bundled_nodes_and_material_attributes(self):
image_depth = self.addon.image_depth
self.assertTrue(image_depth.node_asset_path().is_file())
self.assertEqual(
image_depth.DEPTH_PLANE_NODE_GROUP_NAME,
"O DA3 Depth Plane",
)
self.assertEqual(
image_depth.REMOVE_BACKGROUND_ATTRIBUTE,
"o_remove_background",
)
self.assertEqual(
image_depth.MATERIAL_DISPLACEMENT_ATTRIBUTE,
"o_material_displacement",
)
self.assertEqual(
image_depth.BACKGROUND_DEPTH_ATTRIBUTE,
"o_background_depth",
)
def test_image_mesh_material_depth_scale_matches_fitted_geometry(self):
mesh_object = SimpleNamespace(scale=SimpleNamespace(z=-2.0))
@@ -315,6 +336,7 @@ class AddonTest(unittest.TestCase):
(-0.25, -0.75),
)
self.assertEqual(result_image.name, "img.foreground")
self.assertEqual(result_image.alpha_mode, "CHANNEL_PACKED")
self.assertEqual(pack_calls, [True])
self.assertEqual(remove_calls, [])
self.assertEqual(
@@ -365,6 +387,7 @@ class AddonTest(unittest.TestCase):
self.assertIs(source_object.data, original_image)
self.assertFalse(original_image.use_fake_user)
self.assertEqual(result_image.name, "img.foreground")
self.assertEqual(result_image.alpha_mode, "CHANNEL_PACKED")
self.assertEqual(pack_calls, [True])
def test_sequence_background_result_preserves_empty_image_start(self):
@@ -408,6 +431,7 @@ class AddonTest(unittest.TestCase):
self.assertIs(created, result_image)
self.assertIs(source_object.data, result_image)
self.assertEqual(result_image.alpha_mode, "CHANNEL_PACKED")
self.assertEqual(image_user.frame_start, 4)
self.assertEqual(image_user.frame_duration, 2)
self.assertEqual(image_user.frame_offset, 0)
@@ -456,10 +480,7 @@ class AddonTest(unittest.TestCase):
def test_original_depth_background_starts_independent_job(self):
operator = self.addon.ConvertImageToDepthPlane()
operator.snapform_depth_source = "ORIGINAL"
operator.snapform_background_depth_distance = 2.0
operator.snapform_displacement_via = "MODIFIER"
operator.snapform_unshaded = False
operator.snapform_subdivision_level = 5
operator.snapform_delete_original = False
source_object = SimpleNamespace(
name="Reference",
@@ -486,15 +507,12 @@ class AddonTest(unittest.TestCase):
self.assertEqual(result, {"FINISHED"})
self.assertEqual(calls[0]["job_type"], "ORIGINAL_BACKGROUND")
self.assertEqual(calls[0]["snapform_background_depth_distance"], 2.0)
self.assertNotIn("snapform_background_depth_distance", calls[0])
def test_original_depth_animation_extracts_frames_without_background(self):
def test_original_depth_animation_extracts_frames_and_background(self):
operator = self.addon.ConvertImageToDepthPlane()
operator.snapform_depth_source = "ORIGINAL"
operator.snapform_background_depth_distance = 0.0
operator.snapform_displacement_via = "MODIFIER"
operator.snapform_unshaded = False
operator.snapform_subdivision_level = 5
operator.snapform_delete_original = False
source_object = SimpleNamespace(
name="Reference",
@@ -528,7 +546,7 @@ class AddonTest(unittest.TestCase):
self.assertEqual(result, {"FINISHED"})
self.assertEqual(scene.snapform_settings.video_frames, 97)
self.assertEqual(calls[0]["job_type"], "ORIGINAL_FRAMES")
self.assertEqual(calls[0]["job_type"], "ORIGINAL_BACKGROUND")
self.assertEqual(calls[0]["snapform_input_path"], str(input_path))
self.assertEqual(calls[0]["snapform_source_object_name"], "Reference")
self.assertFalse(calls[0]["snapform_delete_input"])
@@ -552,27 +570,15 @@ class AddonTest(unittest.TestCase):
self.assertFalse(
operator.__annotations__["snapform_unshaded"]["default"]
)
background_offset = operator.__annotations__[
"snapform_background_depth_distance"
]
self.assertEqual(background_offset["default"], 0.0)
self.assertEqual(background_offset["min"], 0.0)
self.assertEqual(
operator.__annotations__["snapform_subdivision_level"]["default"],
5,
)
self.assertEqual(
set(operator.__annotations__),
{
"snapform_depth_source",
"snapform_displacement_via",
"snapform_unshaded",
"snapform_background_depth_distance",
"snapform_model",
"snapform_use_ray_pose",
"snapform_process_res_factor",
"snapform_delete_original",
"snapform_subdivision_level",
},
)
depth_sources = operator.__annotations__["snapform_depth_source"]
@@ -583,15 +589,6 @@ class AddonTest(unittest.TestCase):
)
self.assertEqual(depth_sources["items"][0][1], "AI Generated")
self.assertEqual(depth_sources["name"], "Depth from")
displacement_via = operator.__annotations__[
"snapform_displacement_via"
]
self.assertEqual(displacement_via["default"], "MODIFIER")
self.assertEqual(displacement_via["name"], "Displace via")
self.assertEqual(
[item[0] for item in displacement_via["items"]],
["MODIFIER", "MATERIAL"],
)
self.assertEqual(
operator.__annotations__["snapform_unshaded"]["name"],
"Unshaded",
@@ -674,7 +671,7 @@ class AddonTest(unittest.TestCase):
self.assertEqual(result, {"FINISHED"})
self.assertEqual(scene.snapform_settings.video_frames, 24)
def test_conversion_execute_uses_background_offset_frame_range(self):
def test_conversion_execute_uses_background_mask_frame_range(self):
source_object = SimpleNamespace(
name="Reference",
data=SimpleNamespace(
@@ -694,10 +691,7 @@ class AddonTest(unittest.TestCase):
operator.snapform_model = "BASE"
operator.snapform_use_ray_pose = True
operator.snapform_process_res_factor = 1.0
operator.snapform_displacement_via = "MODIFIER"
operator.snapform_unshaded = False
operator.snapform_background_depth_distance = 1.0
operator.snapform_subdivision_level = 5
operator.snapform_delete_original = False
calls = []
self.fake_bpy.ops = SimpleNamespace(
@@ -720,7 +714,8 @@ class AddonTest(unittest.TestCase):
self.assertEqual(result, {"FINISHED"})
self.assertEqual(scene.snapform_settings.video_frames, 24)
self.assertEqual(calls[0]["job_type"], "IMAGE_DEPTH")
self.assertEqual(calls[0]["snapform_background_depth_distance"], 1.0)
self.assertTrue(calls[0]["snapform_remove_background"])
self.assertNotIn("snapform_background_depth_distance", calls[0])
def test_conversion_dialog_only_lists_installed_models(self):
items_callback = self.addon.ConvertImageToDepthPlane.__annotations__[
@@ -823,10 +818,7 @@ class AddonTest(unittest.TestCase):
operator.snapform_model = "GIANT_1_1"
operator.snapform_use_ray_pose = True
operator.snapform_process_res_factor = 0.5
operator.snapform_displacement_via = "MATERIAL"
operator.snapform_unshaded = True
operator.snapform_background_depth_distance = 2.5
operator.snapform_subdivision_level = 5
operator.snapform_delete_original = True
image = SimpleNamespace(
name="img.png",
@@ -865,12 +857,8 @@ class AddonTest(unittest.TestCase):
self.assertEqual(calls[0]["snapform_input_path"], str(packed_path))
self.assertEqual(calls[0]["snapform_process_res"], 960)
self.assertEqual(calls[0]["snapform_model_key"], "GIANT_1_1")
self.assertEqual(
calls[0]["snapform_displacement_via"],
"MATERIAL",
)
self.assertTrue(calls[0]["snapform_remove_background"])
self.assertTrue(calls[0]["snapform_unshaded"])
self.assertEqual(calls[0]["snapform_background_depth_distance"], 2.5)
self.assertEqual(calls[0]["snapform_depth_data_name"], "img.depth")
self.assertTrue(calls[0]["snapform_delete_input"])
self.assertEqual(
@@ -1070,7 +1058,7 @@ class AddonTest(unittest.TestCase):
snapform_ray_pose,
)
def test_image_depth_background_option_requires_ben2(self):
def test_image_depth_background_mask_requires_ben2(self):
settings = SimpleNamespace(
input_path="debug-input.png",
export_format="mini_npz",
@@ -1082,7 +1070,7 @@ class AddonTest(unittest.TestCase):
operator.snapform_model_key = "BASE"
operator.snapform_use_ray_pose = True
operator.snapform_process_res = 1024
operator.snapform_background_depth_distance = 1.0
operator.snapform_remove_background = True
with TemporaryDirectory() as directory:
input_path = Path(directory) / "input.png"
@@ -1140,16 +1128,15 @@ class AddonTest(unittest.TestCase):
Path("status.json"),
Path("result"),
remove_background=True,
background_depth_distance=2.5,
)
self.assertEqual(
request.payload["parameters"]["remove_background_model_dir"],
str(Path("ben2_base")),
)
self.assertEqual(
request.payload["parameters"]["background_depth_distance"],
2.5,
self.assertNotIn(
"background_depth_distance",
request.payload["parameters"],
)
def test_host_busy_snapshot_is_released_for_completed_local_job(self):
@@ -1174,12 +1161,9 @@ class AddonTest(unittest.TestCase):
operator.snapform_source_object_name = "Reference"
operator.snapform_depth_data_name = "img.depth"
operator.snapform_process_res = 1024
operator.snapform_subdivision_level = 5
operator.snapform_delete_source = False
operator.snapform_delete_input = False
operator.snapform_displacement_via = "MODIFIER"
operator.snapform_unshaded = False
operator.snapform_background_depth_distance = 0.0
started = threading.Event()
release = threading.Event()
@@ -1368,13 +1352,12 @@ class AddonTest(unittest.TestCase):
Path("result"),
"BEN2_BASE",
start_frame=70,
background_depth_distance=3.0,
)
parameters = request.payload["parameters"]
self.assertEqual(parameters["video_frames"], 24)
self.assertEqual(parameters["start_frame"], 70)
self.assertEqual(parameters["background_depth_distance"], 3.0)
self.assertNotIn("background_depth_distance", parameters)
def test_extract_frames_request_passes_frame_range(self):
runtime = importlib.import_module("snapform.runtime")
@@ -1683,7 +1666,7 @@ class AddonTest(unittest.TestCase):
"Gaussian Splats (PLY)",
"Depth Preview (Images)",
"Depth Data (NPZ)",
"Textured Mesh (GLB)",
"Textured Surface (GLB)",
],
)
@@ -1826,7 +1809,7 @@ class AddonTest(unittest.TestCase):
):
self.assertTrue(self.addon.RemoveImageBackground.poll(context))
def test_convert_to_depth_plane_poll_requires_da3_model(self):
def test_convert_to_depth_plane_poll_requires_da3_and_ben2_models(self):
context = SimpleNamespace(
object=SimpleNamespace(
type="EMPTY",
@@ -1841,7 +1824,7 @@ class AddonTest(unittest.TestCase):
), patch.object(
self.addon.runtime,
"model_ready",
side_effect=lambda key: key == "BASE",
side_effect=lambda key: key in {"BASE", "BEN2_BASE"},
):
self.assertTrue(
self.addon.ConvertImageToDepthPlane.poll(context)
@@ -2321,7 +2304,7 @@ class AddonTest(unittest.TestCase):
self.assertFalse(calls[0][1]["snapform_delete_source"])
self.assertEqual(
calls[0][1]["snapform_depth_npz_path"],
str(Path("result") / "original-depth.npz"),
"",
)
self.assertEqual(
calls[1],