chiark / gitweb /
Add loading improvement to changelog.
[cura.git] / Cura / util / stl.py
1 import sys, math, re, os, struct, time
2
3 import mesh
4
5 class stlModel(mesh.mesh):
6         def __init__(self):
7                 super(stlModel, self).__init__()
8
9         def load(self, filename):
10                 f = open(filename, "rb")
11                 if f.read(5).lower() == "solid":
12                         self._loadAscii(f)
13                         if self.vertexCount < 3:
14                                 f.seek(5, os.SEEK_SET)
15                                 self._loadBinary(f)
16                 else:
17                         self._loadBinary(f)
18                 f.close()
19                 self._postProcessAfterLoad()
20                 return self
21         
22         def _loadAscii(self, f):
23                 cnt = 0
24                 for line in f:
25                         if 'vertex' in line:
26                                 cnt += 1
27                 self._prepareVertexCount(int(cnt))
28                 f.seek(5, os.SEEK_SET)
29                 cnt = 0
30                 for line in f:
31                         if 'vertex' in line:
32                                 data = line.split()
33                                 self.addVertex(float(data[1]), float(data[2]), float(data[3]))
34
35         def _loadBinary(self, f):
36                 #Skip the header
37                 f.read(80-5)
38                 faceCount = struct.unpack('<I', f.read(4))[0]
39                 self._prepareVertexCount(faceCount * 3)
40                 for idx in xrange(0, faceCount):
41                         data = struct.unpack("<ffffffffffffH", f.read(50))
42                         self.addVertex(data[3], data[4], data[5])
43                         self.addVertex(data[6], data[7], data[8])
44                         self.addVertex(data[9], data[10], data[11])
45
46 def saveAsSTL(mesh, filename):
47         f = open(filename, 'wb')
48         #Write the STL binary header. This can contain any info, except for "SOLID" at the start.
49         f.write(("CURA BINARY STL EXPORT. " + time.strftime('%a %d %b %Y %H:%M:%S')).ljust(80, '\000'))
50         #Next follow 4 binary bytes containing the amount of faces, and then the face information.
51         f.write(struct.pack("<I", int(mesh.vertexCount / 3)))
52         for idx in xrange(0, mesh.vertexCount, 3):
53                 v1 = mesh.origonalVertexes[idx]
54                 v2 = mesh.origonalVertexes[idx+1]
55                 v3 = mesh.origonalVertexes[idx+2]
56                 f.write(struct.pack("<fff", 0.0, 0.0, 0.0))
57                 f.write(struct.pack("<fff", v1[0], v1[1], v1[2]))
58                 f.write(struct.pack("<fff", v2[0], v2[1], v2[2]))
59                 f.write(struct.pack("<fff", v3[0], v3[1], v3[2]))
60                 f.write(struct.pack("<H", 0))
61         f.close()
62
63 if __name__ == '__main__':
64         for filename in sys.argv[1:]:
65                 m = stlModel().load(filename)
66                 print("Loaded %d faces" % (m.vertexCount / 3))
67                 parts = m.splitToParts()
68                 for p in parts:
69                         saveAsSTL(p, "export_%i.stl" % parts.index(p))
70