1 """
2 This page is in the table of contents.
3 The stl.py script is an import translator plugin to get a carving from an stl file.
4
5 An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
6
7 The getCarving function takes the file name of an stl file and returns the carving.
8
9 STL is an inferior triangle surface format, described at:
10 http://en.wikipedia.org/wiki/STL_(file_format)
11
12 A good triangle surface format is the GNU Triangulated Surface format which is described at:
13 http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
14
15 """
16
17 from fabmetheus_utilities.geometry.geometry_tools import face
18 from fabmetheus_utilities.geometry.solids import triangle_mesh
19 from fabmetheus_utilities.vector3 import Vector3
20 from fabmetheus_utilities import archive
21 from struct import unpack
22
23 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
24 __credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
25 __date__ = '$Date: 2008/21/04 $'
26 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
27
28
39
40 -def addFacesGivenText( stlText, triangleMesh, vertexIndexTable ):
41 "Add faces given stl text."
42 lines = archive.getTextLines( stlText )
43 vertexes = []
44 for line in lines:
45 if line.find('vertex') != - 1:
46 vertexes.append( getVertexGivenLine(line) )
47 addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes )
48
50 "Add faces given stl text."
51 for vertexIndex in xrange( 0, len(vertexes), 3 ):
52 faceGivenLines = face.Face()
53 faceGivenLines.index = len( triangleMesh.faces )
54 for i in xrange( vertexIndex, vertexIndex + 3 ):
55 vertex = vertexes[i]
56 vertexUniqueIndex = len( vertexIndexTable )
57 if str(vertex) in vertexIndexTable:
58 vertexUniqueIndex = vertexIndexTable[ str(vertex) ]
59 else:
60 vertexIndexTable[ str(vertex) ] = vertexUniqueIndex
61 triangleMesh.vertexes.append(vertex)
62 faceGivenLines.vertexIndexes.append( vertexUniqueIndex )
63 triangleMesh.faces.append( faceGivenLines )
64
66 "Get the triangle mesh for the stl file."
67 if fileName == '':
68 return None
69 stlData = archive.getFileText(fileName, True, 'rb')
70 if stlData == '':
71 return None
72 triangleMesh = triangle_mesh.TriangleMesh()
73 vertexIndexTable = {}
74 numberOfVertexStrings = stlData.count('vertex')
75 requiredVertexStringsForText = max( 2, len( stlData ) / 8000 )
76 if numberOfVertexStrings > requiredVertexStringsForText:
77 addFacesGivenText( stlData, triangleMesh, vertexIndexTable )
78 else:
79
80 addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable )
81 return triangleMesh
82
84 "Get the float, replacing commas if necessary because an inferior program is using a comma instead of a point for the decimal point."
85 try:
86 return float(floatString)
87 except:
88 return float( floatString.replace(',', '.') )
89
91 "Get vertex given stl vertex line."
92 return unpack('f', stlData[ byteIndex : byteIndex + 4 ] )[0]
93
95 "Get vertex given stl vertex line."
96 x = unpack('f', stlData[ byteIndex : byteIndex + 4 ] )[0]
97 y = unpack('f', stlData[ byteIndex + 4 : byteIndex + 8 ] )[0]
98 z = unpack('f', stlData[ byteIndex + 8 : byteIndex + 12 ] )[0]
99 return Vector3( x,y,z )
100
102 "Get vertex given stl vertex line."
103 splitLine = line.split()
104 return Vector3( getFloat(splitLine[1]), getFloat( splitLine[2] ), getFloat( splitLine[3] ) )
105