```python
import bpy, math, random
from mathutils import Vector
from math import sin, cos, pi

random.seed(23)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

# Materials
def mat(name, color, rough=.5, metallic=0):
    m=bpy.data.materials.new(name); m.diffuse_color=(*color,1)
    m.use_nodes=True
    p=m.node_tree.nodes.get('Principled BSDF')
    p.inputs['Base Color'].default_value=(*color,1)
    p.inputs['Roughness'].default_value=rough
    p.inputs['Metallic'].default_value=metallic
    return m

def furmat(name,col):
    m=mat(name,col,.78)
    n=m.node_tree.nodes; l=m.node_tree.links; p=n.get('Principled BSDF')
    p.inputs['Subsurface Weight'].default_value=.045
    p.inputs['Sheen Weight'].default_value=.23
    noise=n.new('ShaderNodeTexNoise'); noise.inputs['Scale'].default_value=115
    noise.inputs['Detail'].default_value=2.5
    bump=n.new('ShaderNodeBump'); bump.inputs['Strength'].default_value=.18
    bump.inputs['Distance'].default_value=.026
    l.new(noise.outputs['Fac'],bump.inputs['Height']); l.new(bump.outputs['Normal'],p.inputs['Normal'])
    return m

tan=furmat('Fox red • soft guard coat',(.61,.235,.062))
lighttan=furmat('Golden fur tips',(.77,.345,.105))
darktan=furmat('Warm ear edges',(.46,.145,.039))
cream=furmat('Ivory white coat',(.94,.89,.76))
white=furmat('Sunlit white fur',(.99,.96,.87))
pink=mat('Warm ear velvet',(.64,.245,.22),.83)
nosemat=mat('Wet charcoal nose',(.018,.012,.015),.25)
mouthmat=mat('Inside open mouth',(.075,.013,.025),.65)
lipmat=mat('Dark lip',(.16,.052,.038),.63)
tonguemat=mat('Coral pink tongue',(.94,.23,.34),.39)
tooth=mat('Little ivory teeth',(1,.94,.78),.3)
eyewhite=mat('Eye whites',(.99,.975,.9),.19)
iris=mat('Amber brown iris',(.20,.070,.019),.23)
pupil=mat('Deep pupils',(.005,.009,.012),.12)
padmat=mat('Paw beans',(.29,.13,.105),.73)
sand=mat('Fine warm beach sand',(.72,.53,.30),.87)
n=sand.node_tree.nodes; l=sand.node_tree.links
noise=n.new('ShaderNodeTexNoise'); noise.inputs['Scale'].default_value=145; noise.inputs['Detail'].default_value=2
b=n.new('ShaderNodeBump'); b.inputs['Strength'].default_value=.24; b.inputs['Distance'].default_value=.045
l.new(noise.outputs['Fac'],b.inputs['Height']); l.new(b.outputs['Normal'],n.get('Principled BSDF').inputs['Normal'])
sanddark=mat('Sand inside footprints',(.43,.29,.145),1)
sandlight=mat('Sun-catching sand grains',(.89,.69,.39),.85)

def mesh(name,verts,faces,material):
    me=bpy.data.meshes.new(name); me.from_pydata(verts,[],faces); me.update()
    ob=bpy.data.objects.new(name,me); bpy.context.collection.objects.link(ob)
    if material: me.materials.append(material)
    for p in me.polygons: p.use_smooth=True
    return ob

def uv(name,loc,scale,material,seg=40,rings=24):
    bpy.ops.mesh.primitive_uv_sphere_add(segments=seg,ring_count=rings,location=loc)
    ob=bpy.context.object; ob.name=name; ob.scale=scale
    if material: ob.data.materials.append(material)
    for p in ob.data.polygons:p.use_smooth=True
    return ob

def ell_between(name,a,b,r1,r2,material):
    a=Vector(a); b=Vector(b)
    ob=uv(name,(a+b)/2,(r1,r2,(b-a).length/2+r1*.43),material)
    ob.rotation_mode='QUATERNION'; ob.rotation_quaternion=Vector((0,0,1)).rotation_difference(b-a)
    return ob

def tube(name,pts,r,material):
    cu=bpy.data.curves.new(name,'CURVE'); cu.dimensions='3D'; cu.resolution_u=16
    cu.bevel_depth=r; cu.bevel_resolution=3
    sp=cu.splines.new('BEZIER'); sp.bezier_points.add(len(pts)-1)
    for bp,co in zip(sp.bezier_points,pts):
        bp.co=co; bp.handle_left_type='AUTO'; bp.handle_right_type='AUTO'
    ob=bpy.data.objects.new(name,cu); bpy.context.collection.objects.link(ob); cu.materials.append(material)
    bpy.context.view_layer.objects.active=ob; ob.select_set(True)
    bpy.ops.object.convert(target='MESH'); ob.select_set(False)
    return ob

def unite(obs,name,voxel=.052):
    bpy.ops.object.select_all(action='DESELECT')
    for ob in obs:ob.select_set(True)
    bpy.context.view_layer.objects.active=obs[0]
    bpy.ops.object.transform_apply(location=False,rotation=False,scale=True)
    bpy.ops.object.join()
    ob=bpy.context.object; ob.name=name
    re=ob.modifiers.new('Seamless organic anatomy','REMESH'); re.mode='VOXEL'; re.voxel_size=voxel
    bpy.ops.object.modifier_apply(modifier=re.name)
    sm=ob.modifiers.new('Soft tissue smoothing','SMOOTH'); sm.factor=.72; sm.iterations=5
    bpy.ops.object.modifier_apply(modifier=sm.name)
    su=ob.modifiers.new('Silky silhouette','SUBSURF'); su.levels=1
    bpy.ops.object.modifier_apply(modifier=su.name)
    for p in ob.data.polygons:p.use_smooth=True
    ob.select_set(False)
    return ob

# One continuous, arched, long-bodied corgi sculpture.
parts=[
uv('Long low barrel',(-.66,0,2.89),(1.49,.64,.64),tan),
uv('Big round corgi rump',(-1.63,.025,2.74),(.77,.72,.72),tan),
uv('Arched shoulder',(.34,0,3.02),(.86,.62,.68),tan),
uv('Rising neck',(.78,0,3.29),(.59,.53,.65),tan),
]
for side in [-1,1]:
    y=side*.51
    parts.append(uv('Round muscular haunch',(-1.64,y,2.61),(.51,.37,.52),tan))
    parts.append(ell_between('Short trailing hind thigh',(-1.69,y,2.55),(-2.05,y*1.12,2.23),.265,.24,tan))
    parts.append(ell_between('Little hind hock',(-2.02,y*1.12,2.24),(-2.37,y*1.18,2.13),.175,.18,tan))
    a=(.55,y,3.04); elbow=(.95,y*1.14,2.77+(side+1)*.08)
    parts.append(ell_between('Short forward upper arm',a,elbow,.255,.235,tan))
unite(parts,'Corgi | continuous red saddle and rounded anatomy')

# White fluffy bib, underbelly, and exceptionally short reaching legs.
uv('White belly peeking under saddle',(-.34,-.01,2.52),(1.04,.53,.28),cream)
uv('Great white chest ruff',(.66,-.01,2.98),(.53,.585,.68),cream)
for side in [-1,1]:
    y=side*.57
    elbow=(.98,y,2.79+(side+1)*.075)
    wrist=(1.48,y*1.1,2.91+(side+1)*.075)
    paw=(1.72,y*1.11,2.96+(side+1)*.075)
    fore=ell_between('White reaching foreleg',elbow,wrist,.19,.185,cream)
    foot=uv('Soft mitten front paw',paw,(.34,.245,.20),white)
    for j in [-1,0,1]:
        uv('Individual front toe',(paw[0]+.21,paw[1]+j*.115,paw[2]-.032),(.135,.083,.128),white,24,16)
        uv('Tiny front claw',(paw[0]+.31,paw[1]+j*.115,paw[2]-.045),(.049,.029,.035),tooth,16,10)
    heel=(-2.35,side*.61,2.13)
    end=(-2.68,side*.64,2.19)
    ell_between('White hind sock',heel,end,.17,.175,cream)
    uv('Trailing hind paw',end,(.265,.23,.17),white)
    uv('Visible rear paw cushion',(-2.70,side*.64,2.047),(.13,.13,.025),padmat,24,12)
    for j in [-1,0,1]:
        uv('Hind toes',(-2.85,side*.64+j*.11,2.20),(.10,.082,.125),white,24,16)
        uv('Small rear toe bean',(-2.84,side*.64+j*.10,2.082),(.049,.041,.019),padmat,16,10)
uv('Pembroke bobtail',(-2.23,.16,2.94),(.28,.255,.27),tan)
uv('Cream tip of bobtail',(-2.39,.17,3.0),(.16,.18,.17),cream)

# Head coordinate system: muzzle turns slightly toward the viewer.
F=Vector((.86,-.51,0)); S=Vector((.51,.86,0)); U=Vector((0,0,1))
H=Vector((1.12,-.015,3.56))
def hp(f,s,u):return H+F*f+S*s+U*u
def huv(name,f,s,u,scale,material):
    ob=uv(name,hp(f,s,u),scale,material)
    ob.rotation_euler[2]=math.atan2(F.y,F.x)
    return ob

huv('Broad fox-like corgi skull',0,0,0,(.65,.59,.65),tan)
huv('Near cheek fluff',.21,-.43,-.15,(.39,.27,.36),cream)
huv('Far cheek fluff',.21,.43,-.15,(.39,.27,.36),cream)
huv('Dark smiling open mouth',.72,0,-.285,(.60,.355,.245),mouthmat)
huv('White lower jaw',.69,0,-.454,(.46,.285,.115),cream)
huv('Left white muzzle cushion',.70,-.185,-.065,(.46,.245,.245),white)
huv('Right white muzzle cushion',.70,.185,-.065,(.46,.245,.245),white)

# A blaze hugs the curved forehead, widening into the muzzle.
verts=[]; faces=[]
for i in range(23):
    u=-.04+i*.029
    half=.115 + .06*math.exp(-((u-.01)/.18)**2)-.055*(u/.65)
    for j in range(9):
        s=(j/8*2-1)*half
        f=.65*math.sqrt(max(.001,1-(s/.59)**2-(u/.65)**2))+.008
        verts.append(hp(f,s,u))
for i in range(22):
    for j in range(8):
        k=i*9+j; faces.append((k,k+1,k+10,k+9))
blaze=mesh('Classic tapered white forehead blaze',verts,faces,white)
sol=blaze.modifiers.new('Fluffy blaze thickness','SOLIDIFY'); sol.thickness=.012

# Rounded triangular black nose, nostrils, and philtrum.
noseverts=[hp(1.12,-.25,.04),hp(1.12,.25,.04),hp(1.24,0,-.15),
           hp(1.02,-.22,.12),hp(1.02,.22,.12),hp(1.07,0,-.16)]
no=mesh('Soft triangular nose',noseverts,[(0,1,2),(3,5,4),(0,3,4,1),(1,4,5,2),(2,5,3,0)],nosemat)
be=no.modifiers.new('Rounded nose corners','BEVEL'); be.width=.09; be.segments=4
su=no.modifiers.new('Nose softness','SUBSURF'); su.levels=2
for s in [-.135,.135]:
    huv('Nostril',1.164,s,.005,(.027,.055,.030),pupil)
tube('Short nose groove',[hp(1.17,0,-.12),hp(1.13,0,-.2),hp(1.05,0,-.235)],.012,lipmat)

# Wide, comically intent eyes with real eyelids.
for side in [-1,1]:
    center=hp(.405,side*.432,.235)
    normal=(F*.77+S*(side*.60)+U*.21).normalized()
    uv('Bright worried eye',center,(.207,.207,.218),eyewhite)
    look=(normal+F*.17+U*.07).normalized()
    def eye_disc(name,dist,rad,dep,ma):
        ob=uv(name,center+look*dist,(rad,rad,dep),ma,40,24)
        ob.rotation_mode='QUATERNION'; ob.rotation_quaternion=Vector((0,0,1)).rotation_difference(look)
    eye_disc('Warm amber iris',.187,.126,.035,iris)
    eye_disc('Enlarged excited pupil',.217,.079,.016,pupil)
    uv('Eye sun sparkle',center+look*.237+S*(-.03)+U*.048,(.032,.025,.031),eyewhite,20,12)
    pts=[]
    for i in range(13):
        a=pi*.10+pi*.80*i/12
        pts.append(center+S*(cos(a)*.207)+U*(sin(a)*.215)+F*.033)
    tube('Soft raised upper eyelid',pts,.038,tan)
    tube('Flying expressive eyebrow',[hp(.26,side*.49,.49),hp(.37,side*.43,.52),hp(.47,side*.34,.47)],.051,lighttan)

# Thick, swept-back triangular upright ears.
def ear(side):
    vv=[]; ff=[]
    for i in range(17):
        t=i/16
        c=hp(-.13-.40*t,side*(.43+.30*t),.43+1.05*t)
        width=.31*(1-t)**.65*(.88+.42*sin(pi*t))
        thick=.115*(1-t)+.012
        if i==16: width=.007; thick=.006
        for j in range(16):
            a=j/16*2*pi
            vv.append(c+S*(cos(a)*width)+F*(sin(a)*thick))
    for i in range(16):
        for j in range(16):
            a=i*16+j; b=i*16+(j+1)%16
            ff.append((a,b,b+16,a+16))
    ff.extend([tuple(range(15,-1,-1)),tuple(256+j for j in range(16))])
    ob=mesh('Oversized swept triangular ear',vv,ff,tan)
    sub=ob.modifiers.new('Soft ear silhouette','SUBSURF'); sub.levels=2
    vv=[];ff=[]
    for i in range(15):
        t=.14+.77*i/14
        c=hp(-.13-.40*t,side*(.43+.30*t),.43+1.05*t)
        width=.31*(1-t)**.65*(.88+.42*sin(pi*t))*.71
        for j in range(9):
            q=j/8*2-1
            vv.append(c+S*(q*width)+F*(.115*(1-t)*math.sqrt(max(.1,1-(q*.72)**2))+.017))
    for i in range(14):
        for j in range(8):
            a=i*9+j;ff.append((a,a+1,a+10,a+9))
    mesh('Recessed rose velvet inner ear',vv,ff,pink)
ear(-1);ear(1)

# Teeth visible within the pant, not a closed smile.
def cone_between(name,a,b,r,material):
    a=Vector(a); b=Vector(b)
    bpy.ops.mesh.primitive_cone_add(vertices=20,radius1=r,radius2=.009,depth=(b-a).length,location=(a+b)/2)
    ob=bpy.context.object;ob.name=name
    ob.rotation_mode='QUATERNION';ob.rotation_quaternion=Vector((0,0,1)).rotation_difference(b-a)
    ob.data.materials.append(material)
    be=ob.modifiers.new('Blunt tooth tip','BEVEL');be.width=.015;be.segments=3
    for p in ob.data.polygons:p.use_smooth=True
for side in [-1,1]:
    cone_between('Little upper canine',hp(.78,side*.29,-.19),hp(.83,side*.29,-.365),.068,tooth)
    for f in [.40,.53]:
        cone_between('Small side tooth',hp(f,side*.295,-.19),hp(f+.03,side*.295,-.27),.037,tooth)

# Floppy tongue built as a curved, softly rounded ribbon.
vv=[];ff=[]
for i in range(20):
    t=i/19
    c=hp(.76+.62*t,-.07-.14*t,-.37-.34*sin(t*pi*.61))
    width=.148*(1-.18*t)
    if t>.87: width*=math.sqrt(max(.05,1-((t-.87)/.135)**2))
    for j in range(16):
        a=2*pi*j/16
        vv.append(c+S*(cos(a)*width)+U*(sin(a)*.041))
for i in range(19):
    for j in range(16):
        a=i*16+j;b=i*16+(j+1)%16;ff.append((a,b,b+16,a+16))
ff.extend([tuple(range(15,-1,-1)),tuple(19*16+j for j in range(16))])
mesh('Wind-flapped hanging pink tongue',vv,ff,tonguemat)
tube('Tongue center crease',[hp(.91,-.10,-.424),hp(1.12,-.15,-.54),hp(1.28,-.185,-.634)],.009,pink)

# Batched curved tapered locks give a soft silhouette in both native and GLB views.
fur_batches={}
def tuft(base,direction,length,width,material):
    key=material.name
    if key not in fur_batches:fur_batches[key]=[[],[],material]
    vs,fs,_=fur_batches[key]
    base=Vector(base); d=Vector(direction).normalized()
    axis=d.cross(Vector((0,0,1)))
    if axis.length<.01:axis=d.cross(Vector((0,1,0)))
    axis.normalize(); other=d.cross(axis).normalized()
    start=len(vs)
    for k,(t,r) in enumerate([(0,.62),(.23,1),(.57,.74),(.83,.34),(1,.015)]):
        c=base+d*(length*t)+Vector((-.05,0,.025))*(t*t)
        for j in range(7):
            a=2*pi*j/7
            vs.append(c+axis*(cos(a)*width*r)+other*(sin(a)*width*r*.64))
    for k in range(4):
        for j in range(7):
            a=start+k*7+j;b=start+k*7+(j+1)%7
            fs.append((a,b,b+7,a+7))
for i in range(490):
    x=random.uniform(-2.02,.38); a=random.uniform(0,2*pi)
    # long barrel with extra rump volume
    rr=math.sqrt(max(.12,1-((x+.69)/1.65)**2))
    y=.65*rr*cos(a); z=2.88+.655*rr*sin(a)
    if z<2.54:continue
    tuft((x,y,z),(-.64,cos(a)*.9,sin(a)*.7),random.uniform(.095,.21),random.uniform(.026,.054),random.choice([tan,tan,tan,lighttan]))
for i in range(210):
    a=random.uniform(0,2*pi); z=random.uniform(2.47,3.40)
    rr=math.sqrt(max(.1,1-((z-2.97)/.70)**2))
    x=.68+.49*rr*cos(a);y=.565*rr*sin(a)
    tuft((x,y,z),(-.23,sin(a)*.78,-.65),random.uniform(.14,.29),random.uniform(.038,.075),random.choice([cream,cream,white]))
for side in [-1,1]:
    for i in range(52):
        a=random.uniform(-.8,.8); t=random.random()
        p=hp(.13+random.uniform(-.15,.25),side*(.48+.025*cos(a)),-.06-.28*t)
        tuft(p,-F*.45+S*(side*.8)-U*.24,random.uniform(.12,.25),random.uniform(.025,.049),cream)
    for i in range(31):
        t=random.uniform(.1,.94)
        c=hp(-.13-.4*t,side*(.43+.3*t),.43+1.05*t)
        w=.31*(1-t)**.65*(.88+.42*sin(pi*t))
        edge=random.choice([-1,1])
        tuft(c+S*(w*edge),-F*.5+S*(edge*.28)+U*.35,random.uniform(.065,.13),.021,tan)
for i in range(48):
    a=random.uniform(0,2*pi)
    tuft((-2.36,.17+.15*cos(a),3+.15*sin(a)),(-1,.5*cos(a),.5*sin(a)),random.uniform(.08,.18),.034,cream)
for key,(vs,fs,ma) in fur_batches.items():mesh('Sculpted wind-lifted fur | '+key,vs,fs,ma)

# Whisker freckles and a few fine whiskers.
for side in [-1,1]:
    for k in range(3):
        huv('Muzzle freckle',.80+k*.074,side*(.36-k*.034),-.09-(k%2)*.049,(.017,.013,.017),lipmat)
    for k in range(2):
        tube('Fine pale whisker',[hp(.68,side*.36,-.12-k*.055),hp(.77,side*.57,-.1-k*.08),hp(.86,side*.72,-.07-k*.12)],.0045,cream)

# Six separately colored vinyl panels, rotated away from an axis-aligned globe.
red=mat('Ball • scarlet vinyl',(.94,.035,.047),.26)
yellow=mat('Ball • sunshine vinyl',(1,.68,.025),.28)
blue=mat('Ball • ocean blue vinyl',(.025,.36,.88),.25)
capmat=mat('Ball • white pole caps',(.99,.98,.89),.26)
seammat=mat('Ball seam piping',(.86,.85,.72),.4)
for m in [red,yellow,blue,capmat]:
    p=m.node_tree.nodes.get('Principled BSDF')
    p.inputs['Coat Weight'].default_value=.30
    p.inputs['Coat Roughness'].default_value=.23
    p.inputs['Subsurface Weight'].default_value=.028
ballC=Vector((3.18,.06,3.84)); radius=.88
from mathutils import Euler
rot=Euler((.40,-.55,.23)).to_matrix()
def ballpt(theta,phi,extra=0):
    r=radius+extra
    # Almost spherical vinyl: a gently flattened former contact patch.
    zz=cos(theta)
    return ballC+rot@Vector((r*sin(theta)*cos(phi)*(1+.018*sin(theta)**2),r*sin(theta)*sin(phi),r*zz*(.973+.027*abs(zz))))
for panel in range(6):
    vs=[];fs=[]
    for i in range(45):
        th=.115+(pi-.23)*i/44
        for j in range(17):
            ph=panel*pi/3+(pi/3)*j/16
            vs.append(ballpt(th,ph))
    for i in range(44):
        for j in range(16):
            a=i*17+j;fs.append((a,a+1,a+18,a+17))
    mesh('Inflatable panel %02d'%(panel+1),vs,fs,[red,yellow,blue,red,yellow,blue][panel])
    tube('Fine welded ball seam',[ballpt(.11+(pi-.22)*i/40,panel*pi/3,.002) for i in range(41)],.007,seammat)
for pole in [0,1]:
    vs=[];fs=[]
    for i in range(9):
        th=.001+.115*i/8
        if pole:th=pi-th
        for j in range(48):vs.append(ballpt(th,2*pi*j/48,.002))
    for i in range(8):
        for j in range(48):
            a=i*48+j;b=i*48+(j+1)%48;fs.append((a,b,b+48,a+48))
    mesh('White circular pole cap',vs,fs,capmat)
    tube('Pole cap welded ring',[ballpt(.116 if not pole else pi-.116,2*pi*j/48,.004) for j in range(49)],.008,seammat)
normal=(rot@Vector((0,0,1))).normalized()
val=uv('Small inflatable valve nub',ballC+normal*(radius*.994),( .067,.067,.028),capmat,32,16)
val.rotation_mode='QUATERNION';val.rotation_quaternion=Vector((0,0,1)).rotation_difference(normal)
val=uv('Valve plug',ballC+normal*(radius+ .025),(.031,.031,.015),seammat,24,12)
val.rotation_mode='QUATERNION';val.rotation_quaternion=Vector((0,0,1)).rotation_difference(normal)

# Minimal beach stage.
mesh('Warm sandy beach',[(-200,-200,-.035),(200,-200,-.035),(200,15,-.035),(-200,15,-.035)],[(0,1,2,3)],sand)
sea=mat('Turquoise sea',(.035,.46,.64),.31)
mesh('Quiet blue sea',[(-250,15,-.07),(250,15,-.07),(250,300,-.07),(-250,300,-.07)],[(0,1,2,3)],sea)
foam=mat('Distant sea foam',(.66,.87,.86),.6)
for y in [15.5,17,21,28,39]:
    pts=[(x,y+.13*sin(x*.63+y),-.045) for x in range(-55,56,2)]
    tube('Restrained distant wavelet',pts,.023 if y<22 else .018,foam)

# Prints: shallow dark impressions surrounded by softly displaced sand lips.
def printpad(loc,sx,sy,ang=0):
    ob=uv('Indented sandy paw pad',(loc[0],loc[1],.001),(sx,sy,.014),sanddark,24,12)
    ob.rotation_euler[2]=ang
    pts=[]
    for j in range(33):
        a=j*2*pi/32
        x=sx*1.06*cos(a);y=sy*1.06*sin(a)
        pts.append((loc[0]+x*cos(ang)-y*sin(ang),loc[1]+x*sin(ang)+y*cos(ang),.008))
    tube('Crumbled footprint lip',pts,.014,sand)
for k in range(5):
    x=-5.0+k*.54
    y=(-.34 if k%2==0 else .34)-.10
    printpad((x,y),.17,.135,-.08)
    for j in [-1,0,1]:
        printpad((x+.18,y+j*.115),.072,.055,-.1)
for y in [-.43,.37]:
    printpad((-2.93,y),.22,.17)
    for j in [-1,0,1]:printpad((-2.70,y+j*.14),.088,.061)

# Discrete sunlight-catching spray, concentrated into two toe-shaped takeoff bursts.
grain_vs=[];grain_fs=[];grain_mids=[]
def grain(p,r,mi):
    p=Vector(p); start=len(grain_vs)
    grain_vs.extend([p+Vector((r,0,0)),p+Vector((-r,0,0)),p+Vector((0,r,0)),p+Vector((0,-r,0)),p+Vector((0,0,r*1.25)),p+Vector((0,0,-r))])
    for face in [(0,2,4),(2,1,4),(1,3,4),(3,0,4),(2,0,5),(1,2,5),(3,1,5),(0,3,5)]:
        grain_fs.append(tuple(start+i for i in face));grain_mids.append(mi)
for side in [-1,1]:
    for i in range(265):
        t=random.random()
        toe=random.choice([-1,0,1])
        x=-2.91-1.05*t+random.gauss(0,.12)*t
        y=side*.37+toe*.11+(random.gauss(0,.25)+side*.23)*t
        z=.03+2.3*t-1.22*t*t+random.gauss(0,.14)*t
        grain((x,y,max(.025,z)),random.uniform(.009,.033)*(1-.30*t),random.randrange(3))
    for i in range(65):
        x=-2.9+random.uniform(-.7,.7);y=side*.4+random.uniform(-.4,.4)
        grain((x,y,random.uniform(.025,.14)),random.uniform(.012,.047),random.randrange(3))
ob=mesh('Hundreds of airborne sand grains',grain_vs,grain_fs,sand)
ob.data.materials.append(sandlight);ob.data.materials.append(sanddark)
for p,idx in zip(ob.data.polygons,grain_mids):p.material_index=idx

# A striped towel: modeled cloth with an unmistakably lifted, curling corner.
towelblue=mat('Towel turquoise cotton',(.025,.56,.62),.93)
towelwhite=mat('Towel ivory stripes',(.97,.91,.72),.95)
for ma in [towelblue,towelwhite]:
    p=ma.node_tree.nodes.get('Principled BSDF');p.inputs['Sheen Weight'].default_value=.3
def towelpt(u,v):
    x=-1.38+u*1.28;y=2.18+v*.68
    lift=.68*max(0,(u+.10)/1.10)**3*max(0,(v+.05)/1.05)**2
    z=.024+lift+.037*sin(8*u+4*v)*(.25+.75*abs(v))
    return Vector((x,y,z))
vs=[];fs=[];ids=[]
for i in range(51):
    for j in range(31):vs.append(towelpt(-1+2*i/50,-1+2*j/30))
for i in range(50):
    for j in range(30):
        a=i*31+j;fs.append((a,a+31,a+32,a+1));ids.append(1 if i%12<4 else 0)
ob=mesh('Gust lifts a striped beach towel',vs,fs,towelblue);ob.data.materials.append(towelwhite)
for p,idx in zip(ob.data.polygons,ids):p.material_index=idx
so=ob.modifiers.new('Real cloth thickness','SOLIDIFY');so.thickness=.016
for edge in [-1,1]:
    tube('Stitched towel hem',[towelpt(edge,-1+2*j/40)+Vector((0,0,.009)) for j in range(41)],.014,towelwhite)
    for j in range(22):
        v=-.97+j*1.94/21;p=towelpt(edge,v)
        tube('Loose towel fringe',[p,p+Vector((edge*.07,.01,.01)),p+Vector((edge*.14,.018,.015))],.009,towelwhite)

# Hollow plastic bucket lying on its side, with a swinging handle.
bucketmat=mat('Bucket tangerine plastic',(1,.27,.025),.31)
bucketinside=mat('Bucket inner warm plastic',(.8,.155,.015),.42)
handlema=mat('Bucket pale yellow handle',(1,.78,.18),.35)
origin=Vector((-3.65,1.38,.40)); axis=Vector((-.26,-.88,.33)).normalized()
q=Vector((0,0,1)).rotation_difference(axis)
def bp(x,y,z):return origin+q@Vector((x,y,z))
vs=[];fs=[]
# Open, tapered bucket wall with inner wall and a closed bottom.
profiles=[(.29,-.32),(.43,.33),(.39,.33),(.253,-.265)]
for r,z in profiles:
    for j in range(64):vs.append(bp(r*cos(2*pi*j/64),r*sin(2*pi*j/64),z))
for k in range(3):
    for j in range(64):
        a=k*64+j;b=k*64+(j+1)%64;fs.append((a,b,b+64,a+64))
fs.append(tuple(3*64+j for j in range(64)));fs.append(tuple(range(63,-1,-1)))
ob=mesh('Tipped hollow sand bucket',vs,fs,bucketmat);ob.data.materials.append(bucketinside)
for p in ob.data.polygons:
    if p.index>=128:p.material_index=1
tube('Rolled bucket rim',[bp(.422*cos(2*pi*j/64),.422*sin(2*pi*j/64),.33) for j in range(65)],.032,handlema)
tube('Bucket base ring',[bp(.29*cos(2*pi*j/48),.29*sin(2*pi*j/48),-.30) for j in range(49)],.020,bucketmat)
tube('Loose curved bucket handle',[bp(.44*cos(pi*j/32),0,.23+.59*sin(pi*j/32)) for j in range(33)],.031,handlema)
for side in [-1,1]:
    uv('Bucket handle pin',bp(side*.421,0,.22),(.052,.052,.052),handlema,24,12)

# One little flip-flop, caught upside down in mid-tumble.
solemat=mat('Flip-flop watermelon rubber',(.89,.075,.22),.69)
strapmat=mat('Flip-flop yellow straps',(1,.77,.12),.46)
soleedge=mat('Flip-flop cream sole stripe',(.99,.86,.58),.64)
rotS=Euler((.78,-.59,-.47)).to_matrix(); sc=Vector((-3.25,-1.35,1.0))
def sp(x,y,z):return sc+rotS@Vector((x,y,z))
outline=[]
for j in range(64):
    a=2*pi*j/64
    outline.append((.47*cos(a),.205*sin(a)*(1+.17*cos(a))))
vs=[];fs=[]
for z in [-.05,.015,.055]:
    for x,y in outline:vs.append(sp(x,y,z))
for k in range(2):
    for j in range(64):
        a=k*64+j;b=k*64+(j+1)%64;fs.append((a,b,b+64,a+64))
fs.append(tuple(range(63,-1,-1)));fs.append(tuple(128+j for j in range(64)))
ob=mesh('Airborne tumbling flip-flop',vs,fs,solemat);ob.data.materials.append(soleedge)
for p in ob.data.polygons:
    if p.index<64:p.material_index=1
be=ob.modifiers.new('Soft rubber edges','BEVEL');be.width=.025;be.segments=3
for side in [-1,1]:
    tube('Flip flop raised Y strap',[sp(-.19,side*.18,.06),sp(.02,side*.14,.19),sp(.21,0,.13)],.042,strapmat)
tube('Flip flop toe post',[sp(.21,0,.13),sp(.22,0,.054)],.031,strapmat)
for i in range(7):
    tube('Rubber sole tread',[sp(-.30+i*.085,-.125,-.057),sp(-.30+i*.085,.125,-.057)],.008,soleedge)

# A few small sandy granules beneath the objects.
for i in range(65):
    x=random.uniform(-4.3,1.3);y=random.uniform(-1.5,2.9)
    if random.random()<.7:uv('Quiet scattered sand pebble',(x,y,.014),(random.uniform(.009,.025),.014,.012),sandlight,8,6)

# Clear midday light, crisp grounding shadows, and airy sky.
world=bpy.data.worlds.new('Simple clear blue sky');bpy.context.scene.world=world
world.use_nodes=True; world.node_tree.nodes['Background'].inputs['Color'].default_value=(.32,.64,.88,1)
world.node_tree.nodes['Background'].inputs['Strength'].default_value=.55
bpy.ops.object.light_add(type='SUN',location=(-3,-4,9))
sun=bpy.context.object;sun.name='Midday sunlight';sun.data.energy=2.5;sun.data.angle=math.radians(4)
sun.rotation_euler=Vector((2,3,-8)).to_track_quat('-Z','Y').to_euler()
bpy.ops.object.light_add(type='AREA',location=(1,-7,9))
area=bpy.context.object;area.name='Soft sky fill';area.data.energy=550;area.data.shape='DISK';area.data.size=7
area.rotation_euler=(Vector((0,0,2.5))-area.location).to_track_quat('-Z','Y').to_euler()
bpy.ops.object.light_add(type='AREA',location=(-2,4,7))
area=bpy.context.object;area.name='Sunny fur rim';area.data.energy=750;area.data.size=5
area.rotation_euler=(Vector((0,0,3))-area.location).to_track_quat('-Z','Y').to_euler()

# Low, three-quarter action portrait, with breathing room below the leap.
bpy.ops.object.camera_add(location=(7.1,-16.8,6.45))
cam=bpy.context.object;cam.name='Presentation • the instant before BOOP'
target=Vector((-.10,.15,2.27))
cam.rotation_euler=(target-cam.location).to_track_quat('-Z','Y').to_euler()
cam.data.type='ORTHO';cam.data.ortho_scale=10.65
cam.data.lens=48
bpy.context.scene.camera=cam
cam.data.dof.use_dof=False

scene=bpy.context.scene
scene.render.engine='CYCLES'
scene.cycles.samples=64
scene.cycles.use_denoising=True
scene.render.resolution_x=1536;scene.render.resolution_y=1536;scene.render.resolution_percentage=100
scene.view_settings.view_transform='AgX'
scene.view_settings.look='AgX - Medium High Contrast'
scene.render.image_settings.file_format='PNG'
scene.render.film_transparent=False
scene.render.filepath='/mnt/data/corgi_action.png'
scene.world.color=(.4,.65,.85)
# Scene and all core details are explicit mesh geometry for interactive inspection.
bpy.ops.wm.save_as_mainfile(filepath='/mnt/data/scene.blend')
```