57 lines
3.1 KiB
Python
57 lines
3.1 KiB
Python
"""Render high/final Studio accessory and audit geometry/UV without changing it."""
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import bpy
|
|
import numpy as np
|
|
from mathutils import Vector
|
|
|
|
folder = Path(sys.argv[sys.argv.index('--') + 1]).resolve()
|
|
report = []
|
|
filenames = ('model.glb',) if '--high-only' in sys.argv else ('model_ex.glb',) if '--final-only' in sys.argv else ('model.glb', 'model_ex.glb')
|
|
for filename in filenames:
|
|
bpy.ops.wm.read_factory_settings(use_empty=True)
|
|
bpy.ops.import_scene.gltf(filepath=str(folder / filename))
|
|
objects = [o for o in bpy.context.scene.objects if o.type == 'MESH']
|
|
points = [o.matrix_world @ v.co for o in objects for v in o.data.vertices]
|
|
lo = Vector([min(v[i] for v in points) for i in range(3)])
|
|
hi = Vector([max(v[i] for v in points) for i in range(3)])
|
|
uv = np.array([tuple(v.uv) for o in objects if o.data.uv_layers.active for v in o.data.uv_layers.active.data])
|
|
assert len(objects) == 1 and np.isfinite(uv).all() and len(uv) > 0
|
|
triangles = sum(len(p.vertices) - 2 for o in objects for p in o.data.polygons)
|
|
report.append(dict(file=filename, objects=len(objects), triangles=triangles,
|
|
vertices=sum(len(o.data.vertices) for o in objects), minimum=list(lo), maximum=list(hi),
|
|
uvLoops=len(uv), finiteUV=True))
|
|
scene = bpy.context.scene
|
|
scene.render.engine = 'CYCLES'
|
|
scene.cycles.samples = 16
|
|
scene.render.resolution_x = scene.render.resolution_y = 640
|
|
scene.render.resolution_percentage = 100
|
|
world = bpy.data.worlds.new('ReviewWorld')
|
|
world.use_nodes = True
|
|
world.node_tree.nodes['Background'].inputs[0].default_value = (.32, .38, .44, 1)
|
|
world.node_tree.nodes['Background'].inputs[1].default_value = .6
|
|
scene.world = world
|
|
center = (lo + hi) / 2
|
|
extent = max(hi - lo)
|
|
camera = bpy.data.objects.new('ReviewCamera', bpy.data.cameras.new('ReviewCamera'))
|
|
scene.collection.objects.link(camera)
|
|
scene.camera = camera
|
|
camera.data.type = 'ORTHO'
|
|
camera.data.ortho_scale = extent * 1.3
|
|
for direction, power in (((2, -3, 4), 400), ((-3, -1, 2), 250)):
|
|
light = bpy.data.objects.new('ReviewLight', bpy.data.lights.new('ReviewLight', 'AREA'))
|
|
scene.collection.objects.link(light)
|
|
light.location = center + Vector(direction) * extent
|
|
light.rotation_euler = (center - light.location).to_track_quat('-Z', 'Y').to_euler()
|
|
light.data.energy = power * extent ** 2
|
|
light.data.size = extent * 3
|
|
for name, direction in [('front', (0, -3, .5)), ('side', (3, 0, .5)), ('back', (0, 3, .5)), ('perspective', (2, -3, 1))]:
|
|
camera.location = center + Vector(direction) * extent
|
|
camera.rotation_euler = (center - camera.location).to_track_quat('-Z', 'Y').to_euler()
|
|
scene.render.filepath = str(folder / ('audit_' + Path(filename).stem + '_' + name + '.png'))
|
|
bpy.ops.render.render(write_still=True)
|
|
(folder / ('geometry_high.json' if '--high-only' in sys.argv else 'geometry_audit.json')).write_text(json.dumps(report, indent=2) + '\n', encoding='utf-8')
|
|
print('MT_SUMMARY ' + json.dumps(report))
|