Ship the WeChat hot-update catalogs and the camp, TideWhale T2, UI atlas, and animation-lab work.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""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))
|
||||
Reference in New Issue
Block a user