Browse Source

Update the Blender script

It can now generate views on a per-object basis, and uses
whole collections so that many objects can be grouped together.
master
Fen Dweller 3 years ago
parent
commit
7d719f47aa
1 changed files with 56 additions and 26 deletions
  1. +56
    -26
      scripts/blender-model.py

+ 56
- 26
scripts/blender-model.py View File

@@ -6,8 +6,26 @@ import os
import pathlib
import bmesh

GROUP_NAME = "Bricks"
GROUP_KIND = "objects"
def get_bounds(objects):
xl = []
yl = []
zl = []
for obj in objects:
for bounds in obj.bound_box:
v = obj.matrix_world @ Vector(bounds)
xl += [v[0] for c in obj.bound_box]
yl += [v[1] for c in obj.bound_box]
zl += [v[2] for c in obj.bound_box]
return (
Vector([min(xl), min(yl), min(zl)]),
Vector([max(xl), max(yl), max(zl)])
)

GROUP_NAME = "Billboards"
GROUP_KIND = "buildings"

path_info = pathlib.Path(bpy.data.filepath).parent.joinpath("macrovision-directory.txt")
config_path = pathlib.Path(open(path_info).read())
@@ -28,10 +46,7 @@ bpy.data.scenes["Scene"].view_settings.view_transform = "Raw"

bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[1].default_value = 0

objects = []
for object in bpy.data.collections["Macrovision"].objects:
if object.type == "MESH" or object.type == "CURVE":
objects.append(object)
collections = bpy.data.collections["Macrovision"].children

all_data = {}

@@ -39,33 +54,51 @@ all_data["name"] = GROUP_NAME
all_data["kind"] = GROUP_KIND
all_data["forms"] = []

VOLUME = True
VOLUME = False

os.makedirs(workdir, exist_ok=True)

for selected in objects:
for object in bpy.data.collections["Macrovision"].objects:
object.hide_render = True
VIEW_DATA = {
"Front": [0, 1, 2, "Front"],
"Angled": [0.5, 1, 2, "Angled"],
"Side": [1, 1, 2, "Side"],
"Back": [2, 1, 2, "Back"],
"Top": [0, 0, 1, "Top"]
}

for coll in collections:
coll.hide_render = True

for coll in collections:
selected.hide_render = False
coll.hide_render = False
bpy.ops.object.select_all(action='DESELECT')
selected.select_set(True)
bpy.ops.object.transform_apply( location = False, rotation = True, scale = True )
for obj in coll.objects:
obj.select_set(True)

data = {}
data["name"] = selected.name
data["name"] = coll.name
data["views"] = []

b = selected
bound_min, bound_max = get_bounds(coll.objects)
dimensions = bound_max - bound_min
size = max(dimensions)
global_bbox_center = 0.5 * (bound_min + bound_max)
view_list = []
if "Views" in coll:
for view in coll["Views"].split(","):
view_list.append(VIEW_DATA[view])
else:
view_list = [VIEW_DATA["Front"]]

for angles in [[0, 1, 2, "Front"], [0.5, 1, 2, "Angled"], [1, 1, 2, "Side"], [0, 0, 1, "Top"]]:
local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector())
global_bbox_center = b.matrix_world @ local_bbox_center
for angles in view_list:
c.location = global_bbox_center
largest = max(b.dimensions)
largest = size
c.data.ortho_scale = largest * 1.2
if angles[0] % 1 != 0:
c.data.ortho_scale *= sqrt(2)
@@ -77,18 +110,15 @@ for selected in objects:
c.data.clip_end = largest * 4
data["views"].append({
"name": angles[3],
"height": b.dimensions[angles[2]]
"height": dimensions[angles[2]]
})
if VOLUME and selected.type == "MESH":
bm = bmesh.new()
bm.from_mesh(selected.data)
data["views"][-1]["volume"] = bm.calc_volume()
#s.rotation_euler = c.rotation_euler
filename = f"{b.name}-{angles[3]}.png"
filename = f"{coll.name}-{angles[3]}.png"
bpy.context.scene.render.filepath = workdir.joinpath(filename).resolve().__str__()
bpy.ops.render.render(write_still = True)
all_data["forms"].append(data)
coll.hide_render = True

with open(workdir.joinpath("data.json"), "w") as file:
json.dump(all_data, file)

Loading…
Cancel
Save