import bpy
from mathutils import Vector
scene=bpy.context.scene
body=bpy.data.objects.get('Cube_2m_Through_Channel')
def aim(o,t): o.rotation_euler=(Vector(t)-o.location).to_track_quat('-Z','Y').to_euler()
# camera
cd=bpy.data.cameras.new('Presentation Camera 50mm')
cam=bpy.data.objects.new('Presentation Camera – Through Hole',cd); scene.collection.objects.link(cam)
cam.location=(4.25,-5.15,3.15); cd.lens=54; cd.clip_start=0.03; cd.clip_end=100; aim(cam,(0,0,-0.05)); scene.camera=cam
# floor
fm=bpy.data.materials.get('Studio Floor Neutral') or bpy.data.materials.new('Studio Floor Neutral'); fm.use_nodes=True
fb=fm.node_tree.nodes.get('Principled BSDF'); fb.inputs['Base Color'].default_value=(0.012,0.020,0.032,1); fb.inputs['Roughness'].default_value=0.34
bpy.ops.mesh.primitive_plane_add(size=24,location=(0,0,-1.12)); floor=bpy.context.object; floor.name='Studio Floor (below open bottom)'; floor.data.materials.append(fm)
# lights
for name,loc,energy,col,size in [('Key Warm',(4.2,-4.0,6.0),950,(1,.82,.64),4),('Fill Cool',(-4,-3,3.4),700,(.48,.68,1),3.5),('Rim Cyan',(2.2,4.5,5.5),1200,(.48,.82,1),3),('Channel Bounce',(-1.4,1,3.2),350,(.42,.70,.82),1.6)]:
    ld=bpy.data.lights.new(name,'AREA'); ld.energy=energy; ld.color=col; ld.shape='DISK'; ld.size=size
    ob=bpy.data.objects.new(name,ld); scene.collection.objects.link(ob); ob.location=loc; aim(ob,(0,0,0))
# world/render
w=bpy.data.worlds.get('World') or bpy.data.worlds.new('World'); scene.world=w; w.use_nodes=True
w.node_tree.nodes['Background'].inputs['Color'].default_value=(.004,.007,.014,1); w.node_tree.nodes['Background'].inputs['Strength'].default_value=.18
scene.render.resolution_x=1536; scene.render.resolution_y=1536; scene.render.resolution_percentage=100; scene.render.image_settings.file_format='PNG'; scene.render.film_transparent=False; scene.render.filepath='/home/oai/share/cube_hole_final.png'
try: scene.view_settings.look='AgX - Medium High Contrast'
except: pass
# metadata
body['cube_dimensions_m']=(2,2,2); body['single_finish']=True; body['modeling_note']='Applied boolean cutter removed; finished mesh; channel rims beveled'
bpy.ops.object.select_all(action='DESELECT'); body.select_set(True); bpy.context.view_layer.objects.active=body
result={'objects':[(o.name,o.type) for o in scene.objects],'camera':scene.camera.name,'body_dims':tuple(body.dimensions),'lights':len([o for o in scene.objects if o.type=='LIGHT'])}