"""Render both signs of the actual FBX Z axis to identify anatomical front.""" import sys,json,math from pathlib import Path import bpy from mathutils import Vector ROOT=Path(__file__).resolve().parents[2] OUT=ROOT/'Tools/output/character_front_audit';OUT.mkdir(parents=True,exist_ok=True) for folder,name,kind in [('campguide_studio','CampGuideStudio','static'),('lmgirl_tpose_studio','LmGirlTpose','static'), ('campguide_studio','CampGuideStudio','high'),('lmgirl_tpose_studio','LmGirlTpose','high')]: bpy.ops.wm.read_factory_settings(use_empty=True) base=ROOT/'Tools/output'/folder/'static' if kind=='static':bpy.ops.import_scene.fbx(filepath=str(base/(name+'.fbx')),use_anim=False) else:bpy.ops.import_scene.gltf(filepath=str(base.parent/'model.glb')) obj=next(o for o in bpy.context.scene.objects if o.type=='MESH') if kind=='static': material=bpy.data.materials.new('AuditTexture');material.use_nodes=True node=material.node_tree.nodes.new('ShaderNodeTexImage');node.image=bpy.data.images.load(str(base/(name+'_color.png'))) material.node_tree.nodes.active=node material.node_tree.links.new(node.outputs['Color'],material.node_tree.nodes.get('Principled BSDF').inputs['Base Color']) obj.data.materials.clear();obj.data.materials.append(material) else: for slot in obj.material_slots: if slot.material and slot.material.use_nodes: for node in slot.material.node_tree.nodes: if node.type=='TEX_IMAGE' and any(link.to_socket.name=='Base Color' for link in node.outputs['Color'].links): slot.material.node_tree.nodes.active=node;break pts=[obj.matrix_world@v.co for v in obj.data.vertices];lo=Vector([min(v[i] for v in pts) for i in range(3)]);hi=Vector([max(v[i] for v in pts) for i in range(3)]) h=hi.z-lo.z;center=(lo+hi)/2 scene=bpy.context.scene;scene.render.engine='BLENDER_WORKBENCH' scene.render.resolution_x=512;scene.render.resolution_y=640;scene.render.resolution_percentage=100 scene.render.image_settings.file_format='PNG';scene.world=bpy.data.worlds.new('AuditWorld');scene.world.color=(.7,.7,.7) shading=scene.display.shading;shading.light='STUDIO';shading.color_type='TEXTURE';shading.show_shadows=True;shading.show_cavity=True;shading.background_type='WORLD' camera=bpy.data.objects.new('AuditCamera',bpy.data.cameras.new('AuditCamera'));scene.collection.objects.link(camera);scene.camera=camera camera.data.type='ORTHO';camera.data.ortho_scale=h*1.2 # A Y-up FBX imported into Blender is rotated +90 X: +Z becomes -Y. for sign,axis in [('plus_z',Vector((0,-1,0))),('minus_z',Vector((0,1,0)))]: camera.location=center+axis*h*3 camera.rotation_euler=(center-camera.location).to_track_quat('-Z','Y').to_euler() scene.render.filepath=str(OUT/(name+('_high' if kind=='high' else '')+'_from_'+sign+'.png')) bpy.ops.render.render(write_still=True) print('FRONT_VIEW',scene.render.filepath)