diff --git a/README.md b/README.md index cd23f57..6f17e55 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,15 @@ - Supports filename tokens including `%input%`, `%input2%`, `%date:yyyy-MM-dd%`, `%counter%`, `%width%`, `%height%`, and `%batch_num%`. - `Dumas H3 Plan Attach Scene Images` - - Inputs: `plan`, `scene_index`, optional `image1`..`image6` + - Inputs: `plan`, `scene_index`, optional `image1`..`image7` - Outputs: `plan`, `connected_images` - - Attaches up to six optional image sockets to one MiniMax H3 plan scene while keeping the plan JSON-serializable for the upstream archive system. - - Chain one node per scene that needs its own six-image bundle. + - Attaches up to seven optional image sockets to one MiniMax H3 plan scene while keeping the plan JSON-serializable for the upstream archive system. + - Chain one node per scene that needs its own seven-image bundle. - `Dumas H3 Plan Extract Scene Images` - Inputs: `plan`, `scene_index` - - Outputs: `plan`, `image1`..`image6`, `connected_images` - - Reads back the six optional images for a selected MiniMax H3 plan scene, for example by connecting the current `clip_index`. + - Outputs: `plan`, `image1`..`image7`, `connected_images` + - Reads back the seven optional images for a selected MiniMax H3 plan scene, for example by connecting the current `clip_index`. - `Dumas JSON String to Object` - Input: `json_string` diff --git a/dumas_image_nodes.py b/dumas_image_nodes.py index 8eb9358..426142b 100644 --- a/dumas_image_nodes.py +++ b/dumas_image_nodes.py @@ -172,8 +172,16 @@ def _h3_plan_binding_entry(plan): return token, counts -def _scene_images_tuple(image1=None, image2=None, image3=None, image4=None, image5=None, image6=None): - return (image1, image2, image3, image4, image5, image6) +def _scene_images_tuple( + image1=None, + image2=None, + image3=None, + image4=None, + image5=None, + image6=None, + image7=None, +): + return (image1, image2, image3, image4, image5, image6, image7) def _connected_image_count(images): @@ -489,7 +497,7 @@ class DumasSaveImageNode: class DumasH3PlanAttachSceneImagesNode: DESCRIPTION = ( - "Attach up to six optional IMAGE sockets to one H3 Chain Plan scene " + "Attach up to seven optional IMAGE sockets to one H3 Chain Plan scene " "without breaking the upstream plan archive format. Chain multiple " "copies of this node to bind different scene indexes." ) @@ -501,7 +509,7 @@ class DumasH3PlanAttachSceneImagesNode: @classmethod def INPUT_TYPES(cls): optional = {} - for slot in range(1, 7): + for slot in range(1, 8): optional[f"image{slot}"] = ( "IMAGE", { @@ -530,7 +538,7 @@ class DumasH3PlanAttachSceneImagesNode: "step": 1, "tooltip": ( "1-based scene index inside the H3 plan. Use one node per " - "scene that needs up to six image sockets." + "scene that needs up to seven image sockets." ), }, ), @@ -548,10 +556,11 @@ class DumasH3PlanAttachSceneImagesNode: image4=None, image5=None, image6=None, + image7=None, ): updated_plan = _clone_h3_plan(plan) scene_index = _normalize_h3_scene_index(updated_plan, scene_index) - images = _scene_images_tuple(image1, image2, image3, image4, image5, image6) + images = _scene_images_tuple(image1, image2, image3, image4, image5, image6, image7) connected_count = _connected_image_count(images) token, scene_counts = _h3_plan_binding_entry(updated_plan) @@ -582,11 +591,21 @@ class DumasH3PlanAttachSceneImagesNode: class DumasH3PlanExtractSceneImagesNode: DESCRIPTION = ( - "Read back the six optional image bindings for one H3 Chain Plan scene. " + "Read back the seven optional image bindings for one H3 Chain Plan scene. " "Connect clip_index or another scene selector to recover the matching " "scene images downstream." ) - RETURN_TYPES = (_H3_PLAN_TYPE, "IMAGE", "IMAGE", "IMAGE", "IMAGE", "IMAGE", "IMAGE", "INT") + RETURN_TYPES = ( + _H3_PLAN_TYPE, + "IMAGE", + "IMAGE", + "IMAGE", + "IMAGE", + "IMAGE", + "IMAGE", + "IMAGE", + "INT", + ) RETURN_NAMES = ( "plan", "image1", @@ -595,6 +614,7 @@ class DumasH3PlanExtractSceneImagesNode: "image4", "image5", "image6", + "image7", "connected_images", ) FUNCTION = "extract" @@ -633,11 +653,11 @@ class DumasH3PlanExtractSceneImagesNode: scene_index = _normalize_h3_scene_index(passthrough_plan, scene_index) token, _scene_counts = _h3_plan_binding_entry(passthrough_plan) if not token: - return (passthrough_plan, None, None, None, None, None, None, 0) + return (passthrough_plan, None, None, None, None, None, None, None, 0) registry = _H3_PLAN_IMAGE_BINDINGS.get(token) or {} _touch_plan_image_binding(token) - images = registry.get(int(scene_index)) or (None, None, None, None, None, None) + images = registry.get(int(scene_index)) or (None, None, None, None, None, None, None) return (passthrough_plan, *images, _connected_image_count(images)) diff --git a/tests/test_dumas_image_nodes.py b/tests/test_dumas_image_nodes.py index f459b6e..dc880c9 100644 --- a/tests/test_dumas_image_nodes.py +++ b/tests/test_dumas_image_nodes.py @@ -348,12 +348,14 @@ class DumasImageNodeTests(unittest.TestCase): plan = {"shots": [{"id": "one"}, {"id": "two"}]} image_1 = FakeTensorBatch() image_2 = FakeTensorBatch(width=12, height=9) + image_3 = FakeTensorBatch(width=8, height=8) plan_after_first, _connected = attach_node.attach(plan=plan, scene_index=1, image2=image_1) plan_after_second, _connected = attach_node.attach( plan=plan_after_first, scene_index=2, image6=image_2, + image7=image_3, ) scene1 = extract_node.extract(plan_after_second, 1) @@ -362,10 +364,11 @@ class DumasImageNodeTests(unittest.TestCase): self.assertIs(scene1[2], image_1) self.assertEqual(scene1[-1], 1) self.assertIs(scene2[6], image_2) - self.assertEqual(scene2[-1], 1) + self.assertIs(scene2[7], image_3) + self.assertEqual(scene2[-1], 2) self.assertEqual( plan_after_second["_dumas_scene_image_bindings"]["scene_counts"], - {"1": 1, "2": 1}, + {"1": 1, "2": 2}, ) def test_h3_plan_scene_images_metadata_is_json_serializable(self):