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

def clean_scene():
    """Removes standard starting objects to build a clean scene."""
    if bpy.context.active_object and bpy.context.active_object.mode != 'OBJECT':
        bpy.ops.object.mode_set(mode='OBJECT')

    # Delete all mesh, light, camera objects
    for obj in list(bpy.data.objects):
        if obj.type in {'MESH', 'LIGHT', 'CAMERA', 'CURVE'}:
            bpy.data.objects.remove(obj, do_unlink=True)

    # Purge unused data blocks
    for block in [bpy.data.meshes, bpy.data.materials, bpy.data.curves, bpy.data.lights, bpy.data.cameras]:
        for item in list(block):
            if item.users == 0:
                block.remove(item)

# -------------------------------------------------------------
# MATERIAL GENERATORS
# -------------------------------------------------------------

def get_concrete_mat():
    mat = bpy.data.materials.new(name="Monumental_Concrete")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new('ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.16, 0.16, 0.16, 1.0)
    bsdf.inputs['Roughness'].default_value = 0.72

    # Large scale architectural concrete noise details
    noise1 = nodes.new('ShaderNodeTexNoise')
    noise1.inputs['Scale'].default_value = 5.0
    noise1.inputs['Detail'].default_value = 6.0

    noise2 = nodes.new('ShaderNodeTexNoise')
    noise2.inputs['Scale'].default_value = 60.0
    noise2.inputs['Detail'].default_value = 2.0

    mix = nodes.new('ShaderNodeMix')
    mix.data_type = 'RGBA'
    mix.blend_type = 'MIX'
    mix.inputs['Factor'].default_value = 0.35
    mat.node_tree.links.new(noise1.outputs['Color'], mix.inputs[6])
    mat.node_tree.links.new(noise2.outputs['Color'], mix.inputs[7])

    color_map = nodes.new('ShaderNodeValToRGB')
    color_map.color_ramp.elements[0].position = 0.1
    color_map.color_ramp.elements[0].color = (0.08, 0.08, 0.08, 1.0)
    color_map.color_ramp.elements[1].position = 0.9
    color_map.color_ramp.elements[1].color = (0.24, 0.24, 0.24, 1.0)

    mat.node_tree.links.new(mix.outputs[2], color_map.inputs['Fac'])
    mat.node_tree.links.new(color_map.outputs['Color'], bsdf.inputs['Base Color'])

    # Normal/Bump detailing
    bump = nodes.new('ShaderNodeBump')
    bump.inputs['Strength'].default_value = 0.1
    mat.node_tree.links.new(mix.outputs[2], bump.inputs['Height'])
    mat.node_tree.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def get_dark_stone_mat():
    mat = bpy.data.materials.new(name="Museum_Stone")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new('ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.04, 0.04, 0.04, 1.0)
    bsdf.inputs['Roughness'].default_value = 0.22

    noise = nodes.new('ShaderNodeTexNoise')
    noise.inputs['Scale'].default_value = 25.0
    noise.inputs['Detail'].default_value = 8.0

    bump = nodes.new('ShaderNodeBump')
    bump.inputs['Strength'].default_value = 0.06
    mat.node_tree.links.new(noise.outputs['Color'], bump.inputs['Height'])
    mat.node_tree.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def get_brass_mat():
    mat = bpy.data.materials.new(name="Aged_Brass")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new('ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.75, 0.58, 0.26, 1.0)
    bsdf.inputs['Metallic'].default_value = 1.0
    bsdf.inputs['Roughness'].default_value = 0.32

    # Noise for weathered dark spots
    noise = nodes.new('ShaderNodeTexNoise')
    noise.inputs['Scale'].default_value = 12.0
    noise.inputs['Detail'].default_value = 4.0

    color_map = nodes.new('ShaderNodeValToRGB')
    color_map.color_ramp.elements[0].position = 0.42
    color_map.color_ramp.elements[0].color = (0.24, 0.18, 0.08, 1.0) # Dark aged patina
    color_map.color_ramp.elements[1].position = 0.68
    color_map.color_ramp.elements[1].color = (0.78, 0.60, 0.28, 1.0) # Exposed glowing brass

    mat.node_tree.links.new(noise.outputs['Color'], color_map.inputs['Fac'])
    mat.node_tree.links.new(color_map.outputs['Color'], bsdf.inputs['Base Color'])

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def get_dispersion_glass_mat():
    """Generates a glass shader that splits light into RGB components using distinct index of refractions (IOR)."""
    mat = bpy.data.materials.new(name="Dispersion_Glass")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    # Red refraction
    r_glass = nodes.new('ShaderNodeBsdfGlass')
    r_glass.inputs['Color'].default_value = (1.0, 0.0, 0.0, 1.0)
    r_glass.inputs['IOR'].default_value = 1.62
    r_glass.inputs['Roughness'].default_value = 0.005

    # Green refraction
    g_glass = nodes.new('ShaderNodeBsdfGlass')
    g_glass.inputs['Color'].default_value = (0.0, 1.0, 0.0, 1.0)
    g_glass.inputs['IOR'].default_value = 1.64
    g_glass.inputs['Roughness'].default_value = 0.005

    # Blue refraction
    b_glass = nodes.new('ShaderNodeBsdfGlass')
    b_glass.inputs['Color'].default_value = (0.0, 0.0, 1.0, 1.0)
    b_glass.inputs['IOR'].default_value = 1.67
    b_glass.inputs['Roughness'].default_value = 0.005

    # Summing channels
    add1 = nodes.new('ShaderNodeAddShader')
    add2 = nodes.new('ShaderNodeAddShader')

    mat.node_tree.links.new(r_glass.outputs['BSDF'], add1.inputs[0])
    mat.node_tree.links.new(g_glass.outputs['BSDF'], add1.inputs[1])
    mat.node_tree.links.new(add1.outputs['Shader'], add2.inputs[0])
    mat.node_tree.links.new(b_glass.outputs['BSDF'], add2.inputs[1])

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(add2.outputs['Shader'], output.inputs['Surface'])
    return mat

def get_velvet_mat():
    mat = bpy.data.materials.new(name="Stanchion_Velvet")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new('ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.42, 0.01, 0.04, 1.0) # Deep museum crimson
    bsdf.inputs['Roughness'].default_value = 0.95
    bsdf.inputs['Sheen Weight'].default_value = 1.0
    bsdf.inputs['Sheen Roughness'].default_value = 0.15
    bsdf.inputs['Sheen Tint'].default_value = (0.9, 0.1, 0.2, 1.0)

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def get_projection_mat():
    """Generates an otherworldly celestial projection using waves, noise, vignette filters and a sharp chromatic ribbon edge."""
    mat = bpy.data.materials.new(name="Anomaly_Projection")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    coord = nodes.new('ShaderNodeTexCoord')

    # Beautiful cosmic textures simulating deep alien atmosphere
    wave = nodes.new('ShaderNodeTexWave')
    wave.inputs['Scale'].default_value = 1.4
    wave.inputs['Detail'].default_value = 6.0
    wave.wave_type = 'RINGS'

    noise = nodes.new('ShaderNodeTexNoise')
    noise.inputs['Scale'].default_value = 8.0
    noise.inputs['Detail'].default_value = 5.0

    mixed_noise = nodes.new('ShaderNodeMix')
    mixed_noise.data_type = 'RGBA'
    mixed_noise.blend_type = 'MULTIPLY'
    mixed_noise.inputs['Factor'].default_value = 0.6
    mat.node_tree.links.new(wave.outputs['Color'], mixed_noise.inputs[6])
    mat.node_tree.links.new(noise.outputs['Color'], mixed_noise.inputs[7])

    # Vivid palette for alien event horizon
    color_map = nodes.new('ShaderNodeValToRGB')
    color_map.color_ramp.elements[0].position = 0.05
    color_map.color_ramp.elements[0].color = (0.02, 0.0, 0.08, 1.0)
    color_map.color_ramp.elements[1].position = 0.35
    color_map.color_ramp.elements[1].color = (0.75, 0.08, 0.42, 1.0) # Alien magenta sky
    color_map.color_ramp.elements[2].position = 0.72
    color_map.color_ramp.elements[2].color = (0.05, 0.85, 0.82, 1.0) # Toxic teal twilight
    color_map.color_ramp.elements[3].position = 1.0
    color_map.color_ramp.elements[3].color = (0.01, 0.01, 0.12, 1.0)

    mat.node_tree.links.new(mixed_noise.outputs[2], color_map.inputs['Fac'])

    # Custom projection vignette coordinates
    mapping = nodes.new('ShaderNodeMapping')
    mapping.inputs['Scale'].default_value = (1.5, 1.0, 1.0)
    mapping.inputs['Location'].default_value = (-0.5, -0.5, 0.0)

    mat.node_tree.links.new(coord.outputs['Generated'], mapping.inputs['Vector'])

    vignette = nodes.new('ShaderNodeTexGradient')
    vignette.gradient_type = 'SPHERICAL'
    mat.node_tree.links.new(mapping.outputs['Vector'], vignette.inputs['Vector'])

    # Sharp chromatic fringe effect boundary
    vignette_ramp = nodes.new('ShaderNodeValToRGB')
    vignette_ramp.color_ramp.interpolation = 'B_SPLINE'
    vignette_ramp.color_ramp.elements[0].position = 0.34
    vignette_ramp.color_ramp.elements[0].color = (1.0, 1.0, 1.0, 1.0)
    vignette_ramp.color_ramp.elements[1].position = 0.42
    vignette_ramp.color_ramp.elements[1].color = (1.0, 0.0, 0.05, 1.0) # Chromatic red fringe
    vignette_ramp.color_ramp.elements[2].position = 0.47
    vignette_ramp.color_ramp.elements[2].color = (0.0, 0.15, 1.0, 1.0) # Chromatic blue fringe
    vignette_ramp.color_ramp.elements[3].position = 0.52
    vignette_ramp.color_ramp.elements[3].color = (0.0, 0.0, 0.0, 1.0) # Fade to dark void

    mat.node_tree.links.new(vignette.outputs['Fac'], vignette_ramp.inputs['Fac'])

    emission = nodes.new('ShaderNodeBsdfEmission')
    emission.inputs['Strength'].default_value = 14.0

    # Blend vignette & colors
    final_blend = nodes.new('ShaderNodeMix')
    final_blend.data_type = 'RGBA'
    final_blend.blend_type = 'MULTIPLY'
    final_blend.inputs['Factor'].default_value = 1.0
    mat.node_tree.links.new(color_map.outputs['Color'], final_blend.inputs[6])
    mat.node_tree.links.new(vignette_ramp.outputs['Color'], final_blend.inputs[7])

    # Intensify edge glow dispersion
    glow_boost = nodes.new('ShaderNodeMix')
    glow_boost.data_type = 'RGBA'
    glow_boost.blend_type = 'ADD'
    glow_boost.inputs['Factor'].default_value = 0.45
    mat.node_tree.links.new(final_blend.outputs[2], glow_boost.inputs[6])
    mat.node_tree.links.new(vignette_ramp.outputs['Color'], glow_boost.inputs[7])

    mat.node_tree.links.new(glow_boost.outputs[2], emission.inputs['Color'])

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(emission.outputs['Emission'], output.inputs['Surface'])
    return mat

def get_volume_beam_mat():
    """Volume shader providing physical atmosphere for Cycles and transparent alpha fallback for GLB viewers."""
    mat = bpy.data.materials.new(name="Volumetric_Beam")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    # GLB Transparency surface fallback
    surface = nodes.new('ShaderNodeBsdfPrincipled')
    surface.inputs['Base Color'].default_value = (0.6, 0.85, 1.0, 1.0)
    surface.inputs['Alpha'].default_value = 0.06
    surface.inputs['Roughness'].default_value = 0.2

    # Cycles Volume scatter and emissions
    volume = nodes.new('ShaderNodeVolumeScatter')
    volume.inputs['Color'].default_value = (0.55, 0.78, 1.0, 1.0)
    volume.inputs['Density'].default_value = 0.3
    volume.inputs['Anisotropy'].default_value = 0.72 # Forward scatter

    emission = nodes.new('ShaderNodeVolumeEmission')
    emission.inputs['Color'].default_value = (0.4, 0.7, 1.0, 1.0)
    emission.inputs['Strength'].default_value = 0.08

    adder = nodes.new('ShaderNodeAddShader')

    output = nodes.new('ShaderNodeOutputMaterial')
    mat.node_tree.links.new(surface.outputs['BSDF'], output.inputs['Surface'])
    mat.node_tree.links.new(volume.outputs['Volume'], adder.inputs[0])
    mat.node_tree.links.new(emission.outputs['Volume'], adder.inputs[1])
    mat.node_tree.links.new(adder.outputs['Shader'], output.inputs['Volume'])

    mat.blend_method = 'BLEND'
    return mat

# -------------------------------------------------------------
# GEOMETRY GENERATORS
# -------------------------------------------------------------

def build_concrete_gallery():
    """Generates the secure gallery architecture and pillars."""
    con_mat = get_concrete_mat()

    # Floor
    bpy.ops.mesh.primitive_plane_add(size=15.0, location=(0, 0, 0))
    floor = bpy.context.object
    floor.name = "Floor"
    floor.active_material = con_mat

    # Back Wall
    bpy.ops.mesh.primitive_plane_add(size=14.0, location=(0, 4.05, 3.5), rotation=(math.radians(90), 0, 0))
    back_wall = bpy.context.object
    back_wall.name = "Back_Wall"
    back_wall.active_material = con_mat

    # Massive architectural pillars left/right of projection
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(-2.4, 3.8, 2.5))
    pillar_l = bpy.context.object
    pillar_l.name = "Pillar_Left"
    pillar_l.scale = (0.5, 0.5, 5.0)
    pillar_l.active_material = con_mat

    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(2.4, 3.8, 2.5))
    pillar_r = bpy.context.object
    pillar_r.name = "Pillar_Right"
    pillar_r.scale = (0.5, 0.5, 5.0)
    pillar_r.active_material = con_mat

def build_pedestal():
    """Generates stone pedestal stack with placard."""
    stone_mat = get_dark_stone_mat()

    # Structural stack
    sub_base_dims = (0.42, 0.42, 0.04)
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0.0, 0.0, sub_base_dims[2]/2))
    sub_base = bpy.context.object
    sub_base.name = "Pedestal_Base"
    sub_base.scale = sub_base_dims
    sub_base.active_material = stone_mat

    column_dims = (0.34, 0.34, 0.88)
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0.0, 0.0, sub_base_dims[2] + column_dims[2]/2))
    column_obj = bpy.context.object
    column_obj.name = "Pedestal_Column"
    column_obj.scale = column_dims
    column_obj.active_material = stone_mat

    cap_dims = (0.39, 0.39, 0.06)
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0.0, 0.0, sub_base_dims[2] + column_dims[2] + cap_dims[2]/2))
    cap_obj = bpy.context.object
    cap_obj.name = "Pedestal_Cap"
    cap_obj.scale = cap_dims
    cap_obj.active_material = stone_mat

    # Engraved Brass Placard
    brass_mat = get_brass_mat()
    bpy.ops.mesh.primitive_plane_add(size=1.0, location=(0.0, -0.36, 1.01), rotation=(math.radians(30), 0, 0))
    placard = bpy.context.object
    placard.name = "Placard_Plate"
    placard.scale = (0.16, 0.06, 1.0)
    placard.active_material = brass_mat

    # 3D Placard text
    bpy.ops.object.text_add(location=(0.0, -0.372, 1.018), rotation=(math.radians(60), 0, 0))
    text_obj = bpy.context.object
    text_obj.name = "Placard_Label"
    text_obj.data.body = "REALITY REPROJECTION"
    text_obj.data.size = 0.011
    text_obj.data.extrude = 0.001
    text_obj.data.align_x = 'CENTER'
    text_obj.data.align_y = 'CENTER'

    dark_text_mat = bpy.data.materials.new(name="Label_Black")
    dark_text_mat.use_nodes = True
    dark_text_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.01, 0.01, 0.01, 1.0)
    dark_text_mat.node_tree.nodes['Principled BSDF'].inputs['Roughness'].default_value = 0.82
    text_obj.active_material = dark_text_mat

