User:Sybren/SfA/SceneBuilding
< User:Sybren | SfA
Scripting for Artists: Scene Building
- About constructing a scene with Python.
- JSON file with scene description.
- Link assets from blend files.
- Put them into the scene in the right collection.
Linking assets from Python
Start with the linking, because that's the biggest unknown. We have managed collections before (https://cloud.blender.org/p/scripting-for-artists/5e7c941c5afb8fa58fad6718). Parsing a JSON file is also an unknown for now, but only once we know how we link things to a blend file will we know what we want to put into that JSON file.
Start with docs.
Simple script to explore
import bpy
from pprint import pprint
filepath = "//../envs/desert_plants.blend"
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
pprint(data_from.collections)
Note that in the outliner, Libraries, the blend file is listed. Also in bpy.data.libraries
.
Filter collections by name
import bpy
from pprint import pprint
filepath = "//../envs/desert_plants.blend"
prefix = 'EN-cactus_fork.'
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
pprint(data_from.collections)
for name in data_from.collections:
if not name.startswith(prefix):
continue
print(name)
data_to.collections.append(name)
Now in the outliner you can see the linked collections. Saving & reloading the file still removes them, because they are not yet used.
Instancing into the scene
First do this by hand, to explore what happens.
An instance is just a carefully crafted Empty.
- Create the Empty with the name of the collection.
- Set it to instance that collection (
.instance_type = "COLLECTION"
,.instance_collection = coll
) - Link it to the desired scene collection.
# Create top collection
scene = bpy.context.scene
coll_name = 'Environment'
try:
top_coll = scene.collection.children[coll_name]
except KeyError:
top_coll = bpy.data.collections.new(coll_name)
scene.collection.children.link(top_coll)
# Instance into the scene
location_x = 0
step_x = 1.0
for coll in data_to.collections:
empty = bpy.data.objects.new(coll.name, None)
empty.instance_type = 'COLLECTION'
empty.instance_collection = coll
link_to.objects.link(empty)
empty.location.x = location_x
empty.location.y = location_y
location_x += x_step
Parsing JSON file
- JSON is not the most human-friendly, but quite simple, and support is built into Python.
- Meaning of
{}
and[]
pretty much the same as in Python (dict vs. list).
{
"version": 1,
"collections": {
"Rocks": {
"link": [
{
"file": "//../envs/rocks.blend",
"prefix": "EN-rock_s_"
},
{
"file": "//../envs/rocks.blend",
"prefix": "EN-rock_smooth_"
}
]
},
"Plants": {
"link": [
{
"file": "//../envs/desert_plants.blend",
"prefix": "EN-cactus_fork."
},
{
"file": "//../envs/desert_plants.blend",
"prefix": "EN-cactus_elements."
},
{
"file": "//../envs/desert_plants.blend",
"prefix": "EN-cactus_ball."
}
]
}
}
}