from pathlib import Path exec(Path('/Users/simon/Documents/Codex/2026-09-04/use-x20/work/pelican_flair.py').read_text().split("bpy.ops.wm.save_as_mainfile(filepath=OUT+'/pelican-bicycle-festival.blend')")[0]) # Rebuild the set around the character, keeping only the strongest festival elements. remove=['Golden beach','Turquoise sea','Sparkling sea ripple','Distant gull','Pinwheel','Floating confetti','Confetti on promenade','Curly festival streamer','Festival bunting','Multicolored pennant','Curved palm trunk','Sculpted palm frond','Beach hut','White hut','Hut door','Door knob','Gabled hut','Parasol','Striped parasol','Promenade paving joint','Promenade curb','Long upper bill','Pelican hanging throat pouch','Bill smile seam','Swept crown feather'] for o in list(bpy.data.objects): if any(o.name.startswith(n) for n in remove):bpy.data.objects.remove(o,do_unlink=True) cam.location=(5.6,-21,6.3);target=Vector((0,0.6,2.7));cam.rotation_euler=(target-cam.location).to_track_quat('-Z','Y').to_euler();cam.data.ortho_scale=9.4 # Refine the silhouette: sculpt the pouch as a continuous rounded surface. verts=[];faces=[];nr=28;ns=40 for i in range(nr+1): t=i/nr;x=.55+1.45*t width=.235*(1-t)**.65+.008 depth=.40*math.sin(math.pi*t)**.75+.015 for j in range(ns): a=math.tau*j/ns;verts.append((x,width*math.cos(a),4.32-.055*t-depth*(math.sin(a)+1)/2)) for i in range(nr): for j in range(ns):a=i*ns+j;b=i*ns+(j+1)%ns;faces.append((a,b,b+ns,a+ns)) mesh('Sculpted soft pelican pouch',verts,faces,pouch,0) verts=[];faces=[] for i in range(31): t=i/30 for j in range(24): a=j*math.tau/24;verts.append((.55+1.45*t,(.235*(1-t)**.7+.003)*math.cos(a),4.345-.06*t+.05*(1-t)*math.sin(a))) for i in range(30): for j in range(24):a=i*24+j;b=i*24+(j+1)%24;faces.append((a,b,b+24,a+24)) mesh('Elegant tapered upper bill',verts,faces,orange,0) path('Fine beak seam',[(.59,-.236,4.32),(1.1,-.19,4.30),(1.64,-.105,4.28),(1.98,0,4.285)],.009,wood) for yy in [-1,1]: ell('Small bill nostril',(.78,yy*.195,4.347),(.027,.008,.011),wood) path('Expressive brow',[(.31,yy*.31,4.72),(.44,yy*.34,4.76),(.55,yy*.30,4.72)],.023,white) ell('Wingtip holding handlebar',(.84,yy*.49,2.73),(.15,.12,.13),white) for o in bpy.data.objects: if o.name.startswith('Webbed pedal foot'): mod=o.modifiers.new('Webbed foot thickness','SOLIDIFY');mod.thickness=.045 for i in range(7): o=ell('Delicate breast plumage',(-.02-i*.055,-.37,3.05-i*.075),(.085,.055,.15),white);o.rotation_euler[1]=-.35 # Boardwalk wood texture and fine individual plank seams. bpy.data.objects.remove(bpy.data.objects.get('Plane'),do_unlink=True) planks=mat('Sunlit peach timber',(.68,.37,.23),0,.7) p=planks.node_tree.nodes.get('Principled BSDF');n=planks.node_tree.nodes.new('ShaderNodeTexNoise');n.inputs['Scale'].default_value=7;n.inputs['Detail'].default_value=3 tex=planks.node_tree.nodes.new('ShaderNodeTexCoord');mapping=planks.node_tree.nodes.new('ShaderNodeVectorMath');mapping.operation='MULTIPLY';mapping.inputs[1].default_value=(1,35,4);planks.node_tree.links.new(tex.outputs['Generated'],mapping.inputs[0]);planks.node_tree.links.new(mapping.outputs[0],n.inputs['Vector']) ramp=planks.node_tree.nodes.new('ShaderNodeValToRGB');ramp.color_ramp.elements[0].color=(.38,.17,.085,1);ramp.color_ramp.elements[1].color=(.78,.49,.28,1);planks.node_tree.links.new(n.outputs['Fac'],ramp.inputs[0]);planks.node_tree.links.new(ramp.outputs[0],p.inputs['Base Color']) for i in range(60): y=-12+i*.26;box('Individual boardwalk plank',(0,y,-.045),(32,.25,.08),planks,.01) box('Beach sand',(0,7,-.04),(120,9,.08),sand,.0) box('Ocean surface',(0,55,-.018),(180,90,.02),blue,0) # Low, clean horizon with a peach-to-blue luminous sky backdrop. forward=Vector((-cam.location.x,-cam.location.y,0)).normalized();right=Vector((forward.y,-forward.x,0));center=forward*20 sky_mat=bpy.data.materials.new('Sunset sky gradient');sky_mat.use_nodes=True;nodes=sky_mat.node_tree.nodes;nodes.clear();out=nodes.new('ShaderNodeOutputMaterial');em=nodes.new('ShaderNodeEmission');coord=nodes.new('ShaderNodeTexCoord');sep=nodes.new('ShaderNodeSeparateXYZ');r=nodes.new('ShaderNodeValToRGB');r.color_ramp.elements.remove(r.color_ramp.elements[1]);r.color_ramp.elements[0].position=0;r.color_ramp.elements[0].color=(1,.52,.28,1) for pos,color in [(.15,(1,.71,.50,1)),(.42,(.43,.72,.80,1)),(1,(.12,.42,.64,1))]:r.color_ramp.elements.new(pos).color=color sky_mat.node_tree.links.new(coord.outputs['Generated'],sep.inputs[0]);sky_mat.node_tree.links.new(sep.outputs['Z'],r.inputs[0]);sky_mat.node_tree.links.new(r.outputs[0],em.inputs[0]);sky_mat.node_tree.links.new(em.outputs[0],out.inputs[0]);em.inputs[1].default_value=.8 mesh('Horizon sky',[tuple(center-right*80),tuple(center+right*80),tuple(center+right*80+Vector((0,0,16))),tuple(center-right*80+Vector((0,0,16)))],[(0,1,2,3)],sky_mat,0) sunmat=mat('Glowing apricot sun',(1,.63,.20));sp=sunmat.node_tree.nodes.get('Principled BSDF');sp.inputs['Emission Color'].default_value=(1,.44,.12,1);sp.inputs['Emission Strength'].default_value=1.5 ell('Low golden sun',tuple(center-forward*.15+right*2.65+Vector((0,0,2.2))),(.76,.76,.76),sunmat) # Organic rolling foam lines on the water and on the beach. for i in range(8): y=11.7+i*.8 path('Rolling wave crest',[(x,y+.12*math.sin(x*1.7+i),.03+.03*math.sin(x*.8+i)**2) for x in [k*.2 for k in range(-75,76)]],.028 if i<3 else .013,foam) for i in range(3): y=11.5+i*.18 path('Lapping shore foam',[(x,y+.18*math.sin(x*.9),.021) for x in [k*.22 for k in range(-65,66)]],.018,white) # Layered clouds and a tiny sailboat give the distance scale. cloudmat=mat('Luminous peach clouds',(.98,.82,.66));cp=cloudmat.node_tree.nodes.get('Principled BSDF');cp.inputs['Emission Color'].default_value=(1,.79,.62,1);cp.inputs['Emission Strength'].default_value=.45 for x,y,z in [(-4,18,2.7),(-1.5,18,3.4),(4.9,18,2.6)]: for j in range(5):ell('Soft sunset cloud',(x+j*.28,y,z+.12*math.sin(j)),(.39,.15,.14+.08*math.sin(j)),cloudmat) boatpos=(-2.1,13.5,.09) ell('Distant sailboat hull',boatpos,(.44,.12,.09),white);rod('Sailboat mast',(-2.1,13.5,.1),(-2.1,13.5,1.03),.012,wood) mesh('Little coral sail',[(-2.09,13.5,.97),(-2.09,13.5,.23),(-1.63,13.5,.23)],[(0,1,2)],coral,.01) mesh('Little cream sail',[(-2.14,13.5,.87),(-2.14,13.5,.23),(-2.50,13.5,.23)],[(0,1,2)],white,.01) for o in bpy.data.objects: if o.name.startswith(('Distant sailboat','Sailboat mast','Little coral sail','Little cream sail')):o.location.x+=2.7 # Boutique beach huts, pushed into the midground. for x,y,col in [(-3.7,5.2,coral),(-5.1,5.5,teal)]: box('Painted beach cabin',(x,y,.66),(1.13,1.1,1.32),col) for dx in [-.48,-.32,-.16,0,.16,.32,.48]:box('Cabin wood batten',(x+dx,y-.558,.7),(.023,.025,1.2),white,.005) box('Cabin door',(x+.17,y-.59,.55),(.4,.05,1.05),white) box('Door inset',(x+.17,y-.624,.62),(.29,.025,.72),col) mesh('Cabin roof',[(x-.7,y-.66,1.32),(x+.7,y-.66,1.32),(x,y-.66,1.91),(x-.7,y+.66,1.32),(x+.7,y+.66,1.32),(x,y+.66,1.91)],[(0,2,5,3),(2,1,4,5),(0,1,2)],dark,.035) box('Cabin step',(x,y-.75,.07),(1.13,.38,.14),white) # Delicate palm leaves, each composed of a stem and tapered leaflets. for x,y,h in [(-4.6,3.7,4.5),(4.5,5,4.9)]: top=Vector((x-.3,y,h));path('Leaning palm',[(x,y,0),(x+.08,y,h*.45),tuple(top)],.10,wood) for j in range(8): a=j*math.tau/8;d=Vector((math.cos(a),math.sin(a),0));side=Vector((-math.sin(a),math.cos(a),0)) def palmpt(t):return top+d*1.6*t+Vector((0,0,.45*math.sin(math.pi*t)-.48*t)) path('Frond rib',[tuple(palmpt(k/10)) for k in range(11)],.013,leaf) for k in range(1,10): t=k/10;v=palmpt(t);w=.26*math.sin(math.pi*t)**.6 for sign in [-1,1]:mesh('Palm leaflet',[tuple(v-d*.07),tuple(v+side*w*sign-d*.13+Vector((0,0,-.08))),tuple(v+d*.12)],[(0,1,2)],leaf,.007) # Fine woven basket mounted ahead of the handlebars, full of daisies. wicker=mat('Honey wicker',(.55,.29,.105),0,.6) cx,cy,cz=1.64,.13,2.43 for k in range(10): z=cz-.32+k*.055;rx=.28+k*.008;ry=.23+k*.006 path('Woven basket horizontal',[(cx+rx*math.cos(j*math.tau/40),cy+ry*math.sin(j*math.tau/40),z) for j in range(41)],.018,wicker) for j in range(24): a=j*math.tau/24;rod('Woven basket upright',(cx+.28*math.cos(a),cy+.23*math.sin(a),cz-.33),(cx+.36*math.cos(a),cy+.29*math.sin(a),cz+.19),.013,wicker) for i in range(7): fx=cx+random.uniform(-.25,.25);fy=cy+random.uniform(-.2,.2);fz=cz+random.uniform(.35,.65) rod('Flower stalk',(cx,cy,cz-.05),(fx,fy,fz),.012,leaf) ell('Daisy center',(fx,fy-.025,fz),(.06,.032,.06),gold) for j in range(8): a=j*math.tau/8;o=ell('Daisy petal',(fx+.10*math.cos(a),fy,fz+.10*math.sin(a)),(.075,.025,.035),white if i%2 else coral);o.rotation_euler[1]=-a # Brass headlamp and red rear reflector. ell('Brass bicycle headlamp',(1.37,-.12,2.15),(.14,.13,.13),gold);ell('Headlamp glass',(1.47,-.16,2.15),(.08,.10,.10),white) ell('Rear ruby reflector',(-1.86,-.05,1.91),(.07,.08,.1),coral) # One clean string of flags provides a frame without covering the character. path('High festival string',[(-5,2,6.15),(-2.5,2,5.65),(0,2,5.58),(2.5,2,5.78),(5,2,6.2)],.012,wood) for i in range(20): x=-4.75+i*.5;z=5.58+.62*(x/5)**2 mesh('Fabric festival flag',[(x-.17,2,z),(x+.17,2,z),(x+.05,1.95,z-.31)],[(0,1,2)],palette[i%6],.008) # Restrained confetti and seashell details at the edges. for i in range(30): x=random.uniform(-4,4);y=random.uniform(-2.5,2.3) o=box('Celebration confetti',(x,y,.012),(.055,.10,.012),random.choice(palette),.005);o.rotation_euler[2]=random.random()*6 for x,y in [(3,3.5),(2.7,4),(-2.5,3.7)]: for i in range(6): a=i*.23;o=ell('Scalloped seashell',(x+.06*math.cos(a),y+.06*math.sin(a),.035),(.12,.035,.025),white);o.rotation_euler[2]=a # Golden-hour lighting adds form and coherent long shadows. for o in bpy.data.objects: if o.type=='LIGHT':bpy.data.objects.remove(o,do_unlink=True) area('Warm setting sun',(-5,-3,8),850,4);bpy.context.object.data.color=(1,.77,.53) area('Cool sky fill',(4,-5,7),450,5);bpy.context.object.data.color=(.65,.84,1) area('Golden rim',(-2,6,6),1000,3);bpy.context.object.data.color=(1,.59,.29) s.world.node_tree.nodes['Background'].inputs[0].default_value=(.39,.60,.74,1);s.world.node_tree.nodes['Background'].inputs[1].default_value=.24 s.render.resolution_x=2000;s.render.resolution_y=1600;s.cycles.samples=96 s.render.filepath=OUT+'/pelican-coastal-parade.png';s.render.film_transparent=False bpy.ops.wm.save_as_mainfile(filepath=OUT+'/pelican-coastal-parade.blend');bpy.ops.render.render(write_still=True)