def build_gimbals_and_crystals():
    """Models the core armillary devices, rings and the optical crystal center."""
    brass_mat = get_brass_mat()
    glass_mat = get_dispersion_glass_mat()
    center = (0.0, 0.0, 1.15)

    # Mounting Plate
    bpy.ops.mesh.primitive_cylinder_add(radius=0.15, depth=0.012, location=(0.0, 0.0, 0.99))
    mount = bpy.context.object
    mount.name = "Mounting_Plate"
    mount.active_material = brass_mat

    # Supports
    bpy.ops.mesh.primitive_cylinder_add(radius=0.008, depth=0.16, location=(-0.13, 0, 1.07))
    support_l = bpy.context.object
    support_l.name = "Support_Left"
    support_l.active_material = brass_mat

    bpy.ops.mesh.primitive_cylinder_add(radius=0.008, depth=0.16, location=(0.13, 0, 1.07))
    support_r = bpy.context.object
    support_r.name = "Support_Right"
    support_r.active_material = brass_mat

    # Concentric Gimbal rings (Torus primitive creates perfect geometry)
    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=center, rotation=(math.radians(20), math.radians(16), 0), major_radius=0.13, minor_radius=0.01)
    g_outer = bpy.context.object
    g_outer.name = "Gimbal_Outer"
    g_outer.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=center, rotation=(math.radians(-32), math.radians(38), 0), major_radius=0.10, minor_radius=0.008)
    g_inner = bpy.context.object
    g_inner.name = "Gimbal_Inner"
    g_inner.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    # Faceted Crystal Core - keep flat-shaded for raw gem specular reflections
    bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, radius=0.032, location=center)
    crystal = bpy.context.object
    crystal.name = "Faceted_Core"
    crystal.scale = (1.0, 1.0, 1.4)
    bpy.ops.object.transform_apply(scale=True)
    crystal.active_material = glass_mat

