82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
import bpy
|
|
import os
|
|
from natsort import natsorted
|
|
|
|
# ========== USER SETTINGS ==========
|
|
blend_folder = r"D:\Dropbox\Gitea_OD\Bonsai_Tutorials\_Model"
|
|
frames_per_stage = 5
|
|
start_frame = 1
|
|
# ===================================
|
|
|
|
scene = bpy.context.scene
|
|
scene.frame_start = start_frame
|
|
|
|
skip_names = {"House.blend", "House - Copy.blend"}
|
|
|
|
blend_files = natsorted(
|
|
f for f in os.listdir(blend_folder)
|
|
if f.lower().endswith(".blend") and f.lower() not in {name.lower() for name in skip_names}
|
|
)
|
|
|
|
total_files = len(blend_files)
|
|
collection_instances = []
|
|
|
|
for idx, blend_name in enumerate(reversed(blend_files)):
|
|
i = total_files - idx - 1 # Reverse index for frame calculation
|
|
blend_path = os.path.join(blend_folder, blend_name)
|
|
|
|
print(f"Linking {blend_name}...")
|
|
|
|
# Load only the collection named "IfcProject/My Project"
|
|
with bpy.data.libraries.load(blend_path, link=True) as (data_from, data_to):
|
|
if "IfcProject/My Project" in data_from.collections:
|
|
data_to.collections = ["IfcProject/My Project"]
|
|
else:
|
|
print(f"❌ 'IfcProject/My Project' collection not found in {blend_name}")
|
|
continue
|
|
|
|
if not data_to.collections:
|
|
continue
|
|
|
|
linked_col = data_to.collections[0]
|
|
|
|
# Link collection to the scene collection if not already linked
|
|
if linked_col.name not in [c.name for c in scene.collection.children]:
|
|
scene.collection.children.link(linked_col)
|
|
|
|
# Create a collection instance object for the linked collection
|
|
inst_name = f"{blend_name} - IfcProject/My Project"
|
|
inst = bpy.data.objects.new(inst_name, None)
|
|
inst.instance_type = 'COLLECTION'
|
|
inst.instance_collection = linked_col
|
|
bpy.context.collection.objects.link(inst)
|
|
|
|
collection_instances.append((inst, i))
|
|
|
|
# Now animate visibility so only one is visible at a time
|
|
for inst, i in collection_instances:
|
|
frame_show = start_frame + i * frames_per_stage
|
|
frame_hide = frame_show + frames_per_stage
|
|
|
|
# Before show frame: hidden
|
|
inst.hide_render = True
|
|
inst.hide_viewport = True
|
|
inst.keyframe_insert(data_path="hide_render", frame=frame_show - 1)
|
|
inst.keyframe_insert(data_path="hide_viewport", frame=frame_show - 1)
|
|
|
|
# Show during frame_show to frame_hide - 1
|
|
inst.hide_render = False
|
|
inst.hide_viewport = False
|
|
inst.keyframe_insert(data_path="hide_render", frame=frame_show)
|
|
inst.keyframe_insert(data_path="hide_viewport", frame=frame_show)
|
|
|
|
# After frame_hide: hidden
|
|
inst.hide_render = True
|
|
inst.hide_viewport = True
|
|
inst.keyframe_insert(data_path="hide_render", frame=frame_hide)
|
|
inst.keyframe_insert(data_path="hide_viewport", frame=frame_hide)
|
|
|
|
# Set total frame range for animation
|
|
scene.frame_end = start_frame + frames_per_stage * total_files
|
|
|
|
print("✅ Master time-lapse setup complete.")
|