Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
cura / opt / cura / lib / uranium / plugins / FileHandlers / STLWriter / STLWriter.py
Size: Mime:
# Copyright (c) 2015 Ultimaker B.V.
# Copyright (c) 2013 David Braam
# Uranium is released under the terms of the AGPLv3 or higher.

from UM.Mesh.MeshWriter import MeshWriter
from UM.Scene.SceneNode import SceneNode
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Logger import Logger

import time
import struct
import os

class STLWriter(MeshWriter):
    ##  Write the Mesh to file.
    #   \param file_name Location to write to
    #   \param storage_device Device to write to.
    #   \param mesh_data MeshData to write.
    def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode):
        nodes = []
        for n in BreadthFirstIterator(node):
            if type(n) is not SceneNode or not n.getMeshData():
                continue

            nodes.append(n)

        if not nodes:
            return False

        if mode == MeshWriter.OutputMode.TextMode:
            self._writeAscii(stream, nodes)
        elif mode == MeshWriter.OutputMode.BinaryMode:
            self._writeBinary(stream, nodes)
        else:
            Logger.log("e", "Unsupported output mode writing STL to stream")
            return False

        return True

    def _writeAscii(self, stream, nodes):
        name = "Uranium STLWriter {0}".format(time.strftime("%a %d %b %Y %H:%M:%S"))
        stream.write("solid {0}\n".format(name))

        for node in nodes:
            mesh_data = node.getMeshData().getTransformed(node.getWorldTransformation())

            if mesh_data.hasIndices():
                verts = mesh_data.getVertices()
                for face in mesh_data.getIndices():
                    stream.write("facet normal 0.0 0.0 0.0\n")
                    stream.write("  outer loop\n")

                    v1 = verts[face[0]]
                    v2 = verts[face[1]]
                    v3 = verts[face[2]]
                    stream.write("    vertex {0} {1} {2}\n".format(v1[0], -v1[2], v1[1]))
                    stream.write("    vertex {0} {1} {2}\n".format(v2[0], -v2[2], v2[1]))
                    stream.write("    vertex {0} {1} {2}\n".format(v3[0], -v3[2], v3[1]))

                    stream.write("  endloop\n")
                    stream.write("endfacet\n")

        stream.write("endsolid {0}\n".format(name))

    def _writeBinary(self, stream, nodes):
        stream.write("Uranium STLWriter {0}".format(time.strftime("%a %d %b %Y %H:%M:%S")).encode().ljust(80, b"\000"))

        face_count = 0
        for node in nodes:
            face_count += node.getMeshData().getFaceCount()

        stream.write(struct.pack("<I", int(face_count))) #Write number of faces to STL

        for node in nodes:
            mesh_data = node.getMeshData().getTransformed(node.getWorldTransformation())

            if mesh_data.hasIndices():
                verts = mesh_data.getVertices()
                for face in mesh_data.getIndices():
                    v1 = verts[face[0]]
                    v2 = verts[face[1]]
                    v3 = verts[face[2]]
                    stream.write(struct.pack("<fff", 0.0, 0.0, 0.0))
                    stream.write(struct.pack("<fff", v1[0], -v1[2], v1[1]))
                    stream.write(struct.pack("<fff", v2[0], -v2[2], v2[1]))
                    stream.write(struct.pack("<fff", v3[0], -v3[2], v3[1]))
                    stream.write(struct.pack("<H", 0))