2014-11-19 20:35:11 +01:00
|
|
|
# Apache License, Version 2.0
|
|
|
|
|
|
|
|
# Pass in:
|
|
|
|
#
|
|
|
|
# blender --python blendfile_templates.py -- destination/file.blend create_command return_code
|
|
|
|
#
|
|
|
|
# 'return_code' can be any number, use to check the script completes.
|
|
|
|
|
|
|
|
|
|
|
|
def _clear_blend():
|
|
|
|
import bpy
|
|
|
|
|
|
|
|
# copied from batch_import.py
|
|
|
|
unique_obs = set()
|
|
|
|
for scene in bpy.data.scenes:
|
|
|
|
for obj in scene.objects[:]:
|
|
|
|
scene.objects.unlink(obj)
|
|
|
|
unique_obs.add(obj)
|
|
|
|
|
|
|
|
# remove obdata, for now only worry about the startup scene
|
|
|
|
for bpy_data_iter in (bpy.data.objects, bpy.data.meshes, bpy.data.lamps, bpy.data.cameras):
|
|
|
|
for id_data in bpy_data_iter:
|
|
|
|
bpy_data_iter.remove(id_data)
|
|
|
|
|
|
|
|
|
2014-11-27 12:51:04 +01:00
|
|
|
def create_blank(blendfile_root, _create_data, deps):
|
2014-11-21 12:44:55 +01:00
|
|
|
assert(isinstance(deps, list))
|
2014-11-19 20:35:11 +01:00
|
|
|
|
|
|
|
|
2014-11-27 12:51:04 +01:00
|
|
|
def create_image_single(blendfile_root, _create_data, deps):
|
2014-11-19 20:35:11 +01:00
|
|
|
import bpy
|
2014-11-21 12:44:55 +01:00
|
|
|
|
|
|
|
path = "//my_image.png"
|
2014-11-19 20:35:11 +01:00
|
|
|
image = bpy.data.images.new(name="MyImage", width=512, height=512)
|
2014-11-21 12:44:55 +01:00
|
|
|
image.filepath_raw = path
|
|
|
|
deps.append(bpy.path.abspath(path))
|
2014-11-19 20:35:11 +01:00
|
|
|
image.file_format = 'PNG'
|
|
|
|
image.use_fake_user = True
|
|
|
|
image.save()
|
|
|
|
|
|
|
|
|
2014-11-27 12:51:04 +01:00
|
|
|
def create_from_files(blendfile_root, _create_data, deps):
|
2014-11-21 17:22:02 +01:00
|
|
|
"""Create a blend file which users all sub-directories.
|
|
|
|
(currently images only)
|
|
|
|
"""
|
|
|
|
import os
|
|
|
|
import bpy
|
|
|
|
|
|
|
|
def iter_files_blend(path):
|
|
|
|
for dirpath, dirnames, filenames in os.walk(path):
|
|
|
|
for filename in filenames:
|
|
|
|
filepath = os.path.join(dirpath, filename)
|
|
|
|
yield filepath
|
|
|
|
|
2014-11-25 17:16:40 +01:00
|
|
|
# dirname = os.path.dirname(bpy.data.filepath)
|
|
|
|
dirname = blendfile_root
|
2014-11-21 17:22:02 +01:00
|
|
|
for f_abs in iter_files_blend(dirname):
|
|
|
|
if f_abs.endswith(".png"):
|
|
|
|
f_rel = bpy.path.relpath(f_abs)
|
2014-11-21 20:58:44 +01:00
|
|
|
image = bpy.data.images.load(f_rel)
|
2014-11-21 17:22:02 +01:00
|
|
|
image.use_fake_user = True
|
2014-11-21 17:56:57 +01:00
|
|
|
deps.append(f_abs)
|
2014-11-21 17:22:02 +01:00
|
|
|
|
|
|
|
|
2014-11-27 17:48:35 +01:00
|
|
|
def create_from_file_liblinks(blendfile_root, create_data, deps):
|
|
|
|
# _clear_blend()
|
|
|
|
# create_data is a list of string pairs:
|
|
|
|
# [(blend_file, data_id, links_to)]
|
|
|
|
import os
|
|
|
|
import bpy
|
|
|
|
|
|
|
|
def savefile(f):
|
|
|
|
bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=f)
|
|
|
|
|
|
|
|
def newfile(f):
|
|
|
|
bpy.ops.wm.read_factory_settings()
|
|
|
|
_clear_blend()
|
|
|
|
savefile(f)
|
|
|
|
|
|
|
|
# NOTE: no attempt has been made to optimize loop below
|
|
|
|
# we rely on this being < 10 items to not be completely slow!
|
|
|
|
print(create_data)
|
|
|
|
data_id_map = {f: f_id for (f, f_id, f_link) in create_data}
|
|
|
|
done = {bpy.data.filepath}
|
|
|
|
|
|
|
|
# simplifies logic below
|
|
|
|
os.remove(bpy.data.filepath)
|
|
|
|
|
|
|
|
ok = True
|
|
|
|
while ok:
|
|
|
|
ok = False
|
|
|
|
for f, f_id, f_links in create_data:
|
|
|
|
if not os.path.exists(f):
|
|
|
|
print(f_links)
|
|
|
|
if not f_links or all(os.path.exists(l) for l in f_links):
|
|
|
|
if f != bpy.data.filepath:
|
|
|
|
newfile(f)
|
|
|
|
|
|
|
|
scene = bpy.context.scene
|
|
|
|
|
|
|
|
# we have a path with an existing link!
|
|
|
|
ok = True
|
|
|
|
for i, l_abs in enumerate(f_links):
|
|
|
|
l_rel = bpy.path.relpath(l_abs)
|
|
|
|
with bpy.data.libraries.load(l_rel, link=True) as (data_src, data_dst):
|
|
|
|
data_dst.scenes = [data_id_map[l_abs]]
|
|
|
|
|
|
|
|
scene_link = bpy.data.scenes[data_id_map[l_abs]]
|
|
|
|
edit = scene.sequence_editor_create()
|
|
|
|
edit.sequences.new_scene(
|
|
|
|
name=scene_link.name,
|
|
|
|
scene=scene_link,
|
|
|
|
frame_start=1,
|
|
|
|
channel=i,
|
|
|
|
)
|
|
|
|
|
|
|
|
# save the file with a new scene name
|
|
|
|
scene.name = f_id
|
|
|
|
bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=f)
|
|
|
|
done.add(f)
|
|
|
|
|
|
|
|
if len(create_data) != len(done):
|
|
|
|
raise Exception(
|
|
|
|
"Paths could not be resolved (cyclic deps) %r!" %
|
|
|
|
tuple(sorted({f for f, f_id, f_links in create_data} - done)))
|
|
|
|
|
|
|
|
|
2014-11-19 20:35:11 +01:00
|
|
|
if __name__ == "__main__":
|
|
|
|
import sys
|
2014-11-27 12:51:04 +01:00
|
|
|
blendfile, blendfile_root, blendfile_deps_json, create_id, create_data, returncode = sys.argv[-6:]
|
2014-11-19 20:35:11 +01:00
|
|
|
returncode = int(returncode)
|
|
|
|
create_fn = globals()[create_id]
|
|
|
|
|
2014-11-27 12:51:04 +01:00
|
|
|
if create_data != "NONE":
|
|
|
|
with open(create_data, 'r') as f:
|
|
|
|
import json
|
|
|
|
create_data = json.load(f)
|
|
|
|
del json
|
|
|
|
|
2014-11-19 20:35:11 +01:00
|
|
|
# ----
|
|
|
|
import bpy
|
|
|
|
# no need for blend1's
|
|
|
|
bpy.context.user_preferences.filepaths.save_version = 0
|
|
|
|
# WEAK! (but needed)
|
|
|
|
# save the file first, so we can do real, relative dirs
|
|
|
|
bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=blendfile)
|
|
|
|
del bpy
|
|
|
|
# ----
|
|
|
|
|
|
|
|
_clear_blend()
|
2014-11-21 12:44:55 +01:00
|
|
|
deps = []
|
2014-11-25 17:16:40 +01:00
|
|
|
|
2014-11-27 12:51:04 +01:00
|
|
|
create_fn(blendfile_root, create_data, deps)
|
2014-11-25 17:16:40 +01:00
|
|
|
|
2014-11-21 12:44:55 +01:00
|
|
|
if deps:
|
|
|
|
with open(blendfile_deps_json, 'w') as f:
|
|
|
|
import json
|
|
|
|
json.dump(
|
|
|
|
deps, f, ensure_ascii=False,
|
|
|
|
check_circular=False,
|
|
|
|
# optional (pretty)
|
|
|
|
sort_keys=True, indent=4, separators=(',', ': '),
|
|
|
|
)
|
|
|
|
del json
|
2014-11-19 20:35:11 +01:00
|
|
|
|
|
|
|
import bpy
|
|
|
|
bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=blendfile)
|
|
|
|
|
|
|
|
import sys
|
|
|
|
sys.exit(returncode)
|