import bpy,json,re from pathlib import Path from mathutils import Vector P=Path(__file__).resolve().parents[1];out=P/'private-assets/transfer';out.mkdir(exist_ok=True) scene=bpy.context.scene;fast=bpy.data.collections['00 FAST TOUR - lightweight viewport'];fast.hide_viewport=False;bpy.data.collections['DETAIL - full geometry for renders'].hide_viewport=False;bpy.context.view_layer.update() # Keep existing charging lead endpoint and corresponding plug together. bpy.data.objects['Tesla plugged charge connector'].location=(-2.67,-21.08,1.56) # Source file is saved with the static display and all existing tour chapters. bpy.data.collections['DETAIL - full geometry for renders'].hide_viewport=True bpy.ops.wm.save_as_mainfile(filepath=str(P/'samford-solarpunk-tesla-v008.blend')) objects=[bpy.data.objects['FAST | 38 Licensed Tesla Model 3'],bpy.data.objects['FAST | 29 Bicycles and racks']] # Transfer original mesh, source UVs and material slots. Adapt legacy Blender shaders to UE PBR. used=list(dict.fromkeys(m for o in objects for m in o.data.materials if m));mats={} for i,m in enumerate(used): n=m.name.lower();base=(.055,.055,.055,1);rough=.45;metal=0;opacity=1;coat=0 if 'car paint' in n:base=(.009,.012,.016,1);rough=.16;metal=.35;coat=1 elif 'glass' in n:base=(.035,.07,.07,1);rough=.065;opacity=.28 if 'dark' not in n else .65 elif any(s in n for s in ['steel','metal','mirror','reflection']):base=(.36,.38,.4,1);rough=.23;metal=1 elif 'wood' in n:base=(.36,.19,.08,1);rough=.48 elif 'red' in n:base=(.45,.008,.01,1);rough=.18 elif 'blinker' in n:base=(.8,.22,.012,1);rough=.18 elif any(s in n for s in ['led.front','led.bright','normal lamp']):base=(.85,.85,.82,1);rough=.14 elif 'tire' in n or 'rubber' in n:base=(.015,.018,.018,1);rough=.75 elif 'bright' in n:base=(.58,.59,.6,1);rough=.5 # Preserve original house bicycle colours using their Principled inputs. if not any(m in bpy.data.objects['FAST | 38 Licensed Tesla Model 3'].data.materials[:] for _ in [0]): bs=next((x for x in m.node_tree.nodes if x.type=='BSDF_PRINCIPLED'),None) if m.use_nodes else None if bs:base=tuple(bs.inputs['Base Color'].default_value);rough=bs.inputs['Roughness'].default_value;metal=bs.inputs['Metallic'].default_value key='M_Tesla_%02d_'%i+re.sub('[^a-zA-Z0-9_]','_',m.name) mats[key]={'source':m.name,'base_color':base,'roughness':rough,'metallic':metal,'opacity':opacity,'coat':coat} m.name=key;m.diffuse_color=base records=[] for name,o in zip(['Tesla_7K','Bicycles_preserved'],objects): o.name=name;records.append({'name':name,'materials':[m.name for m in o.data.materials]}) bpy.ops.object.select_all(action='DESELECT') for o in objects:o.select_set(True) bpy.context.view_layer.objects.active=objects[0] bpy.ops.export_scene.fbx(filepath=str(out/'TeslaGarage.fbx'),use_selection=True,object_types={'MESH'},use_mesh_modifiers=True,bake_anim=False,axis_forward='-Y',axis_up='Z',path_mode='AUTO') (out/'manifest.json').write_text(json.dumps({'materials':mats,'objects':records,'original_asset':'7K Studio Tesla Model 3','note':'Artist geometry and UVs; legacy shaders adapted to UE PBR.'},indent=2)) print('TESLA_EXPORTED',len(mats),flush=True)