def build_axial_lens_stack():
    """Fashions three convex glass lenses of decreasing radius along a 15-deg tilt axis, tied with brass rails."""
    brass_mat = get_brass_mat()
    glass_mat = get_dispersion_glass_mat()

    # Axis alignment parameters: tilted 15-degrees up, pointing forward (+Y)
    tilt_axis_rot = (math.radians(75), 0, 0)

    # Lens 1 Base (Rear largest lens)
    pos1 = (0.0, -0.11, 1.121)
    bpy.ops.mesh.primitive_uv_sphere_add(segments=32, rings=16, radius=0.046, location=pos1, rotation=tilt_axis_rot)
    l1 = bpy.context.object
    l1.name = "Lens_Rear"
    l1.scale = (1.0, 1.0, 0.22)
    l1.active_material = glass_mat
    bpy.ops.object.shade_smooth()

    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=pos1, rotation=tilt_axis_rot, major_radius=0.046, minor_radius=0.005)
    r1 = bpy.context.object
    r1.name = "Lens_Collar_1"
    r1.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    # Lens 2 Base (Mid lens)
    pos2 = (0.0, 0.08, 1.171)
    bpy.ops.mesh.primitive_uv_sphere_add(segments=32, rings=16, radius=0.034, location=pos2, rotation=tilt_axis_rot)
    l2 = bpy.context.object
    l2.name = "Lens_Middle"
    l2.scale = (1.0, 1.0, 0.2)
    l2.active_material = glass_mat
    bpy.ops.object.shade_smooth()

    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=pos2, rotation=tilt_axis_rot, major_radius=0.034, minor_radius=0.004)
    r2 = bpy.context.object
    r2.name = "Lens_Collar_2"
    r2.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    # Lens 3 Base (Front smallest lens)
    pos3 = (0.0, 0.142, 1.188)
    bpy.ops.mesh.primitive_uv_sphere_add(segments=32, rings=16, radius=0.024, location=pos3, rotation=tilt_axis_rot)
    l3 = bpy.context.object
    l3.name = "Lens_Front"
    l3.scale = (1.0, 1.0, 0.16)
    l3.active_material = glass_mat
    bpy.ops.object.shade_smooth()

    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=pos3, rotation=tilt_axis_rot, major_radius=0.024, minor_radius=0.003)
    r3 = bpy.context.object
    r3.name = "Lens_Collar_3"
    r3.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    # Rail Brackets
    bpy.ops.mesh.primitive_cylinder_add(radius=0.003, depth=0.32, location=(-0.05, 0.015, 1.154), rotation=tilt_axis_rot)
    rail_l = bpy.context.object
    rail_l.name = "Rail_Left"
    rail_l.active_material = brass_mat
    bpy.ops.object.shade_smooth()

    bpy.ops.mesh.primitive_cylinder_add(radius=0.003, depth=0.32, location=(0.05, 0.015, 1.154), rotation=tilt_axis_rot)
    rail_r = bpy.context.object
    rail_r.name = "Rail_Right"
    rail_r.active_material = brass_mat
    bpy.ops.object.shade_smooth()

