from koko.lib.shapes import *
from koko.lib.text import *

# Minion (Dispicable Me)
# Model origin is on floor at foot level in center

# Looks like sphere defn is (xcenter, ycenter, zcenter, radius)
# Looks like cylinder defn is (xcenter, ycenter, z1, z2, radius)

# scale_z defn is (part, scale_factor, z_invarient_point) height of point on z axis that stays in place

cad.mm_per_unit = 10

scale = 0.5

# Body
# Body is created from 2 spheres and a cylinder.  The loweer sphere is squashed slightly to provide a flatter bottom.
minion_body = (scale_z(sphere(0,0,scale, scale), scale, 0.5)           # lower sphere
               + scale_z(sphere(0,0,scale*2.5, scale), scale*2.5, 0.9) # upper sphere
               + cylinder(0,0, scale,scale*2.5, scale))
minion_body.color = "yellow"
# playing with some transforms to get a better idea of what the parameters are.
#minion_body = shear_x_z(minion_body, 0.4,0.6, 0.2, 0.1) #fail
#minion_body = shear_x_y(minion_body, 0, 0.5, 0, 0.5) #good
#minion_body = scale_z(minion_body, 0, 0.5) #good
#minion_body = taper_xy_z(minion_body, 0,0, 0,0.5, 1.0, 0.3) #good, the taper cone inverts beyond z1
# Mouth
mouth = extrusion(text("C", 0,0, 0.14), 0, scale)
mouth = rotate_y(rotate_z(mouth, 180), -90)
mouth = scale_z(scale_y(mouth, 0, 3.0), 0, 1.5)
mouth = move(mouth, scale*0.9, 0, scale*2.05)
minion_body -= mouth

# Dungerees
# Dungerees are a copy of the body scaled up slightly so that they cover it.  Chunks are then cut out to leave the final dungeree shape.
dungerees = scale_xy(scale_z(minion_body, scale, 1.05), 0, 0, 1.05)
dungerees -= cube(-scale*1.5,scale*1.5, -scale*1.5,scale*1.5, scale*1.9, scale*4)
dungerees -= cube(-scale*0.9,scale*0.9, -scale*1.5,scale*1.5, scale*1.1, scale*1.7)
dungerees.color = "blue"
pocket = scale_xy(scale_z(dungerees, scale, 1.05), 0, 0, 1.05)
pocket &= cube(0,scale*1.5, -scale*0.3,scale*0.3, scale*1.0,scale*1.5)
dungerees += pocket
gru = extrusion(text("G", 0,0, 0.14), 0, 0.03)
gru = rotate_y(rotate_z(gru, 90), -90)
dungerees -= move(gru, scale*1.05, 0, scale*1.2)

# Glasses
glasses_lens = (cylinder(0,0, 0,scale/4, scale*0.25)
                - cylinder(0,0, 0,scale/4, scale*0.18))
glasses_lens = rotate_y(glasses_lens, 90)
glasses_lens.color = "grey"
glasses = (move(glasses_lens, scale*1.1, -(scale*0.22), scale*2.5)
           + move(glasses_lens, scale*1.1, scale*0.22, scale*2.5))

glasses_strap = (cylinder(0,0, 0,scale*0.2, scale*1.05)
                 - cylinder(0,0, 0,scale*0.2, scale))
glasses_strap = move(glasses_strap, 0,0,scale*2.4)
glasses_strap.color = "black"

# Eyes
# Eyes are squashed flat so that the don't protrude from the glasses lens but still cover all of the glasses strap.
eye = scale_x(sphere(0,0,0, scale*0.2), 0, 0.5)
eye.color = "white"
eyes = (move(eye, scale*1.0, -(scale*0.22), scale*2.5)
        + move(eye, scale*1.0, (scale*0.22), scale*2.5))

# Pupils
pupil = scale_x(sphere(0,0,0, scale*0.07), 0, 0.5)
pupil.color = "brown"
pupils = (move(pupil, scale*1.08, -(scale*0.20), scale*2.45)
           + move(pupil, scale*1.08, (scale*0.20), scale*2.45))

## A bit of mucking about got me these shapes
#mouth = circle(scale, scale*0.5, scale*0.02)
##mouth = sphere(scale,scale*0.5,0, scale*0.2)
#mouth = revolve_y(mouth)
#mouth = revolve_x(mouth)
#mouth = rotate_x(mouth, 90)
#mouth -= cube(-scale*2,scale*2, 0,-scale*2, -scale*2,scale*2)
#mouth = move(mouth, 0,0,scale*2.5)
#
#mouth = (cylinder(0,0, 0,scale/4, scale*0.25)
#                - cylinder(0,0, 0,scale/4, scale*0.18))
#mouth = rotate_y(mouth, 90)
#mouth = move(mouth, scale*1.1, 0, scale*2)



# Legs
leg = move(rotate_y(cone(0,0, 0,scale*0.7, scale*0.5), 180), 0, 0, scale*0.7)
leg.color = "blue"
legs = (move(leg, 0, -scale*0.3, 0)
        + move(leg, 0, scale*0.3, 0))

# Feet
# Made from a squashed sphere that's then truncated
foot = scale_z(sphere(0,0, -scale*0.5, scale*0.5), scale*0.5, 0.5)
foot = scale_y(foot, 0, 0.7)
foot -= cube(-scale,scale, -scale,scale, -scale,0)
foot.color = "black"
feet = (move(foot, scale*0.1, -scale*0.3, 0)
        + move(foot, scale*0.1, scale*0.3, 0))

# Arms
# assemble with elbow joint at 0,0,0 so we don't need to bother with any trig to position it
armr = cylinder(0,0, 0,scale*0.7, scale*0.1) # Upper
armr = rotate_x(armr, -10)
armr += cylinder(0,0, -scale*0.7,0, scale*0.1) # Lower
elbow = sphere(0,0,0, scale*0.1)
armr += elbow
armr = move(armr, 0, -scale*1.05, scale*1.1)
armr.color = "yellow"
arml = reflect_y(armr, 0)

# Hands
# Construct these seperately so that we can make them black
handr = scale_z(sphere(0,0,0, scale*0.2), 0, 2.0)
handr += move(rotate_y(scale_z(sphere(0,0,0, scale*0.10), 0, 2.0), -40), -scale*0.2, 0, 0)
handr += move(rotate_y(scale_z(sphere(0,0,0, scale*0.10), 0, 2.0), 40), scale*0.2, 0, 0)
handr = move(handr, 0, -scale*1.05, scale*0.2)
handr -= cube(-scale*2,scale*2, -scale*2,scale*2, -scale,0) # chop off at ground level
handr.color = "black"
handl = reflect_y(handr, 0)

# And finally the piece de resistance...
# The Key Ring Loop
loop = (cylinder(0,0, 0,scale/4, scale*0.35)
                - cylinder(0,0, 0,scale/4, scale*0.2))
loop = rotate_y(loop, 90)
loop = move(loop, scale/8, 0, scale*3.5)
loop.color = "yellow"


# Assemble parts seperately so that we can give them unique colours
cad.shapes = minion_body, dungerees, glasses, glasses_strap, eyes, pupils, legs, feet, armr, arml, handr, handl, loop

