|
26 | 26 | """
|
27 | 27 | from Model3D import STLModel, Vector3, Normal
|
28 | 28 | from svgwrite import Drawing, rgb
|
| 29 | +import sys |
29 | 30 |
|
30 |
| -resolution = 0.1 # mms |
31 |
| -scale = 10 |
32 |
| -model_file = 'models/yoda.stl' |
| 31 | +def slice_file(f=None, resolution=0.1): |
| 32 | + print("Status: Loading File.") |
33 | 33 |
|
34 |
| -f = open(model_file, 'rb') |
35 |
| -stlobj = None |
| 34 | + stlobj = STLModel(f) |
| 35 | + scale = 10 |
| 36 | + stats = stlobj.stats() |
36 | 37 |
|
37 |
| -stlobj = STLModel(f) |
| 38 | + sub_vertex = Vector3(stats['extents']['x']['lower'], stats['extents']['y']['lower'], stats['extents']['z']['lower']) |
| 39 | + add_vertex = Vector3(0.5,0.5,0.5) |
38 | 40 |
|
39 |
| -stats = stlobj.stats() |
40 |
| -print(stats) |
| 41 | + stlobj.xmin = stlobj.xmax = None |
| 42 | + stlobj.ymin = stlobj.ymax = None |
| 43 | + stlobj.zmin = stlobj.zmax = None |
41 | 44 |
|
42 |
| -sub_vertex = Vector3(stats['extents']['x']['lower'], stats['extents']['y']['lower'], stats['extents']['z']['lower']) |
43 |
| -add_vertex = Vector3(0.5,0.5,0.5) |
| 45 | + print("Status: Scaling Triangles.") |
44 | 46 |
|
45 |
| -for facet in stlobj.triangles: |
46 |
| - facet.vertices[0] -= sub_vertex |
47 |
| - facet.vertices[1] -= sub_vertex |
48 |
| - facet.vertices[2] -= sub_vertex |
| 47 | + for facet in stlobj.triangles: |
| 48 | + facet.vertices[0] -= sub_vertex |
| 49 | + facet.vertices[1] -= sub_vertex |
| 50 | + facet.vertices[2] -= sub_vertex |
49 | 51 |
|
50 |
| - # The lines above have no effect on the normal. |
| 52 | + # The lines above have no effect on the normal. |
51 | 53 |
|
52 |
| - facet.vertices[0] = (facet.vertices[0] * scale) + add_vertex |
53 |
| - facet.vertices[1] = (facet.vertices[1] * scale) + add_vertex |
54 |
| - facet.vertices[2] = (facet.vertices[2] * scale) + add_vertex |
| 54 | + facet.vertices[0] = (facet.vertices[0] * scale) + add_vertex |
| 55 | + facet.vertices[1] = (facet.vertices[1] * scale) + add_vertex |
| 56 | + facet.vertices[2] = (facet.vertices[2] * scale) + add_vertex |
55 | 57 |
|
56 |
| - facet.vertices[0].integerise() |
57 |
| - facet.vertices[1].integerise() |
58 |
| - facet.vertices[2].integerise() |
| 58 | + facet.vertices[0].integerise() |
| 59 | + facet.vertices[1].integerise() |
| 60 | + facet.vertices[2].integerise() |
59 | 61 |
|
60 |
| - # Recalculate the facet normal |
| 62 | + # Recalculate the facet normal |
61 | 63 |
|
62 |
| - u = stlobj.triangles[0].vertices[1] - stlobj.triangles[0].vertices[0] |
63 |
| - v = stlobj.triangles[0].vertices[2] - stlobj.triangles[0].vertices[0] |
| 64 | + u = stlobj.triangles[0].vertices[1] - stlobj.triangles[0].vertices[0] |
| 65 | + v = stlobj.triangles[0].vertices[2] - stlobj.triangles[0].vertices[0] |
64 | 66 |
|
65 |
| - facet.n = Normal((u.y * v.z)-(u.z*v.y), (u.z*v.x)-(u.x*v.z), (u.x*v.y)-(u.y*v.x)) |
66 |
| - stlobj.update_extents(facet) |
67 |
| -# So now, we have all of the points as integers... |
| 67 | + facet.n = Normal((u.y * v.z)-(u.z*v.y), (u.z*v.x)-(u.x*v.z), (u.x*v.y)-(u.y*v.x)) |
| 68 | + stlobj.update_extents(facet) |
| 69 | + # So now, we have all of the points as integers... |
68 | 70 |
|
69 |
| -interval = scale * resolution |
70 |
| -stats = stlobj.stats() |
71 |
| -print (stats) |
| 71 | + print("Status: Calculating Slices") |
72 | 72 |
|
73 |
| -def findInterpolatedPoint(A, B): |
74 |
| - # Find the vector between the two... |
| 73 | + interval = scale * resolution |
| 74 | + stats = stlobj.stats() |
75 | 75 |
|
76 |
| - V = (float(B[0]-A[0]), float(B[1]-A[1]), float(B[2]-A[2])) |
| 76 | + def findInterpolatedPoint(A, B): |
| 77 | + # Find the vector between the two... |
77 | 78 |
|
78 |
| - # Therefore the interpolated point = ('some n' * V)+A |
| 79 | + V = (float(B[0]-A[0]), float(B[1]-A[1]), float(B[2]-A[2])) |
79 | 80 |
|
80 |
| - # ( x ) |
81 |
| - # ( y ) = n*V + A |
82 |
| - # (240) |
| 81 | + # Therefore the interpolated point = ('some n' * V)+A |
83 | 82 |
|
84 |
| - refz = targetz - A[2] |
| 83 | + # ( x ) |
| 84 | + # ( y ) = n*V + A |
| 85 | + # (240) |
85 | 86 |
|
86 |
| - # ( x ) |
87 |
| - # ( y ) = nV |
88 |
| - # (refz) |
| 87 | + refz = targetz - A[2] |
89 | 88 |
|
90 |
| - n = float(refz/V[2]) |
| 89 | + # ( x ) |
| 90 | + # ( y ) = nV |
| 91 | + # (refz) |
91 | 92 |
|
92 |
| - coords = (int(n * V[0] + A[0]), int(n * V[1] + A[1])) |
| 93 | + n = float(refz/V[2]) |
93 | 94 |
|
94 |
| - return (coords) |
| 95 | + coords = (int(n * V[0] + A[0]), int(n * V[1] + A[1])) |
95 | 96 |
|
96 |
| -for targetz in range(0, int(stats['extents']['z']['upper']), int(interval)): |
97 |
| - dwg = Drawing('outputs/svg/'+str(targetz)+'.svg', profile='tiny') |
| 97 | + return (coords) |
98 | 98 |
|
99 |
| - for facet in stlobj.triangles: |
100 |
| - pair = [] |
| 99 | + for targetz in range(0, int(stats['extents']['z']['upper']), int(interval)): |
| 100 | + dwg = Drawing('outputs/svg/'+str(targetz)+'.svg', profile='tiny') |
| 101 | + |
| 102 | + for facet in stlobj.triangles: |
| 103 | + pair = [] |
| 104 | + |
| 105 | + if (facet.vertices[0].z > targetz and facet.vertices[1].z < targetz) or (facet.vertices[0].z < targetz and facet.vertices[1].z > targetz): |
| 106 | + # Calculate the coordinates of one segment at z = targetz (between v[0] and v[1]) |
| 107 | + |
| 108 | + A = (facet.vertices[0].x, facet.vertices[0].y, facet.vertices[0].z) |
| 109 | + B = (facet.vertices[1].x, facet.vertices[1].y, facet.vertices[1].z) |
| 110 | + |
| 111 | + pair.append(findInterpolatedPoint(A, B)) |
| 112 | + |
| 113 | + if (facet.vertices[0].z > targetz and facet.vertices[2].z < targetz) or (facet.vertices[0].z < targetz and facet.vertices[2].z > targetz): |
| 114 | + # Calculate the coordinates of one segment at z = targetz (between v[0] and v[2]) |
| 115 | + |
| 116 | + A = (facet.vertices[0].x, facet.vertices[0].y, facet.vertices[0].z) |
| 117 | + B = (facet.vertices[2].x, facet.vertices[2].y, facet.vertices[2].z) |
101 | 118 |
|
102 |
| - if (facet.vertices[0].z > targetz and facet.vertices[1].z < targetz) or (facet.vertices[0].z < targetz and facet.vertices[1].z > targetz): |
103 |
| - # Calculate the coordinates of one segment at z = targetz (between v[0] and v[1]) |
| 119 | + pair.append(findInterpolatedPoint(A, B)) |
104 | 120 |
|
105 |
| - A = (facet.vertices[0].x, facet.vertices[0].y, facet.vertices[0].z) |
106 |
| - B = (facet.vertices[1].x, facet.vertices[1].y, facet.vertices[1].z) |
| 121 | + if (facet.vertices[1].z > targetz and facet.vertices[2].z < targetz) or (facet.vertices[1].z < targetz and facet.vertices[2].z > targetz): |
| 122 | + # Calculate the coordinates of one segment at z = targetz (between v[1] and v[2]) |
107 | 123 |
|
108 |
| - pair.append(findInterpolatedPoint(A, B)) |
| 124 | + A = (facet.vertices[1].x, facet.vertices[1].y, facet.vertices[1].z) |
| 125 | + B = (facet.vertices[2].x, facet.vertices[2].y, facet.vertices[2].z) |
109 | 126 |
|
110 |
| - if (facet.vertices[0].z > targetz and facet.vertices[2].z < targetz) or (facet.vertices[0].z < targetz and facet.vertices[2].z > targetz): |
111 |
| - # Calculate the coordinates of one segment at z = targetz (between v[0] and v[2]) |
| 127 | + pair.append(findInterpolatedPoint(A, B)) |
112 | 128 |
|
113 |
| - A = (facet.vertices[0].x, facet.vertices[0].y, facet.vertices[0].z) |
114 |
| - B = (facet.vertices[2].x, facet.vertices[2].y, facet.vertices[2].z) |
| 129 | + if facet.vertices[0].z == targetz: |
| 130 | + pair.append((int(facet.vertices[0].x), int(facet.vertices[0].y))) |
| 131 | + elif facet.vertices[1].z == targetz: |
| 132 | + pair.append((int(facet.vertices[1].x), int(facet.vertices[1].y))) |
| 133 | + elif facet.vertices[2].z == targetz: |
| 134 | + pair.append((int(facet.vertices[2].x), int(facet.vertices[2].y))) |
115 | 135 |
|
116 |
| - pair.append(findInterpolatedPoint(A, B)) |
| 136 | + if len(pair) == 2: |
| 137 | + dwg.add(dwg.line(pair[0], pair[1], stroke=rgb(50,50,50, '%'))) |
117 | 138 |
|
118 |
| - if (facet.vertices[1].z > targetz and facet.vertices[2].z < targetz) or (facet.vertices[1].z < targetz and facet.vertices[2].z > targetz): |
119 |
| - # Calculate the coordinates of one segment at z = targetz (between v[1] and v[2]) |
| 139 | + dwg.save() |
120 | 140 |
|
121 |
| - A = (facet.vertices[1].x, facet.vertices[1].y, facet.vertices[1].z) |
122 |
| - B = (facet.vertices[2].x, facet.vertices[2].y, facet.vertices[2].z) |
| 141 | + print("Status: Finished Outputting Slices.c") |
123 | 142 |
|
124 |
| - pair.append(findInterpolatedPoint(A, B)) |
125 | 143 |
|
126 |
| - if facet.vertices[0].z == targetz: |
127 |
| - pair.append((int(facet.vertices[0].x), int(facet.vertices[0].y))) |
128 |
| - elif facet.vertices[1].z == targetz: |
129 |
| - pair.append((int(facet.vertices[1].x), int(facet.vertices[1].y))) |
130 |
| - elif facet.vertices[2].z == targetz: |
131 |
| - pair.append((int(facet.vertices[2].x), int(facet.vertices[2].y))) |
| 144 | +if __name__ == '__main__': |
| 145 | + # Run as a command line program. |
132 | 146 |
|
133 |
| - if len(pair) == 2: |
134 |
| - dwg.add(dwg.line(pair[0], pair[1], stroke=rgb(50,50,50, '%'))) |
| 147 | + import argparse |
| 148 | + parser = argparse.ArgumentParser( |
| 149 | + description='Takes a 3D Model, and slices it at regular intervals') |
| 150 | + parser.add_argument('file', |
| 151 | + metavar='FILE', |
| 152 | + help='File to be sliced', |
| 153 | + nargs='?', |
| 154 | + default='models/yoda.stl', |
| 155 | + type=argparse.FileType('rb')) |
| 156 | + parser.add_argument('-r', '--resolution', type=float, |
| 157 | + default=0.1, |
| 158 | + help='The Z-Axis resolution of the printer, in mms') |
135 | 159 |
|
136 |
| - dwg.save() |
| 160 | + args = parser.parse_args() |
| 161 | + slice_file(args.file, args.resolution) |
0 commit comments