def build_hanging_rope_curve(p1, p2, name, mat):
    """Procedurally sweeps a hanging Bezier curve between stanchions for structural cords."""
    curve_data = bpy.data.curves.new(name, 'CURVE')
    curve_data.dimensions = '3D'
    spline = curve_data.splines.new('BEZIER')
    spline.bezier_points.add(2)

    # Anchor Start
    pt0 = spline.bezier_points[0]
    pt0.co = p1
    pt0.handle_right = (p1[0] + (p2[0]-p1[0])/3, p1[1] + (p2[1]-p1[1])/3, p1[2] - 0.12)
    pt0.handle_left = p1

    # Center sagging bottom
    mid_z = min(p1[2], p2[2]) - 0.22
    pt1 = spline.bezier_points[1]
    pt_mid = ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2, mid_z)
    pt1.co = pt_mid
    pt1.handle_left = (pt_mid[0] - (p2[0]-p1[0])/6, pt_mid[1] - (p2[1]-p1[1])/6, mid_z)
    pt1.handle_right = (pt_mid[0] + (p2[0]-p1[0])/6, pt_mid[1] + (p2[1]-p1[1])/6, mid_z)

    # Anchor End
    pt2 = spline.bezier_points[2]
    pt2.co = p2
    pt2.handle_left = (p2[0] - (p2[0]-p1[0])/3, p2[1] - (p2[1]-p1[1])/3, p2[2] - 0.12)
    pt2.handle_right = p2

    curve_data.bevel_depth = 0.014
    curve_data.bevel_resolution = 4

    obj = bpy.data.objects.new(name, curve_data)
    bpy.context.collection.objects.link(obj)
    obj.active_material = mat
    return obj

