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:
@@ -51,7 +51,7 @@ def test_shader_editor_pin_and_shared_group_target(shader_editor, tmp_path):
|
||||
source = nested.image
|
||||
target = ImageEditTarget.capture(context)
|
||||
write_result(tmp_path)
|
||||
target.apply(tmp_path)
|
||||
target.apply(tmp_path / "foreground.png")
|
||||
assert nested.image == source
|
||||
assert tuple(source.size) == (8, 6)
|
||||
assert second_instance.node_tree.nodes[nested.name].image == source
|
||||
@@ -98,23 +98,23 @@ def test_texture_poll_applies_busy_and_size_limits(texture, busy, limit, expecte
|
||||
assert remove_background.RemoveImageBackground.poll(context) == (not busy)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("operation,prefix", [(upscale.UpscaleImage, "upscale."), (remove_background.RunBackgroundRemoval, "image.")])
|
||||
@pytest.mark.parametrize("operation,filename", [(upscale.UpscaleImage, "upscale.png"), (remove_background.RunBackgroundRemoval, "foreground.png")])
|
||||
@pytest.mark.parametrize("shared", [False, True])
|
||||
def test_texture_action_undo_redo_restores_image_and_binding(texture, tmp_path, operation, prefix, shared):
|
||||
def test_texture_action_undo_redo_restores_image_and_binding(texture, tmp_path, operation, filename, shared):
|
||||
source_name = texture.image.name
|
||||
source_pixels = images.image_pixels(texture.image)
|
||||
if shared:
|
||||
other = texture.id_data.nodes.new("ShaderNodeTexImage")
|
||||
other.image = texture.image
|
||||
other.name = "Other texture"
|
||||
write_result(tmp_path, prefix)
|
||||
write_result(tmp_path, filename)
|
||||
|
||||
def execute(operator, context):
|
||||
node = bpy.data.materials["Texture material"].node_tree.nodes["Source texture"]
|
||||
operator._image_target = ImageEditTarget.capture(texture_context(node))
|
||||
if operation == upscale.UpscaleImage:
|
||||
operator.model = "HAT_GAN_X4_SHARPER"
|
||||
operator.response(context, SimpleNamespace(directory=tmp_path))
|
||||
operator.response(context, SimpleNamespace(file=lambda key: tmp_path / f"{key}.png"))
|
||||
return {"FINISHED"}
|
||||
|
||||
bpy.context.preferences.edit.use_global_undo = True
|
||||
@@ -145,22 +145,23 @@ def test_texture_action_undo_redo_restores_image_and_binding(texture, tmp_path,
|
||||
bpy.utils.unregister_class(operation)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("operation,module,prefix", [
|
||||
(upscale.UpscaleImage, upscale, "upscale."),
|
||||
(remove_background.RunBackgroundRemoval, remove_background, "image."),
|
||||
@pytest.mark.parametrize("operation,module,filename", [
|
||||
(upscale.UpscaleImage, upscale, "upscale.png"),
|
||||
(remove_background.RunBackgroundRemoval, remove_background, "foreground.png"),
|
||||
])
|
||||
@pytest.mark.parametrize("outcome", ["succeeded", "cancelled", "failed", "invalid_target"])
|
||||
def test_texture_job_request_and_completion(texture, tmp_path, operation, module, prefix, outcome):
|
||||
def test_texture_job_request_and_completion(texture, tmp_path, operation, module, filename, outcome):
|
||||
context = texture_context(texture)
|
||||
context.window = object()
|
||||
context.window_manager = SimpleNamespace(
|
||||
progress_begin=Mock(), progress_end=Mock(), event_timer_add=Mock(return_value=object()),
|
||||
event_timer_remove=Mock(), modal_handler_add=Mock(),
|
||||
)
|
||||
write_result(tmp_path, prefix)
|
||||
write_result(tmp_path, filename)
|
||||
controller = SimpleNamespace(
|
||||
submit=Mock(return_value={"job_id": "texture-job", "directory": str(tmp_path)}),
|
||||
status=Mock(return_value={"state": "failed" if outcome == "invalid_target" else outcome}),
|
||||
status=Mock(return_value={"state": "failed" if outcome == "invalid_target" else outcome,
|
||||
"result": {Path(filename).stem: filename}}),
|
||||
mark_job_complete=Mock(), cancel=Mock(),
|
||||
)
|
||||
original_pixels = images.image_pixels(texture.image)
|
||||
@@ -183,7 +184,7 @@ def test_texture_job_request_and_completion(texture, tmp_path, operation, module
|
||||
assert not job.start_thread.is_alive()
|
||||
kind, parameters = controller.submit.call_args.args
|
||||
assert kind == operation.job_type
|
||||
assert parameters["start_frame"] == 1
|
||||
assert "start_frame" not in parameters and "video_frames" not in parameters
|
||||
assert parameters["device"] == "cpu"
|
||||
assert parameters["model"] == ("HAT_GAN_X4_SHARPER" if operation == upscale.UpscaleImage else "BIREFNET_LITE")
|
||||
input_path = operator.input_path
|
||||
@@ -193,7 +194,7 @@ def test_texture_job_request_and_completion(texture, tmp_path, operation, module
|
||||
texture.id_data.nodes.active = other
|
||||
if outcome == "invalid_target":
|
||||
texture.image = None
|
||||
controller.status.return_value = {"state": "succeeded"}
|
||||
controller.status.return_value = {"state": "succeeded", "result": {Path(filename).stem: filename}}
|
||||
bpy.ops.ed.undo_push(message="Before asynchronous texture result")
|
||||
result = operator.modal(context, SimpleNamespace(type="TIMER"))
|
||||
assert result == ({"FINISHED"} if outcome == "succeeded" else {"CANCELLED"})
|
||||
|
||||
Reference in New Issue
Block a user