Files
AIGame/Tools/model_tools/bl_audit_t2_accessory.py

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))