from pathlib import Path import random source=Path('/Users/simon/Documents/Codex/2026-09-04/use-x20/work/pelican_scene.py').read_text() exec(source[:source.rfind('bpy.ops.wm.save_as_mainfile')]) random.seed(14) coral=mat('Festival coral',(1,.19,.15)); blue=mat('Ocean turquoise',(.025,.55,.66),.15,.28); sand=mat('Peach sand',(.95,.71,.45)); purple=mat('Lavender',(.49,.25,.75)); lime=mat('Lime',(.48,.8,.16)); wood=mat('Palm trunks',(.40,.21,.095)); leaf=mat('Emerald palm leaves',(.035,.37,.19)); road=mat('Promenade warm pink',(.82,.44,.34)); sky=mat('Sky blue',(.29,.70,.82)); foam=mat('Seafoam',(.71,.95,.91)); gold=mat('Sunshine',(1,.64,.055)) palette=[coral,yellow,teal,purple,lime,orange] def box(name,loc,scale,material,bevel=.04): bpy.ops.mesh.primitive_cube_add(size=1,location=loc);o=bpy.context.object;o.name=name;o.scale=scale;bpy.ops.object.transform_apply(location=False,rotation=False,scale=True);smooth(o,material) if bevel: b=o.modifiers.new('Soft corners','BEVEL');b.width=bevel;b.segments=3;o.modifiers.new('Weighted normals','WEIGHTED_NORMAL') return o # Broad stripes of promenade, sand, and sea create a fully modeled coastal set. bpy.data.objects.get('Plane').data.materials.clear();bpy.data.objects.get('Plane').data.materials.append(road) box('Golden beach',(0,5,.005),(200,5,.1),sand) box('Turquoise sea',(0,60,.018),(200,106,.1),blue) box('Promenade curb',(0,2.4,.055),(50,.18,.15),white) for x in range(-14,15):box('Promenade paving joint',(x*.7,-.4,.004),(.012,5.3,.007),sand,0) for i in range(23): x=random.uniform(-15,15);y=random.uniform(7,20) path('Sparkling sea ripple',[(x-.5,y,.075),(x,y-.05,.075),(x+.5,y,.075)],.016,foam) # Colorful boardwalk huts. for x,col in [(-4.4,coral),(-2.75,yellow),(3.9,purple)]: y=4.5 box('Beach hut walls',(x,y,.73),(1.3,1.15,1.45),col) for offset in [-.5,-.3,-.1,.1,.3,.5]:box('White hut stripes',(x+offset,y-.581,.74),(.075,.02,1.36),white,.005) box('Hut door',(x,y-.61,.61),(.44,.08,1.14),teal) ell('Door knob',(x+.14,y-.67,.65),(.035,.022,.035),gold) mesh('Gabled hut roof',[(x-.8,y-.7,1.42),(x+.8,y-.7,1.42),(x,y-.7,2.06),(x-.8,y+.7,1.42),(x+.8,y+.7,1.42),(x,y+.7,2.06)],[(0,1,2),(3,5,4),(0,2,5,3),(2,1,4,5)],white,.035) # Sweeping palms on the edges. for x,y,h in [(-5.3,3.8,4.8),(4.5,3.8,5.0)]: top=Vector((x-.35,y,h)) path('Curved palm trunk',[(x,y,0),(x+.15,y,h*.4),tuple(top)],.13,wood) for j in range(8): a=j*math.tau/8 direction=Vector((math.cos(a),math.sin(a),0)); side=Vector((-math.sin(a),math.cos(a),0)) mid=top+direction*.8+Vector((0,0,.23)); tip=top+direction*1.65+Vector((0,0,-.5)) mesh('Sculpted palm frond',[tuple(top),tuple(mid+side*.24),tuple(tip),tuple(mid-side*.24),tuple(mid+Vector((0,0,.12)))],[(0,1,4),(1,2,4),(2,3,4),(3,0,4)],leaf,.035) # Festive overhead bunting, positioned above the rider. coords=[(-6,1.4,6.2),(-3,1.4,5.75),(0,1.4,5.6),(3,1.4,5.75),(6,1.4,6.2)] path('Festival bunting string',coords,.018,dark) for i in range(23): x=-5.75+i*.5;z=5.6+.6*(x/6)**2 mesh('Multicolored pennant',[(x-.2,1.4,z),(x+.2,1.4,z),(x,1.4,z-.40)],[(0,1,2)],palette[i%6],.008) # Balloons tethered to the saddle trail behind the pelican. for i,(x,y,z) in enumerate([(-2.25,.5,4.2),(-2.95,.6,4.8),(-3.35,.4,3.9)]): ell('Party balloon',(x,y,z),(.32,.28,.43),palette[i]) ell('Balloon knot',(x,y,z-.43),(.055,.04,.065),palette[i]) path('Balloon ribbon',[(-.9,.12,2.55),(x+.4,y,3.2),(x,y,z-.44)],.012,white) # A straw boater hat with a vivid ribbon, tilted on the crown. ell('Boater hat brim',(.23,0,4.89),(.56,.43,.075),yellow) rod('Boater crown',(.23,0,4.91),(.23,0,5.12),.29,yellow) rod('Coral hat band',(.23,0,4.93),(.23,0,5.00),.297,coral) # Pinwheel fitted to the front fork. rod('Pinwheel mast',(1.16,.16,2.12),(1.75,.16,3.24),.021,yellow) for i in range(4): a=i*math.pi/2; center=Vector((1.75,-.02,3.24)) p1=center+Vector((math.cos(a)*.38,0,math.sin(a)*.38));p2=center+Vector((math.cos(a+.9)*.30,-.035,math.sin(a+.9)*.30)) mesh('Pinwheel blade',[tuple(center),tuple(p1),tuple(p2)],[(0,1,2)],palette[i],.015) ell('Pinwheel center',(1.75,-.055,3.24),(.065,.04,.065),gold) # Airborne confetti stays outside the face and torso silhouette. for i in range(65): x=random.uniform(-4.6,4.6);z=random.uniform(.5,5.45) if -1.91.3:continue y=random.uniform(-1,1.0) o=box('Floating confetti',(x,y,z),(.09,.018,.045),random.choice(palette),.008) o.rotation_euler=(random.random()*3,random.random()*3,random.random()*3) for i in range(34): x=random.uniform(-5,5);y=random.uniform(-2,2) o=box('Confetti on promenade',(x,y,.02),(.07,.13,.016),random.choice(palette),.008);o.rotation_euler[2]=random.random()*6 # Curled streamers flank the rider. for x,z,col in [(-3.9,2.5,purple),(3.05,4.2,coral),(3.3,1.7,yellow)]: path('Curly festival streamer',[(x+.14*math.sin(i*.6),-.35+.10*math.cos(i*.6),z-i*.04) for i in range(25)],.022,col) # Beach umbrellas and a few distant seabirds. for x,y in [(1.4,6.2),(-6.3,6.1)]: rod('Parasol pole',(x,y,0),(x,y,1.8),.026,white) for j in range(10): a=j*math.tau/10;b=(j+1)*math.tau/10 mesh('Striped parasol panel',[(x,y,1.95),(x+.8*math.cos(a),y+.8*math.sin(a),1.58),(x+.8*math.cos(b),y+.8*math.sin(b),1.58)],[(0,1,2)],coral if j%2 else white,.025) for x,y,z in [(-2,10,2.4),(.1,12,3.0),(3,13,2.7)]: path('Distant gull',[(x-.35,y,z),(x-.16,y,z+.12),(x,y,z),(x+.16,y,z+.12),(x+.35,y,z)],.023,white) cam.location=(6,-16,8);cam.rotation_euler=(Vector((0,1,2.65))-cam.location).to_track_quat('-Z','Y').to_euler();cam.data.ortho_scale=10.7 s.render.resolution_x=1800;s.render.resolution_y=1400;s.cycles.samples=64 s.world.node_tree.nodes['Background'].inputs[0].default_value=(.40,.70,.85,1) s.view_settings.look='AgX - Medium High Contrast' s.render.filepath=OUT+'/pelican-bicycle-festival.png' bpy.ops.wm.save_as_mainfile(filepath=OUT+'/pelican-bicycle-festival.blend') bpy.ops.render.render(write_still=True)