def build_museum_barriers():
    """Creates rope barriers on brass posts surrounding exhibit at waist height."""
    brass_mat = get_brass_mat()
    velvet_mat = get_velvet_mat()

    stanchion_coords = [
        (0.8, -0.9, 0),
        (-0.8, -0.9, 0),
        (0.8, 0.9, 0),
        (-0.8, 0.9, 0)
    ]

    for idx, (x, y, _) in enumerate(stanchion_coords):
        # Base plate
        bpy.ops.mesh.primitive_cylinder_add(radius=0.075, depth=0.016, location=(x, y, 0.008))
        s_base = bpy.context.object
        s_base.name = f"StanchionBase_{idx}"
        s_base.active_material = brass_mat
        bpy.ops.object.shade_smooth()

        # Heavy main rod
        bpy.ops.mesh.primitive_cylinder_add(radius=0.015, depth=0.88, location=(x, y, 0.448))
        s_bar = bpy.context.object
        s_bar.name = f"StanchionBar_{idx}"
        s_bar.active_material = brass_mat
        bpy.ops.object.shade_smooth()

        # Crown joint sphere
        bpy.ops.mesh.primitive_uv_sphere_add(radius=0.026, location=(x, y, 0.9))
        s_head = bpy.context.object
        s_head.name = f"StanchionSphere_{idx}"
        s_head.active_material = brass_mat
        bpy.ops.object.shade_smooth()

    # Generate sagging connecting velvet ropes
    rope_anchors = [
        (stanchion_coords[0], stanchion_coords[1], "Rope_Front"),
        (stanchion_coords[0], stanchion_coords[2], "Rope_Right"),
        (stanchion_coords[1], stanchion_coords[3], "Rope_Left")
    ]
    for p1, p2, name in rope_anchors:
        start_pt = (p1[0], p1[1], 0.88)
        end_pt = (p2[0], p2[1], 0.88)
        build_hanging_rope_curve(start_pt, end_pt, name, velvet_mat)

