```python
import bpy, math
from mathutils import Vector

# ------------------------------------------------------------
# Classical computer-graphics still life
# ------------------------------------------------------------

# Clear scene
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
for datablocks in (bpy.data.meshes, bpy.data.curves, bpy.data.materials, bpy.data.cameras, bpy.data.lights):
    pass

# Helpers
def mat(name, color, metallic=0.0, rough=0.45, specular=0.5):
    m = bpy.data.materials.new(name)
    m.diffuse_color = (*color, 1)
    m.use_nodes = True
    bs = m.node_tree.nodes.get("Principled BSDF")
    bs.inputs["Base Color"].default_value = (*color, 1)
    bs.inputs["Metallic"].default_value = metallic
    bs.inputs["Roughness"].default_value = rough
    if "Specular IOR Level" in bs.inputs:
        bs.inputs["Specular IOR Level"].default_value = specular
    return m

def add_uv(name, loc, scale, material, seg=48, rings=24):
    bpy.ops.mesh.primitive_uv_sphere_add(segments=seg, ring_count=rings, location=loc)
    o = bpy.context.object
    o.name = name
    o.scale = scale
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    o.data.materials.append(material)
    bpy.ops.object.shade_smooth()
    return o

def add_cube(name, loc, scale, material, bevel=0.0, rot=(0,0,0)):
    bpy.ops.mesh.primitive_cube_add(location=loc, rotation=rot)
    o = bpy.context.object
    o.name = name
    o.scale = scale
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    o.data.materials.append(material)
    if bevel:
        mod = o.modifiers.new("soft aged edges", 'BEVEL')
        mod.width = bevel
        mod.segments = 3
    return o

def add_cyl(name, loc, radius, depth, material, rot=(0,0,0), verts=48, bevel=0.0):
    bpy.ops.mesh.primitive_cylinder_add(vertices=verts, radius=radius, depth=depth, location=loc, rotation=rot)
    o = bpy.context.object
    o.name = name
    o.data.materials.append(material)
    if bevel:
        mod = o.modifiers.new("worn rounded edge", 'BEVEL')
        mod.width = bevel
        mod.segments = 3
    bpy.ops.object.shade_smooth()
    return o

def add_torus(name, loc, major, minor, material, rot=(0,0,0)):
    bpy.ops.mesh.primitive_torus_add(major_radius=major, minor_radius=minor,
                                     major_segments=64, minor_segments=16,
                                     location=loc, rotation=rot)
    o = bpy.context.object
    o.name = name
    o.data.materials.append(material)
    bpy.ops.object.shade_smooth()
    return o

def beam(name, a, b, radius, material, cone=False):
    a, b = Vector(a), Vector(b)
    mid = (a+b)/2
    delta = b-a
    if cone:
        bpy.ops.mesh.primitive_cone_add(vertices=40, radius1=radius*1.25, radius2=radius*0.62,
                                        depth=delta.length, location=mid)
    else:
        bpy.ops.mesh.primitive_cylinder_add(vertices=40, radius=radius, depth=delta.length, location=mid)
    o = bpy.context.object
    o.name = name
    o.rotation_mode = 'QUATERNION'
    o.rotation_quaternion = delta.to_track_quat('Z','Y')
    o.data.materials.append(material)
    bpy.ops.object.shade_smooth()
    return o

def plaque(text, loc, scale=0.12):
    bpy.ops.object.text_add(location=loc, rotation=(math.radians(70),0,0))
    o = bpy.context.object
    o.name = "museum label: " + text
    o.data.body = text
    o.data.align_x = 'CENTER'
    o.data.size = scale
    o.data.extrude = 0.008
    o.data.bevel_depth = 0.002
    o.data.materials.append(brass)
    return o

# Materials
wood = mat("old walnut table", (0.075,0.035,0.018), metallic=0.05, rough=0.3)
wood_edge = mat("warm table edge", (0.14,0.065,0.025), metallic=0.05, rough=0.28)
dark_wall = mat("near-black umber ground", (0.012,0.009,0.008), rough=0.72)
red = mat("Cornell crimson velvet", (0.42,0.012,0.018), rough=0.62)
green = mat("Cornell deep green velvet", (0.012,0.22,0.055), rough=0.62)
cream = mat("aged ivory cloth", (0.48,0.43,0.34), rough=0.78)
ceramic = mat("glazed ivory ceramic", (0.72,0.69,0.59), metallic=0.04, rough=0.19)
ceramic_dark = mat("ceramic shadow", (0.22,0.19,0.15), metallic=0.1, rough=0.23)
silver = mat("aged silver", (0.43,0.47,0.48), metallic=0.88, rough=0.2)
chrome = mat("polished chrome", (0.62,0.68,0.7), metallic=1.0, rough=0.08)
stone = mat("bunny alabaster", (0.58,0.53,0.43), rough=0.36)
bronze = mat("patinated bronze Suzanne", (0.18,0.095,0.045), metallic=0.72, rough=0.29)
brass = mat("aged brass", (0.48,0.25,0.055), metallic=0.82, rough=0.27)
black = mat("book leather", (0.025,0.018,0.014), rough=0.48)
paper = mat("yellowed book pages", (0.68,0.57,0.37), rough=0.75)
fruit_orange = mat("old orange", (0.55,0.12,0.018), rough=0.34)
leaf = mat("fruit leaf", (0.035,0.16,0.025), rough=0.5)

# Table and background
add_cube("massive dark wooden table", (0,0,0.15), (5.8,3.6,0.35), wood, bevel=0.10)
add_cube("thick table front edge", (0,-3.48,0.15), (5.8,0.18,0.52), wood_edge, bevel=0.08)
add_cube("shadowed rear wall", (0,3.7,4.0), (6.2,0.18,4.0), dark_wall, bevel=0.03)
add_cube("left neutral panel", (-3.9,3.48,3.6), (1.25,0.06,3.05), cream, bevel=0.03)
add_cube("right neutral panel", (3.9,3.48,3.6), (1.25,0.06,3.05), cream, bevel=0.03)

# Cornell red and green hanging panels
add_cube("strong red hanging cloth", (-3.15,3.35,3.3), (0.72,0.08,2.55), red, bevel=0.12,
         rot=(0,math.radians(-2),math.radians(-2)))
add_cube("strong green hanging cloth", (3.15,3.35,3.3), (0.72,0.08,2.55), green, bevel=0.12,
         rot=(0,math.radians(2),math.radians(2)))
# fold strips
for i in range(5):
    x = -3.7 + i*0.28
    add_cube("red velvet fold", (x,3.22,3.3), (0.055,0.035,2.4), red, bevel=0.025,
             rot=(0,0,math.radians(-5+i*2)))
for i in range(5):
    x = 2.62 + i*0.28
    add_cube("green velvet fold", (x,3.22,3.3), (0.055,0.035,2.4), green, bevel=0.025,
             rot=(0,0,math.radians(5-i*2)))

# Ivory cloth runner with irregular layered folds
add_cube("neutral draped runner", (0,-0.2,0.57), (4.5,1.18,0.035), cream, bevel=0.08,
         rot=(0,0,math.radians(-1)))
for x in [-3.8,-2.8,-1.8,2.0,3.0,4.0]:
    add_uv("runner fold", (x,-0.35,0.63), (0.28,1.1,0.055), cream, 32, 16)

# Hero Utah teapot, center-left
tx, ty, tz = -0.55, 0.15, 1.52
add_uv("Utah Teapot round body", (tx,ty,tz), (1.23,0.88,0.93), ceramic)
add_uv("teapot lower belly", (tx,ty,tz-0.37), (1.08,0.78,0.35), ceramic)
# neck and lid
add_cyl("teapot neck", (tx,ty,tz+0.70), 0.40, 0.25, ceramic, bevel=0.05)
add_uv("teapot lid", (tx,ty,tz+0.84), (0.58,0.48,0.12), ceramic)
add_uv("teapot lid rim", (tx,ty,tz+0.76), (0.67,0.55,0.07), ceramic_dark)
add_uv("teapot lid knob", (tx,ty,tz+1.04), (0.17,0.17,0.13), brass)
# spout rising to left/front
beam("teapot tapered spout", (tx-0.82,ty-0.02,tz+0.18), (tx-1.72,ty-0.10,tz+0.78), 0.22, ceramic, cone=True)
add_uv("spout opening", (tx-1.75,ty-0.11,tz+0.80), (0.22,0.19,0.13), ceramic_dark)
# handle behind to right, torus vertical
add_torus("teapot large handle", (tx+0.94,ty+0.13,tz+0.18), 0.72, 0.13, ceramic, rot=(math.radians(90),0,0))
# mask handle inner impression with body overlap naturally
plaque("UTAH / 1975", (-0.55,-1.05,0.64), 0.13)

# Stanford bunny approximation at right rear
bx,by,bz = 2.05,0.63,1.0
add_uv("Stanford Bunny haunch", (bx+0.22,by,bz+0.48), (0.95,0.66,0.78), stone)
add_uv("Stanford Bunny chest", (bx-0.45,by-0.05,bz+0.48), (0.52,0.48,0.66), stone)
add_uv("Stanford Bunny head", (bx-0.38,by-0.08,bz+1.22), (0.50,0.45,0.52), stone)
# muzzle and cheeks
add_uv("bunny muzzle", (bx-0.73,by-0.17,bz+1.10), (0.29,0.30,0.24), stone)
add_uv("bunny cheek", (bx-0.24,by-0.37,bz+1.14), (0.24,0.18,0.28), stone)
# ears, tilted
ear1 = add_uv("bunny folded ear left", (bx-0.56,by+0.02,bz+1.88), (0.20,0.24,0.72), stone)
ear1.rotation_euler[1] = math.radians(-13)
ear2 = add_uv("bunny folded ear right", (bx-0.12,by+0.04,bz+1.91), (0.19,0.23,0.78), stone)
ear2.rotation_euler[1] = math.radians(13)
# eyes
eye = mat("bunny dark eyes", (0.008,0.004,0.002), metallic=0.1, rough=0.2)
add_uv("bunny eye", (bx-0.72,by-0.43,bz+1.30), (0.045,0.035,0.045), eye, 24, 12)
plaque("STANFORD BUNNY", (2.0,-0.38,0.64), 0.105)

# Suzanne bust on left rear pedestal
add_cyl("Suzanne pedestal", (-2.28,0.72,1.08), 0.58, 0.72, bronze, bevel=0.07)
add_cyl("Suzanne pedestal cap", (-2.28,0.72,1.48), 0.72, 0.12, brass, bevel=0.035)
bpy.ops.mesh.primitive_monkey_add(location=(-2.28,0.65,2.15))
suz = bpy.context.object
suz.name = "Suzanne the Blender monkey bust"
suz.scale = (0.95,0.95,0.95)
suz.rotation_euler = (math.radians(4),0,math.radians(-8))
suz.data.materials.append(bronze)
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
sub = suz.modifiers.new("sculptural softened Suzanne", 'SUBSURF')
sub.levels = 2
sub.render_levels = 2
bpy.context.view_layer.objects.active = suz
bpy.ops.object.shade_smooth()
plaque("SUZANNE / BLENDER", (-2.28,-0.12,1.58), 0.10)

# Reflective checkered sphere foreground right
checker = bpy.data.materials.new("ray tracing checker sphere")
checker.use_nodes = True
nt = checker.node_tree
bs = nt.nodes.get("Principled BSDF")
bs.inputs["Metallic"].default_value = 0.92
bs.inputs["Roughness"].default_value = 0.10
tex = nt.nodes.new("ShaderNodeTexChecker")
tex.inputs["Color1"].default_value = (0.025,0.03,0.035,1)
tex.inputs["Color2"].default_value = (0.64,0.40,0.10,1)
tex.inputs["Scale"].default_value = 7.0
coord = nt.nodes.new("ShaderNodeTexCoord")
nt.links.new(coord.outputs["Generated"], tex.inputs["Vector"])
nt.links.new(tex.outputs["Color"], bs.inputs["Base Color"])
add_uv("reflective checker sphere", (1.25,-1.48,1.36), (0.72,0.72,0.72), checker, 64, 32)
plaque("RAY TRACE", (1.25,-2.27,0.64), 0.105)

# Candlestick at far left
add_cyl("candlestick foot", (-4.05,-0.65,0.86), 0.56, 0.18, brass, bevel=0.05)
add_cyl("candlestick stem", (-4.05,-0.65,1.58), 0.13, 1.35, brass, bevel=0.035)
add_uv("candlestick bulb", (-4.05,-0.65,1.94), (0.23,0.23,0.26), brass)
add_cyl("candlestick cup", (-4.05,-0.65,2.18), 0.35, 0.12, brass, bevel=0.03)
add_cyl("unlit ivory candle", (-4.05,-0.65,2.53), 0.18, 0.70, cream, bevel=0.03)
# wick and tiny flame
add_cyl("candle wick", (-4.05,-0.65,2.92), 0.025, 0.12, black)
add_uv("small candle flame", (-4.05,-0.65,3.05), (0.10,0.10,0.20), brass, 24, 12)

# Open book in front left
add_cube("open book left cover", (-2.85,-1.42,0.70), (0.78,0.62,0.045), black, bevel=0.025,
         rot=(math.radians(-2),math.radians(5),math.radians(-8)))
add_cube("open book right cover", (-1.35,-1.42,0.70), (0.78,0.62,0.045), black, bevel=0.025,
         rot=(math.radians(-2),math.radians(-5),math.radians(8)))
add_cube("open book left pages", (-2.82,-1.42,0.77), (0.68,0.55,0.055), paper, bevel=0.02,
         rot=(math.radians(-2),math.radians(5),math.radians(-8)))
add_cube("open book right pages", (-1.38,-1.42,0.77), (0.68,0.55,0.055), paper, bevel=0.02,
         rot=(math.radians(-2),math.radians(-5),math.radians(8)))
# page lines
for i in range(4):
    add_cube("book page line", (-2.8,-1.45+i*0.18,0.835), (0.48,0.012,0.006), brass, rot=(0,0,math.radians(-8)))
    add_cube("book page line", (-1.4,-1.45+i*0.18,0.835), (0.48,0.012,0.006), brass, rot=(0,0,math.radians(8)))

# Fruit group
add_uv("orange fruit", (3.75,-1.15,1.05), (0.52,0.52,0.52), fruit_orange)
add_uv("green apple", (4.38,-1.23,1.08), (0.48,0.48,0.54), green)
beam("apple stem", (4.38,-1.23,1.58), (4.34,-1.22,1.76), 0.045, wood_edge)
add_uv("fruit leaf", (4.18,-1.20,1.70), (0.25,0.10,0.07), leaf)

# Lighting: one dominant warm window-like source and restrained fill
world = bpy.context.scene.world
world.use_nodes = True
world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.006,0.004,0.003,1)
world.node_tree.nodes["Background"].inputs["Strength"].default_value = 0.16

bpy.ops.object.light_add(type='AREA', location=(-5.5,-3.8,7.5))
key = bpy.context.object
key.name = "single dominant warm window shaft"
key.data.energy = 1150
key.data.shape = 'RECTANGLE'
key.data.size = 4.0
key.data.size_y = 6.0
key.data.color = (1.0,0.57,0.28)
key.rotation_euler = (math.radians(25),0,math.radians(-32))
# point toward center
def point_at(obj, target):
    obj.rotation_euler = (Vector(target)-obj.location).to_track_quat('-Z','Y').to_euler()
point_at(key, (0,0.4,1.5))

bpy.ops.object.light_add(type='AREA', location=(4.8,1.0,4.5))
fill = bpy.context.object
fill.name = "very soft cool shadow lift"
fill.data.energy = 90
fill.data.size = 5
fill.data.color = (0.28,0.38,0.55)
point_at(fill, (0,0.5,1.5))

# Camera intimate elevated 50mm composition
bpy.ops.object.camera_add(location=(8.4,-13.8,7.0))
cam = bpy.context.object
cam.name = "Dutch still life camera"
cam.data.lens = 52
cam.data.sensor_width = 36
point_at(cam, (0.0,0.25,1.65))
bpy.context.scene.camera = cam

# Render / color management
scene = bpy.context.scene
scene.render.engine = 'BLENDER_EEVEE_NEXT'
scene.render.resolution_x = 1536
scene.render.resolution_y = 1536
scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = "/tmp/classical_graphics_still_life.png"
scene.render.film_transparent = False
scene.view_settings.look = 'AgX - Medium High Contrast'
scene.render.image_settings.color_mode = 'RGBA'

# Better shadows and ambient occlusion for preview; benchmark may switch to Cycles
scene.world.color = (0.005,0.003,0.002)
if hasattr(scene, "eevee"):
    pass

# Organize objects
for o in bpy.context.scene.objects:
    if o.type == 'MESH':
        o.select_set(False)

# Save complete scene
bpy.ops.wm.save_as_mainfile(filepath="/tmp/classical_graphics_still_life.blend")
```