Add seventh H3 scene image slot
This commit is contained in:
@@ -17,15 +17,15 @@
|
|||||||
- Supports filename tokens including `%input%`, `%input2%`, `%date:yyyy-MM-dd%`, `%counter%`, `%width%`, `%height%`, and `%batch_num%`.
|
- Supports filename tokens including `%input%`, `%input2%`, `%date:yyyy-MM-dd%`, `%counter%`, `%width%`, `%height%`, and `%batch_num%`.
|
||||||
|
|
||||||
- `Dumas H3 Plan Attach Scene Images`
|
- `Dumas H3 Plan Attach Scene Images`
|
||||||
- Inputs: `plan`, `scene_index`, optional `image1`..`image6`
|
- Inputs: `plan`, `scene_index`, optional `image1`..`image7`
|
||||||
- Outputs: `plan`, `connected_images`
|
- 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.
|
- 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 six-image bundle.
|
- Chain one node per scene that needs its own seven-image bundle.
|
||||||
|
|
||||||
- `Dumas H3 Plan Extract Scene Images`
|
- `Dumas H3 Plan Extract Scene Images`
|
||||||
- Inputs: `plan`, `scene_index`
|
- Inputs: `plan`, `scene_index`
|
||||||
- Outputs: `plan`, `image1`..`image6`, `connected_images`
|
- Outputs: `plan`, `image1`..`image7`, `connected_images`
|
||||||
- Reads back the six optional images for a selected MiniMax H3 plan scene, for example by connecting the current `clip_index`.
|
- 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`
|
- `Dumas JSON String to Object`
|
||||||
- Input: `json_string`
|
- Input: `json_string`
|
||||||
|
|||||||
+30
-10
@@ -172,8 +172,16 @@ def _h3_plan_binding_entry(plan):
|
|||||||
return token, counts
|
return token, counts
|
||||||
|
|
||||||
|
|
||||||
def _scene_images_tuple(image1=None, image2=None, image3=None, image4=None, image5=None, image6=None):
|
def _scene_images_tuple(
|
||||||
return (image1, image2, image3, image4, image5, image6)
|
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):
|
def _connected_image_count(images):
|
||||||
@@ -489,7 +497,7 @@ class DumasSaveImageNode:
|
|||||||
|
|
||||||
class DumasH3PlanAttachSceneImagesNode:
|
class DumasH3PlanAttachSceneImagesNode:
|
||||||
DESCRIPTION = (
|
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 "
|
"without breaking the upstream plan archive format. Chain multiple "
|
||||||
"copies of this node to bind different scene indexes."
|
"copies of this node to bind different scene indexes."
|
||||||
)
|
)
|
||||||
@@ -501,7 +509,7 @@ class DumasH3PlanAttachSceneImagesNode:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def INPUT_TYPES(cls):
|
||||||
optional = {}
|
optional = {}
|
||||||
for slot in range(1, 7):
|
for slot in range(1, 8):
|
||||||
optional[f"image{slot}"] = (
|
optional[f"image{slot}"] = (
|
||||||
"IMAGE",
|
"IMAGE",
|
||||||
{
|
{
|
||||||
@@ -530,7 +538,7 @@ class DumasH3PlanAttachSceneImagesNode:
|
|||||||
"step": 1,
|
"step": 1,
|
||||||
"tooltip": (
|
"tooltip": (
|
||||||
"1-based scene index inside the H3 plan. Use one node per "
|
"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,
|
image4=None,
|
||||||
image5=None,
|
image5=None,
|
||||||
image6=None,
|
image6=None,
|
||||||
|
image7=None,
|
||||||
):
|
):
|
||||||
updated_plan = _clone_h3_plan(plan)
|
updated_plan = _clone_h3_plan(plan)
|
||||||
scene_index = _normalize_h3_scene_index(updated_plan, scene_index)
|
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)
|
connected_count = _connected_image_count(images)
|
||||||
|
|
||||||
token, scene_counts = _h3_plan_binding_entry(updated_plan)
|
token, scene_counts = _h3_plan_binding_entry(updated_plan)
|
||||||
@@ -582,11 +591,21 @@ class DumasH3PlanAttachSceneImagesNode:
|
|||||||
|
|
||||||
class DumasH3PlanExtractSceneImagesNode:
|
class DumasH3PlanExtractSceneImagesNode:
|
||||||
DESCRIPTION = (
|
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 "
|
"Connect clip_index or another scene selector to recover the matching "
|
||||||
"scene images downstream."
|
"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 = (
|
RETURN_NAMES = (
|
||||||
"plan",
|
"plan",
|
||||||
"image1",
|
"image1",
|
||||||
@@ -595,6 +614,7 @@ class DumasH3PlanExtractSceneImagesNode:
|
|||||||
"image4",
|
"image4",
|
||||||
"image5",
|
"image5",
|
||||||
"image6",
|
"image6",
|
||||||
|
"image7",
|
||||||
"connected_images",
|
"connected_images",
|
||||||
)
|
)
|
||||||
FUNCTION = "extract"
|
FUNCTION = "extract"
|
||||||
@@ -633,11 +653,11 @@ class DumasH3PlanExtractSceneImagesNode:
|
|||||||
scene_index = _normalize_h3_scene_index(passthrough_plan, scene_index)
|
scene_index = _normalize_h3_scene_index(passthrough_plan, scene_index)
|
||||||
token, _scene_counts = _h3_plan_binding_entry(passthrough_plan)
|
token, _scene_counts = _h3_plan_binding_entry(passthrough_plan)
|
||||||
if not token:
|
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 {}
|
registry = _H3_PLAN_IMAGE_BINDINGS.get(token) or {}
|
||||||
_touch_plan_image_binding(token)
|
_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))
|
return (passthrough_plan, *images, _connected_image_count(images))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -348,12 +348,14 @@ class DumasImageNodeTests(unittest.TestCase):
|
|||||||
plan = {"shots": [{"id": "one"}, {"id": "two"}]}
|
plan = {"shots": [{"id": "one"}, {"id": "two"}]}
|
||||||
image_1 = FakeTensorBatch()
|
image_1 = FakeTensorBatch()
|
||||||
image_2 = FakeTensorBatch(width=12, height=9)
|
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_first, _connected = attach_node.attach(plan=plan, scene_index=1, image2=image_1)
|
||||||
plan_after_second, _connected = attach_node.attach(
|
plan_after_second, _connected = attach_node.attach(
|
||||||
plan=plan_after_first,
|
plan=plan_after_first,
|
||||||
scene_index=2,
|
scene_index=2,
|
||||||
image6=image_2,
|
image6=image_2,
|
||||||
|
image7=image_3,
|
||||||
)
|
)
|
||||||
|
|
||||||
scene1 = extract_node.extract(plan_after_second, 1)
|
scene1 = extract_node.extract(plan_after_second, 1)
|
||||||
@@ -362,10 +364,11 @@ class DumasImageNodeTests(unittest.TestCase):
|
|||||||
self.assertIs(scene1[2], image_1)
|
self.assertIs(scene1[2], image_1)
|
||||||
self.assertEqual(scene1[-1], 1)
|
self.assertEqual(scene1[-1], 1)
|
||||||
self.assertIs(scene2[6], image_2)
|
self.assertIs(scene2[6], image_2)
|
||||||
self.assertEqual(scene2[-1], 1)
|
self.assertIs(scene2[7], image_3)
|
||||||
|
self.assertEqual(scene2[-1], 2)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
plan_after_second["_dumas_scene_image_bindings"]["scene_counts"],
|
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):
|
def test_h3_plan_scene_images_metadata_is_json_serializable(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user