# install euclid and numpy packages from euclid import Vector3, Matrix4 import numpy as np import math execfile("stl-writer.py") # number of points on the circle PRECISE=100 # number of circles to be placed across the path NUM_CIRCLES = 500 # connect corresponding points between two instances of same polygon def get_mesh(poly1, poly2, precision): faces = [] for i in range(precision): p1 = i p2 = (i + 1) % precision face = [poly1[p1], poly1[p2], poly2[p2], poly2[p1]] faces.append(face) # print str(i) + " " + str(face) # print faces return faces # draw a catmull spline def spline_4p(t, p_1, p0, p1, p2 ): """ Catmull-Rom (Ps can be numpy vectors or arrays too: colors, curves ...) """ # wikipedia Catmull-Rom -> Cubic_Hermite_spline # 0 -> p0, 1 -> p1, 1/2 -> (- p_1 + 9 p0 + 9 p1 - p2) / 16 # assert 0 <= t <= 1 return ( t*((2-t)*t - 1) * p_1 + (t*t*(3*t - 5) + 2) * p0 + t*((4 - 3*t)*t + 1) * p1 + (t-1)*t*t * p2 ) / 2 # control points, note first and last points are repeated P = np.array([[0, 0, 0], [0, 0, 0], [1, 1, 2], [0.5, 0, 3], [-1, 2, 4], [-0.5, 0, 6], [-0.5, 0, 6]]) # calculate the path with NUM_CIRCLE points along it path = np.array(P[0]) k=NUM_CIRCLES/(len(P) - 3) print k for j in range( 1, len(P)-2 ): # skip the ends for t in range(1,k): # t: 0 .1 .2 .. .9 p = spline_4p( 1.0*t/k, P[j-1], P[j], P[j+1], P[j+2] ) path = np.vstack((path, p)) #path = np.vstack((path, P[2:4])) cylinder = [] for i in range(3,NUM_CIRCLES-3): shape1 = [Vector3(math.cos(x) + path[i-1][0], math.sin(x) + path[i-1][1], path[i-1][2]) for x in np.linspace(0,2*math.pi,PRECISE,endpoint=False)] shape2 = [Vector3(math.cos(x) + path[i][0], math.sin(x) + path[i][1], path[i][2]) for x in np.linspace(0,2*math.pi,PRECISE,endpoint=False)] faces = get_mesh(shape1, shape2, PRECISE) cylinder.extend(faces) with open('cylinder.stl', 'wb') as fp: writer = ASCII_STL_Writer(fp) faces = [] for face in cylinder: faces.append([face[0].xyz, face[1].xyz, face[2].xyz, face[3].xyz]) #print faces writer.add_faces(faces) writer.close()