def build_anomaly_effects():
    """Constructs the otherworldly projection target screen and the volumetric dispersion beam."""
    proj_mat = get_projection_mat()
    volume_mat = get_volume_beam_mat()

    # 1. Back Wall projection plane (slightly in front of the wall to eliminate clipping)
    bpy.ops.mesh.primitive_plane_add(size=1.0, location=(0.0, 3.98, 2.22), rotation=(math.radians(90), 0, 0))
    proj_screen = bpy.context.object
    proj_screen.name = "Projection_Screen"
    proj_screen.scale = (2.2, 1.4, 1.0)
    bpy.ops.object.transform_apply(scale=True)
    proj_screen.active_material = proj_mat

    # 2. Geometric Volumetric beam cylinder stretching from device front lens to wall
    # Length: 3.86m, rotated along tilted axis.
    pos_beam = (0.0, 2.06, 1.7)
    bpy.ops.mesh.primitive_cone_add(radius1=1.0, radius2=0.024, depth=3.86, location=pos_beam, rotation=(math.radians(75), 0, 0))
    light_beam = bpy.context.object
    light_beam.name = "Projection_Beam"
    light_beam.active_material = volume_mat

# -------------------------------------------------------------
# LIGHTING & CAMERA CONFIGURATION
# -------------------------------------------------------------

