module extrusion(points){ //points[0] must have its points ordered clockwise n = len(points); k = len(points[0]); points_new = [for(L = points) for(p = L) p]; faces = concat([[for(i = [0 : k-1]) i], [for(i = [1 : k]) (n*k)-i]], concat([for (i = [0 : n-2]) for (j = [0 : k-2]) [(i*k)+j+1, (i*k)+j, ((i+1)*k)+j, ((i+1)*k)+j+1]], [for (i = [0 : n-2]) [i*k,(i+1)*k-1,((i+2)*k)-1,(i+1)*k]])); polyhedron(points = points_new, faces = faces, convexity = 10); } module bezier_extrude(ctrl, shape, mod = function (t) 1, mod_x = function(t) 1, mod_y = function (t) 1, sections = 128){ B_0 = ctrl[0]; B_1 = 3*(-ctrl[0] + ctrl[1]); B_2 = 3*(ctrl[0] - 2*ctrl[1] + ctrl[2]); B_3 = -ctrl[0] + 3*(ctrl[1] - ctrl[2]) + ctrl[3]; function bezier(t) = B_0 + t*B_1 + (t^2)*B_2 + (t^3)*B_3; Bn_0 = [B_1.y,-B_1.x]; Bn_1 = [2*B_2.y,(-2)*B_2.x]; Bn_2 = [3*B_3.y,(-3)*B_3.x]; function normal(t) = Bn_0 + t*Bn_1 + (t^2)*Bn_2; slices = [for (i = [0 : sections]) let (t = i/sections, p = bezier(t), normal = normal(t), n = normal/norm(normal)) [for (v = shape) [p.x+(mod(t) * mod_x(t) * n.x * v.x),p.y+(mod(t) * mod_x(t) * n.y * v.x), mod(t) * mod_y(t) * v.y]]]; extrusion(slices); } shape = [[0,0.5],[0.8,0],[0.5,-1],[-0.5,-1],[-0.8,0]]; ctrl = [[0,0],[20,10],[0,20],[10,0]]; wave = function (x) 0.75+0.25*cos(3*360*x); bezier_extrude(ctrl = ctrl, shape = shape, mod = wave, sections = 8192);