1
1
import struct
2
2
import numpy as np
3
-
3
+ from itertools import product
4
4
try :
5
5
from .cwrapped import tessellate
6
6
c_lib = True
@@ -61,7 +61,6 @@ def roll2d(image, shifts):
61
61
62
62
63
63
def numpy2stl (A , fn , scale = 0.1 , mask_val = None , ascii = False ,
64
- calc_normals = False ,
65
64
max_width = 235. ,
66
65
max_depth = 140. ,
67
66
max_height = 150. ,
@@ -85,8 +84,6 @@ def numpy2stl(A, fn, scale=0.1, mask_val=None, ascii=False,
85
84
86
85
ascii (bool) - sets the STL format to ascii or binary (default)
87
86
88
- calc_normals (bool) - sets whether surface normals are calculated or not
89
-
90
87
max_width, max_depth, max_height (floats) - maximum size of the stl
91
88
object (in mm). Match this to
92
89
the dimensions of a 3D printer
@@ -104,15 +101,90 @@ def numpy2stl(A, fn, scale=0.1, mask_val=None, ascii=False,
104
101
105
102
m , n = A .shape
106
103
if n >= m :
104
+ # rotate to best fit a printing platform
107
105
A = np .rot90 (A , k = 3 )
108
106
m , n = n , m
109
107
A = scale * (A - A .min ())
110
108
111
109
if not mask_val :
112
110
mask_val = A .min () - 1.
113
- A = np .ascontiguousarray (A , dtype = float )
114
111
115
- facets = np .asarray (tessellate (A , mask_val , min_thickness_percent , solid ))
112
+ if c_lib and not force_python : # try to use c library
113
+ # needed for memoryviews
114
+ A = np .ascontiguousarray (A , dtype = float )
115
+
116
+ facets = np .asarray (tessellate (A , mask_val , min_thickness_percent ,
117
+ solid ))
118
+ # center on platform
119
+ facets [:, 3 ::3 ] += - m / 2
120
+ facets [:, 4 ::3 ] += - n / 2
121
+
122
+ else : # use python + numpy
123
+ facets = []
124
+ mask = np .zeros ((m , n ))
125
+ print ("Creating top mesh..." )
126
+ for i , k in product (range (m - 1 ), range (n - 1 )):
127
+
128
+ this_pt = np .array ([i - m / 2. , k - n / 2. , A [i , k ]])
129
+ top_right = np .array ([i - m / 2. , k + 1 - n / 2. , A [i , k + 1 ]])
130
+ bottom_left = np .array ([i + 1. - m / 2. , k - n / 2. , A [i + 1 , k ]])
131
+ bottom_right = np .array (
132
+ [i + 1. - m / 2. , k + 1 - n / 2. , A [i + 1 , k + 1 ]])
133
+
134
+ n1 , n2 = np .zeros (3 ), np .zeros (3 )
135
+
136
+ if (this_pt [- 1 ] > mask_val and top_right [- 1 ] > mask_val and
137
+ bottom_left [- 1 ] > mask_val ):
138
+
139
+ facet = np .concatenate ([n1 , top_right , this_pt , bottom_right ])
140
+ mask [i , k ] = 1
141
+ mask [i , k + 1 ] = 1
142
+ mask [i + 1 , k ] = 1
143
+ facets .append (facet )
144
+
145
+ if (this_pt [- 1 ] > mask_val and bottom_right [- 1 ] > mask_val and
146
+ bottom_left [- 1 ] > mask_val ):
147
+
148
+ facet = np .concatenate (
149
+ [n2 , bottom_right , this_pt , bottom_left ])
150
+ facets .append (facet )
151
+ mask [i , k ] = 1
152
+ mask [i + 1 , k + 1 ] = 1
153
+ mask [i + 1 , k ] = 1
154
+ facets = np .array (facets )
155
+
156
+ if solid :
157
+ print ("Computed edges..." )
158
+ edge_mask = np .sum ([roll2d (mask , (i , k ))
159
+ for i , k in product ([- 1 , 0 , 1 ], repeat = 2 )],
160
+ axis = 0 )
161
+ edge_mask [np .where (edge_mask == 9. )] = 0.
162
+ edge_mask [np .where (edge_mask != 0. )] = 1.
163
+ edge_mask [0 ::m - 1 , :] = 1.
164
+ edge_mask [:, 0 ::n - 1 ] = 1.
165
+ X , Y = np .where (edge_mask == 1. )
166
+ locs = zip (X - m / 2. , Y - n / 2. )
167
+
168
+ zvals = facets [:, 5 ::3 ]
169
+ zmin , zthickness = zvals .min (), zvals .ptp ()
170
+
171
+ minval = zmin - min_thickness_percent * zthickness
172
+
173
+ bottom = []
174
+ print ("Extending edges, creating bottom..." )
175
+ for i , facet in enumerate (facets ):
176
+ if (facet [3 ], facet [4 ]) in locs :
177
+ facets [i ][5 ] = minval
178
+ if (facet [6 ], facet [7 ]) in locs :
179
+ facets [i ][8 ] = minval
180
+ if (facet [9 ], facet [10 ]) in locs :
181
+ facets [i ][11 ] = minval
182
+ this_bottom = np .concatenate (
183
+ [facet [:3 ], facet [6 :8 ], [minval ], facet [3 :5 ], [minval ],
184
+ facet [9 :11 ], [minval ]])
185
+ bottom .append (this_bottom )
186
+
187
+ facets = np .concatenate ([facets , bottom ])
116
188
117
189
xsize = facets [:, 3 ::3 ].ptp ()
118
190
if xsize > max_width :
0 commit comments