def setup_lights():
    """Positions ceiling spotlight units and internal caustics generator lights."""

    # Light 1: Main intense golden spotlight directed down on pedestal
    spot1_data = bpy.data.lights.new(name="Spot_Pedestal", type='SPOT')
    spot1_data.energy = 550.0
    spot1_data.color = (1.0, 0.93, 0.84)
    spot1_data.spot_size = math.radians(24)
    spot1_data.spot_blend = 0.35
    spot1_obj = bpy.data.objects.new("Spot_Pedestal_Obj", spot1_data)
    bpy.context.collection.objects.link(spot1_obj)
    spot1_obj.location = (0.5, -0.6, 3.4)

    track1 = spot1_obj.constraints.new(type="TRACK_TO")
    track_target1 = bpy.data.objects.new("Target_Light_Pedestal", None)
    bpy.context.collection.objects.link(track_target1)
    track_target1.location = (0.0, 0.0, 1.15)
    track1.target = track_target1
    track1.track_axis = 'TRACK_NEGATIVE_Z'
    track1.up_axis = 'UP_Y'

    # Light 2: Small cooler backlight targeting the placard and pedestal face
    spot2_data = bpy.data.lights.new(name="Spot_Placard", type='SPOT')
    spot2_data.energy = 160.0
    spot2_data.color = (0.9, 0.94, 1.0)
    spot2_data.spot_size = math.radians(16)
    spot2_data.spot_blend = 0.2
    spot2_obj = bpy.data.objects.new("Spot_Placard_Obj", spot2_data)
    bpy.context.collection.objects.link(spot2_obj)
    spot2_obj.location = (0.0, -0.9, 2.45)

    track2 = spot2_obj.constraints.new(type="TRACK_TO")
    track_target2 = bpy.data.objects.new("Target_Light_Placard", None)
    bpy.context.collection.objects.link(track_target2)
    track_target2.location = (0.0, -0.34, 1.01)
    track2.target = track_target2
    track2.track_axis = 'TRACK_NEGATIVE_Z'
    track2.up_axis = 'UP_Y'

    # Light 3: Super bright point light situated behind/inside crystal core to project genuine physical caustics
    caustics_light_data = bpy.data.lights.new(name="Crystal_Caustics", type='POINT')
    caustics_light_data.energy = 22.0
    caustics_light_data.color = (0.0, 0.88, 1.0) # Highly saturated anomaly cyan
    caustics_light_data.shadow_soft_size = 0.005 # Sharp caustic shadows through glass
    caustics_obj = bpy.data.objects.new("Crystal_Caustics_Obj", caustics_light_data)
    bpy.context.collection.objects.link(caustics_obj)
    caustics_obj.location = (0.0, -0.06, 1.13)

