Scene Manager: Load Publish and numbered instances
Load Publish (Loaded panel) searches every asset of the project, then loads any of its published .blend files at any version, cast in the shot or not. The file the casting would load and the latest version on this site are preselected; a version not on this site is requested instead. Built on the existing wtd_list_assets / wtd_get_asset_files / wtd_get_revisions commands. New instances are numbered (COL_bob_01, tree_01...), counting on from the highest number in the file (SCENE_MANAGER_INSTANCE_NAME). README: Pick Shot only lists shots that exist in Libreflow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6ec2b228ae
commit
fbc7ac18e4
9 files changed
+307
-32
No files matched your search
+40
-11
@@ -100,14 +100,14 @@ print("Load")
|
||||
bpy.ops.wtd_scene.load()
|
||||
pump()
|
||||
state = loaded()
|
||||
check("bob: 2 instances of v002", state.get("bob") == ("v002", ["COL_bob", "COL_bob.001"]), str(state.get("bob")))
|
||||
check("tree: 1 collection instance", state.get("tree") == ("v001", ["tree"]), str(state.get("tree")))
|
||||
check("rock: single top-level collection fallback", state.get("rock") == ("v001", ["rock_geo"]))
|
||||
check("bob: 2 numbered instances of v002", state.get("bob") == ("v002", ["COL_bob_01", "COL_bob_02"]), str(state.get("bob")))
|
||||
check("tree: 1 numbered collection instance", state.get("tree") == ("v001", ["tree_01"]), str(state.get("tree")))
|
||||
check("rock: single top-level collection fallback", state.get("rock") == ("v001", ["rock_geo_01"]))
|
||||
check("lamp and ghost reported", "lamp" in message() and "ghost" in message(), message())
|
||||
check("type collections", {"COL_main_character", "COL_bg_set", "COL_main_props"} <= set(scene.collection.children.keys()))
|
||||
check(
|
||||
"chars are posable overrides",
|
||||
all(ob.override_library for ob in bpy.data.collections["COL_bob"].all_objects),
|
||||
all(ob.override_library for ob in bpy.data.collections["COL_bob_01"].all_objects),
|
||||
)
|
||||
check("shot manager groups bob as character", "Characters" in shot_viewer.rig_groups(bpy.context.view_layer))
|
||||
bpy.ops.wtd_scene.load()
|
||||
@@ -149,7 +149,7 @@ for ob in bpy.context.view_layer.objects:
|
||||
ob.select_set(ob in (tree, bpy.data.objects["RIG_COL_car"]))
|
||||
check("LOD of selected", bpy.ops.wtd_scene.set_lod(lod="1", selected=True) == {"FINISHED"})
|
||||
check("only the selected instances having it switched", (lib.current_lod(tree_lib, tree), lib.current_lod(car_lib, car)) == ("1", "low"))
|
||||
check("missing LOD refused", bpy.ops.wtd_scene.set_lod(lod="5", library="tree", instance="tree") == {"CANCELLED"})
|
||||
check("missing LOD refused", bpy.ops.wtd_scene.set_lod(lod="5", library="tree", instance="tree_01") == {"CANCELLED"})
|
||||
check("LOD order: list, numbers, names", sorted(["b", "10", "low", "2", "a", "high"], key=lib.lod_order) == ["high", "low", "2", "10", "a", "b"])
|
||||
second = lib.add_instance(scene, bpy.context.view_layer, car_lib)
|
||||
check(
|
||||
@@ -161,7 +161,7 @@ lib.remove_instance(second)
|
||||
lib.update("tree", {"name": "v002", "path": os.path.join(WORKDIR, "lib", "tree", "v002", "model.blend")})
|
||||
tree = lib.instances(bpy.data.libraries["tree"])[0]
|
||||
check("LOD kept by an update", lib.current_lod(bpy.data.libraries["tree"], tree) == "1")
|
||||
check("content outside the LODs: instance refused", bpy.ops.wtd_scene.set_lod(lod="0", library="tree", instance="tree") == {"CANCELLED"})
|
||||
check("content outside the LODs: instance refused", bpy.ops.wtd_scene.set_lod(lod="0", library="tree", instance="tree_01") == {"CANCELLED"})
|
||||
lib.update("tree", {"name": "v003", "path": os.path.join(WORKDIR, "lib", "tree", "v003", "model.blend")})
|
||||
tree = lib.instances(bpy.data.libraries["tree"])[0]
|
||||
check("LODs gone: whole collection instanced", tree.instance_collection.name == "COL_tree" and not lib.lods(bpy.data.libraries["tree"], tree))
|
||||
@@ -207,11 +207,11 @@ check("picking a version not on this site requests it", message() == "Requested
|
||||
check("still on v002", loaded()["bob"][0] == "v002")
|
||||
|
||||
print("Remove")
|
||||
bpy.ops.wtd_scene.remove(instance="COL_bob.001")
|
||||
check("one instance removed", loaded()["bob"][1] == ["COL_bob"])
|
||||
bpy.ops.wtd_scene.remove(instance="COL_bob_02")
|
||||
check("one instance removed", loaded()["bob"][1] == ["COL_bob_01"])
|
||||
for ob in bpy.context.view_layer.objects:
|
||||
ob.select_set(False)
|
||||
bpy.data.objects["tree"].select_set(True)
|
||||
bpy.data.objects["tree_01"].select_set(True)
|
||||
bpy.ops.wtd_scene.remove(selected=True)
|
||||
check("selected instance removed", loaded()["tree"][1] == [])
|
||||
bpy.ops.wtd_scene.remove("EXEC_DEFAULT", library="rock")
|
||||
@@ -220,6 +220,35 @@ check("its indirect library removed too", set(bpy.data.libraries.keys()) == {"bo
|
||||
bpy.ops.wtd_scene.load()
|
||||
pump()
|
||||
check("load restores what is missing", {k: len(v[1]) for k, v in loaded().items()} == {"bob": 2, "car": 1, "rock": 1, "tree": 1})
|
||||
check("numbers go on after the highest one", loaded()["bob"][1] == ["COL_bob_01", "COL_bob_02"], str(loaded()["bob"][1]))
|
||||
|
||||
print("Load publish")
|
||||
CHAIR = "/melvile/asset_types/set_props/assets/chair"
|
||||
check("project of the context", sm.project_oid(scene) == "/melvile")
|
||||
sm.STATE.assets = ipc.call("wtd_list_assets", None, oid=sm.project_oid(scene))
|
||||
check("any asset listed, cast or not", CHAIR in [a["oid"] for a in sm.STATE.assets])
|
||||
sm.browse_asset(next(a for a in sm.STATE.assets if a["oid"] == CHAIR))
|
||||
chair_file = sm.default_file("set_props", sm.STATE.browse["files"])
|
||||
check("default file follows the file patterns", chair_file["label"] == "modeling/chair.blend", chair_file["label"])
|
||||
check("versions newest first", [r["name"] for r in chair_file["revisions"]] == ["v002", "v001"])
|
||||
check("default version: latest on this site", sm.default_revision(chair_file)["name"] == "v001")
|
||||
result = bpy.ops.wtd_scene.load_publish("EXEC_DEFAULT", file=chair_file["file_oid"], revision="v002")
|
||||
pump()
|
||||
check(
|
||||
"version not on this site: requested, not loaded",
|
||||
result == {"CANCELLED"} and "chair" not in loaded()
|
||||
and ["wtd_request_revisions", {"revision_oids": [chair_file["file_oid"] + "/history/revisions/v002"]}] in fake("/_test/calls", {}),
|
||||
)
|
||||
bpy.ops.wtd_scene.load_publish("EXEC_DEFAULT", file=chair_file["file_oid"], revision="v001", count=2)
|
||||
check("loaded twice, numbered", loaded().get("chair") == ("v001", ["chair_01", "chair_02"]), str(loaded().get("chair")))
|
||||
check("its versions followed in Loaded", sm.version_status(bpy.data.libraries["chair"])[0] == "PENDING")
|
||||
sm.browse_asset(next(a for a in sm.STATE.assets if a["asset"] == "bob"))
|
||||
check(
|
||||
"another version of a loaded file refused",
|
||||
bpy.ops.wtd_scene.load_publish("EXEC_DEFAULT", file=BOB_FILE, revision="v004") == {"CANCELLED"} and loaded()["bob"][0] == "v002",
|
||||
)
|
||||
bpy.ops.wtd_scene.load_publish("EXEC_DEFAULT", file=BOB_FILE, revision="v002")
|
||||
check("same version: one more numbered instance", loaded()["bob"][1] == ["COL_bob_01", "COL_bob_02", "COL_bob_03"], str(loaded()["bob"][1]))
|
||||
|
||||
print("Ambiguous file")
|
||||
try:
|
||||
@@ -243,7 +272,7 @@ bpy.ops.wtd_scene.assetize(
|
||||
)
|
||||
pump()
|
||||
check("published and replaced", "replaced" in message(), message())
|
||||
check("lamp linked", loaded().get("lamp") == ("v001", ["COL_lamp"]), str(loaded().get("lamp")))
|
||||
check("lamp linked", loaded().get("lamp") == ("v001", ["COL_lamp_01"]), str(loaded().get("lamp")))
|
||||
check("local collection kept, renamed", "COL_lamp_local" in bpy.data.collections)
|
||||
bad = bpy.data.collections.new("COL_bad")
|
||||
scene.collection.children.link(bad)
|
||||
@@ -256,7 +285,7 @@ path = os.path.join(WORKDIR, "scene_manager_test.blend")
|
||||
bpy.ops.wm.save_as_mainfile(filepath=path)
|
||||
bpy.ops.wm.open_mainfile(filepath=path)
|
||||
sm._on_load_post()
|
||||
check("everything found after reopening", set(loaded()) == {"bob", "car", "lamp", "rock", "tree"})
|
||||
check("everything found after reopening", set(loaded()) == {"bob", "car", "chair", "lamp", "rock", "tree"})
|
||||
car_lib = bpy.data.libraries["car"]
|
||||
check("LOD kept after reopening", lib.current_lod(car_lib, lib.instances(car_lib)[0]) == "low")
|
||||
sm.connect(bpy.context.scene)
|
||||
|
||||
Reference in new issue
Block a user