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