Advertisement
Guest User

stl-writer.py

a guest
Oct 18th, 2013
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.00 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #coding:utf-8
  3. # Purpose: Export 3D objects, build of faces with 3 or 4 vertices, as ASCII or Binary STL file.
  4. # License: MIT License
  5.  
  6. import struct
  7.  
  8. ASCII_FACET = """  facet normal 0 0 0
  9.    outer loop
  10.      vertex {face[0][0]:.4f} {face[0][1]:.4f} {face[0][2]:.4f}
  11.      vertex {face[1][0]:.4f} {face[1][1]:.4f} {face[1][2]:.4f}
  12.      vertex {face[2][0]:.4f} {face[2][1]:.4f} {face[2][2]:.4f}
  13.    endloop
  14.  endfacet
  15. """
  16.  
  17. BINARY_HEADER ="80sI"
  18. BINARY_FACET = "12fH"
  19.  
  20. class ASCII_STL_Writer:
  21.     """ Export 3D objects build of 3 or 4 vertices as ASCII STL file.
  22.    """
  23.     def __init__(self, stream):
  24.         self.fp = stream
  25.         self._write_header()
  26.  
  27.     def _write_header(self):
  28.         self.fp.write("solid python\n")
  29.  
  30.     def close(self):
  31.         self.fp.write("endsolid python\n")
  32.  
  33.     def _write(self, face):
  34.         self.fp.write(ASCII_FACET.format(face=face))
  35.  
  36.     def _split(self, face):
  37.         p1, p2, p3, p4 = face
  38.         return (p1, p2, p3), (p3, p4, p1)
  39.  
  40.     def add_face(self, face):
  41.         """ Add one face with 3 or 4 vertices. """
  42.         if len(face) == 4:
  43.             face1, face2 = self._split(face)
  44.             self._write(face1)
  45.             self._write(face2)
  46.         elif len(face) == 3:
  47.             self._write(face)
  48.         else:
  49.             raise ValueError('only 3 or 4 vertices for each face')
  50.  
  51.     def add_faces(self, faces):
  52.         """ Add many faces. """
  53.         for face in faces:
  54.             self.add_face(face)
  55.  
  56. class Binary_STL_Writer(ASCII_STL_Writer):
  57.     """ Export 3D objects build of 3 or 4 vertices as binary STL file.
  58.    """
  59.     def __init__(self, stream):
  60.         self.counter = 0
  61.         super(Binary_STL_Writer, self).__init__(stream)
  62.  
  63.     def close(self):
  64.         self._write_header()
  65.  
  66.     def _write_header(self):
  67.         self.fp.seek(0)
  68.         self.fp.write(struct.pack(BINARY_HEADER, b'Python Binary STL Writer', self.counter))
  69.  
  70.     def _write(self, face):
  71.         self.counter += 1
  72.         data = [
  73.             0., 0., 0.,
  74.             face[0][0], face[0][1], face[0][2],
  75.             face[1][0], face[1][1], face[1][2],
  76.             face[2][0], face[2][1], face[2][2],
  77.             0
  78.         ]
  79.         self.fp.write(struct.pack(BINARY_FACET, *data))
  80.  
  81.  
  82. def example():
  83.     def get_cube():
  84.         # cube corner points
  85.         s = 3.
  86.         p1 = (0, 0, 0)
  87.         p2 = (0, 0, s)
  88.         p3 = (0, s, 0)
  89.         p4 = (0, s, s)
  90.         p5 = (s, 0, 0)
  91.         p6 = (s, 0, s)
  92.         p7 = (s, s, 0)
  93.         p8 = (s, s, s)
  94.  
  95.         # define the 6 cube faces
  96.         # faces just lists of 3 or 4 vertices
  97.         return [
  98.             [p1, p5, p7, p3],
  99.             [p1, p5, p6, p2],
  100.             [p5, p7, p8, p6],
  101.             [p7, p8, p4, p3],
  102.             [p1, p3, p4, p2],
  103.             [p2, p6, p8, p4],
  104.         ]
  105.  
  106.     with open('cube.stl', 'wb') as fp:
  107.         writer = ASCII_STL_Writer(fp)
  108.         writer.add_faces(get_cube())
  109.         writer.close()
  110.  
  111. if __name__ == '__main__':
  112.     example()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement