Files
sunrise/scripts/export-summit-plateau.py

46 lines
3.6 KiB
Python

"""Export Blender-authored slab heights + one shared boundary, and the marker GLB."""
import bpy,json
import io_scene_gltf2
from pathlib import Path
ROOT=Path('D:/project/sunrise')
scene=bpy.data.scenes['Summit slab and marker'];bpy.context.window.scene=scene
slab=bpy.data.objects['SLAB_SURFACE'];outline=bpy.data.objects['WALKABLE_OUTLINE'];marker=bpy.data.objects['summit-marker']
heights=[[round(v.co.x,6),round(-v.co.y,6),round(v.co.z+620,6)] for v in slab.data.vertices]
boundary=[[round(v.co.x,4),round(-v.co.y,4)] for v in outline.data.vertices]
spec={'boundary':boundary,'heights':heights,'marker':{'assetId':'summit-marker','offset':[round(marker.location.x,4),round(-marker.location.y,4)],'blockedRadius':marker['blockedRadius']}}
spec['atlasBounds']=list(slab['atlasBounds'])
(ROOT/'src/constants/summitPlateau.ts').write_text('/** Exported from Blender. Photo-estimated slab; local east/south metres from SUMMIT_TERRAIN.start. */\nexport const SUMMIT_PLATEAU: { boundary: [number,number][]; heights: [number,number,number][]; atlasBounds: [number,number,number,number]; marker: {assetId: string; offset: [number,number]; blockedRadius: number} } = '+json.dumps(spec,separators=(',',':'))+';\n',encoding='utf-8')
for obj in scene.objects:obj.select_set(False)
for obj in [marker,*marker.children_recursive]:obj.select_set(True)
bpy.context.view_layer.objects.active=marker
location=marker.location.copy();marker.location=(0,0,0)
photo_body=bpy.data.objects.get('Photo matched summit boulder')
# Repacking an already-packed image after baking can retain its old PNG bytes.
# Refresh from the saved bake before glTF copies those bytes into the GLB.
if photo_body and photo_body.get('paintedInscription'):
images={n.image for mat in photo_body.data.materials for n in mat.node_tree.nodes
if n.type=='TEX_IMAGE' and n.image and n.image.filepath}
for image in images:
path=Path(bpy.path.abspath(image.filepath))
data=path.read_bytes()
image.pack(data=data,data_len=len(data))
image.reload()
restore=None
if photo_body and not photo_body.get('paintedInscription'):
mat=photo_body.data.materials[0]
bs=next(n for n in mat.node_tree.nodes if n.type=='BSDF_PRINCIPLED')
socket=bs.inputs['Base Color'];restore=(mat,socket,socket.links[0].from_socket)
scan=next(n for n in mat.node_tree.nodes if n.type=='TEX_IMAGE' and n.image and n.image.name.startswith('rock-color'))
mat.node_tree.links.new(scan.outputs['Color'],socket)
try:
fmt=next(item[0] for item in io_scene_gltf2.get_format_items(None,bpy.context) if item[0]=='GLB')
mode=next(i.identifier for i in bpy.ops.export_scene.gltf.get_rna_type().properties['export_materials'].enum_items if i.identifier=='EXPORT')
color_choice='NONE' if photo_body and photo_body.get('paintedInscription') else 'ACTIVE'
color_mode=next(i.identifier for i in bpy.ops.export_scene.gltf.get_rna_type().properties['export_vertex_color'].enum_items if i.identifier==color_choice)
bpy.ops.export_scene.gltf(filepath=str(ROOT/'public/models/summit/summit-marker.glb'),export_format=fmt,use_selection=True,use_active_scene=True,export_yup=True,export_apply=True,export_materials=mode,export_vertex_color=color_mode,export_all_vertex_colors=False,export_animations=False,export_cameras=False,export_lights=False)
finally:
marker.location=location
if restore:restore[0].node_tree.links.new(restore[2],restore[1])
bpy.ops.wm.save_as_mainfile(filepath=str(ROOT/'assets/summit/blender-plateau-study/summit-slab-and-marker.blend'))
print('Exported',len(heights),'heights,',len(boundary),'boundary points and summit marker')