def setup_camera():
    """Sets up camera with Depth of Field focusing on the Reality Reprojection device."""
    cam_data = bpy.data.cameras.new("Contestant_Camera")
    cam_data.lens = 38.0
    cam_data.clip_start = 0.1
    cam_data.clip_end = 100.0

    # Focus tracking setup
    cam_data.use_dof = True
    focus_target = bpy.data.objects.get("Faceted_Core")
    if focus_target:
        cam_data.dof.focus_object = focus_target
    cam_data.dof.aperture_fstop = 2.4 # Elegant blur for background pillars and projection edge

    cam_obj = bpy.data.objects.new("Camera", cam_data)
    bpy.context.collection.objects.link(cam_obj)
    bpy.context.scene.camera = cam_obj

    cam_obj.location = (1.52, -2.62, 1.58)

    # Constraint to frame the device and back wall projection sequentially
    track = cam_obj.constraints.new(type="TRACK_TO")
    cam_target = bpy.data.objects.new("Camera_Target", None)
    bpy.context.collection.objects.link(cam_target)
    cam_target.location = (0.0, 0.44, 1.34)
    track.target = cam_target
    track.track_axis = 'TRACK_NEGATIVE_Z'
    track.up_axis = 'UP_Y'

# -------------------------------------------------------------
# ENGINE AND POST-PROCESSING RENDER CONFIGURATION
# -------------------------------------------------------------

def configure_render_engine():
    """Sets standard high-fidelity Cycles parameters."""
    scene = bpy.context.scene
    scene.render.engine = 'CYCLES'

    # Optimize viewport settings
    scene.cycles.preview_samples = 32

    # Final render setup overrides
    scene.cycles.samples = 64
    scene.cycles.use_denoising = True
    scene.cycles.denoise_ao_only = False

    # Allow caustics to properly escape refractive lenses
    scene.cycles.blur_glossy = 0.2

    # Render Output Dimensions
    scene.render.resolution_x = 1536
    scene.render.resolution_y = 1536
    scene.render.resolution_percentage = 100

def configure_compositor_bloom():
    """Implements subtle fog glow bloom around extreme hot highlights of the core."""
    scene = bpy.context.scene
    scene.use_nodes = True
    tree = scene.node_tree
    tree.nodes.clear()

    render_layers = tree.nodes.new(type='CompositorNodeRLayers')
    glare = tree.nodes.new(type='CompositorNodeGlare')
    glare.glare_type = 'FOG_GLOW'
    glare.quality = 'HIGH'
    glare.threshold = 0.7
    glare.size = 8

    composite = tree.nodes.new(type='CompositorNodeComposite')

    tree.links.new(render_layers.outputs['Image'], glare.inputs['Image'])
    tree.links.new(glare.outputs['Image'], composite.inputs['Image'])

# -------------------------------------------------------------
# EXECUTION
# -------------------------------------------------------------

def main():
    clean_scene()
    build_concrete_gallery()
    build_pedestal()
    build_gimbals_and_crystals()
    build_axial_lens_stack()
    build_anomaly_effects()
    build_museum_barriers()
    setup_lights()
    setup_camera()
    configure_render_engine()
    configure_compositor_bloom()

if __name__ == "__main__":
    main()
```