Add new functionality for image rectification and depth metadata handling

- Implemented a preview tool for rectifying images with interactive aspect controls in `preview.py`.
- Added tests for depth metadata loading to ensure consistent schema usage in `test_depth_metadata.py`.
- Developed comprehensive tests for cutout calibration processes in `test_cutout_calibration.py`, including stability checks and depth calibration.
- Created tests for frame compositing operations in `test_frame_compositing.py`, ensuring correct handling of depth and transparency.
- Introduced material slot inheritance functionality in `material_slots.py` to manage geometry material assignments.
- Built shared shader nodes for material processing in `shader.py`, including roughness and bump mapping setups.
This commit is contained in:
2026-09-12 19:20:06 +08:00
parent e8268504c2
commit 938d95db0f
175 changed files with 3812 additions and 6864 deletions

View File

@@ -35,18 +35,6 @@ def color_texture(result):
return next(node.image for node in result.node_tree.nodes if node.type == "TEX_IMAGE")
def test_adaptation_preference_defaults_and_reads_current_value():
with patch.object(preferences, "addon_preferences", return_value=None):
assert preferences.configured_material_view_adaptation()
with patch.object(preferences, "addon_preferences", return_value=SimpleNamespace()):
assert preferences.configured_material_view_adaptation()
settings = SimpleNamespace(adapt_material_to_view_transform=False)
with patch.object(preferences, "addon_preferences", return_value=settings):
assert not preferences.configured_material_view_adaptation()
settings.adapt_material_to_view_transform = True
assert preferences.configured_material_view_adaptation()
@pytest.mark.parametrize("enabled", [False, True])
@pytest.mark.parametrize("view,space", [*material.VIEW_TRANSFORM_COLOR_SPACES, ("Standard", "sRGB"), ("Unknown", "sRGB")])
def test_color_space_and_alpha_follow_preference(color_data, enabled, view, space):
@@ -85,11 +73,11 @@ def test_material_pixels_survive_pack_and_library_reload(color_data, tmp_path, e
source.pixels.foreach_set((expected.astype(np.float32) / 255).ravel())
else:
source = bpy.data.images.new("Material pixels", width=2, height=1, alpha=True, float_buffer=kind == "float")
source.alpha_mode = "PREMUL"
source.pixels.foreach_set((expected.astype(np.float32) / 255).ravel())
if kind == "packed":
source.pack()
source.reload()
images.configure_color_alpha(source)
before = images.image_pixels(source)
owner = bpy.data.objects.new("Color source owner", None)
owner.empty_display_type = "IMAGE"
@@ -175,51 +163,13 @@ def test_material_configures_the_image_selected_by_its_caller(color_data, entry,
def test_edit_results_preserve_source_alpha_with_adaptation_enabled(color_data, tmp_path):
source = bpy.data.images.new("Editing source", width=1, height=1, alpha=True)
rgba = np.array([0.2, 0.4, 0.8, 0.25], dtype=np.float32)
Image.fromarray(np.array([[[51, 102, 204, 64]]], dtype=np.uint8)).save(tmp_path / "image.0001.png")
Image.fromarray(np.array([[[51, 102, 204, 64]]], dtype=np.uint8)).save(tmp_path / "foreground.png")
with patch.object(preferences, "addon_preferences", return_value=SimpleNamespace(adapt_material_to_view_transform=True)):
edited = images.create_image_edit_result(source, rgba, (1, 1))
loaded = images.load_image_edit_result(source, tmp_path)
loaded = images.load_image_edit_result(source, tmp_path / "foreground.png")
for result in (edited, loaded):
assert result.colorspace_settings.name == "sRGB"
assert result.alpha_mode == source.alpha_mode
np.testing.assert_allclose(images.image_pixels(result), rgba, atol=1 / 255)
assert source.colorspace_settings.name == "sRGB"
assert source.alpha_mode == "STRAIGHT"
@pytest.mark.parametrize("supported", [{"sRGB", "Non-Color"}, {"Non-Color"}])
def test_unavailable_color_space_falls_back_or_preserves_original(supported):
class ColorSpace:
value = "Non-Color"
@property
def name(self):
return self.value
@name.setter
def name(self, value):
if value not in supported:
raise TypeError("Unsupported color space")
self.value = value
image = SimpleNamespace(colorspace_settings=ColorSpace(), users=0, use_fake_user=False, alpha_mode="STRAIGHT")
with patch.object(material, "configured_material_view_adaptation", return_value=True):
if "sRGB" in supported:
result = material.configure_material_color_image(image, view_scene("AgX"))
assert result.colorspace_settings.name == "sRGB"
assert result.alpha_mode == "PREMUL"
else:
with pytest.raises(RuntimeError, match="material color space"):
material.configure_material_color_image(image, view_scene("AgX"))
assert image.colorspace_settings.name == "Non-Color"
assert image.alpha_mode == "STRAIGHT"
def test_missing_scene_uses_srgb(color_data):
image = bpy.data.images.new("Missing scene", width=1, height=1)
with patch.object(material, "bpy", SimpleNamespace(context=SimpleNamespace(scene=None))), patch.object(
material, "configured_material_view_adaptation", return_value=True
):
result = material.configure_material_color_image(image)
assert result.colorspace_settings.name == "sRGB"
assert result.alpha_mode == "PREMUL"