Source code for BasicTools.IO.StlWriter

# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#

"""Stl file writer
"""
import numpy as np

from BasicTools.IO.WriterBase import WriterBase as WriterBase
import BasicTools.Containers.ElementNames as EN


[docs]def WriteMeshToStl(filename, mesh, normals = None): """Function API for writing mesh in the stl format file. Parameters ---------- filename : str name with path to the file to be created (relative or absolute) mesh : UnstructuredMesh the mesh to be exported normals : np.ndarray, optional containing the normal at each element of the surface, by default None """ OW = StlWriter() OW.Open(filename) OW.Write(mesh, normals=normals) OW.Close()
[docs]class StlWriter(WriterBase): """Class to write Unstructured surface mesh on disk in the stl format file """ def __init__(self): super(StlWriter,self).__init__() self.extractSkin = True def __str__(self): res = 'StlWriter : \n' res += ' FileName : '+str(self.fileName)+'\n' return res
[docs] def SetFileName(self,fileName): """Sets the name of the file to read Parameters ---------- fileName : str name of the file to read """ self.fileName = fileName
[docs] def Close(self): if self.isOpen(): super(StlWriter,self).Close()
[docs] def Write(self, meshObject, normals=None, Name= None, PointFieldsNames=None, PointFields=None, CellFieldsNames=None, CellFields=None, GridFieldsNames=None, GridFields=None): """Write mesh to file in stl format Parameters ---------- meshObject : UnstructuredMesh the mesh to be written normals : np.ndarray, optional containing the normal at each element of the surface, by default None Name : str, optional name of the surface to write, by default None PointFieldsNames : None Not Used, by default None PointFields : None Not Used, by default None CellFieldsNames : None Not Used, by default None CellFields : None Not Used, by default None GridFieldsNames : None Not Used, by default None GridFields : None Not Used, by default None """ from BasicTools.Containers.UnstructuredMesh import ElementsContainer tris = ElementsContainer(EN.Triangle_3) tris.Merge(meshObject.GetElementsOfType(EN.Triangle_3)) nodes = meshObject.nodes if nodes.shape[1] < 3: nodes = np.hstack((nodes,)+(np.zeros((nodes.shape[0],1)),)*(3-nodes.shape[1]) ) if self.extractSkin : from BasicTools.Containers.UnstructuredMeshModificationTools import ComputeSkin skin = ComputeSkin(meshObject) elements = skin.GetElementsOfType(EN.Triangle_3) tris.Merge(elements) #self.PrintDebug(Name) if Name is None: Name == "Solid" self.writeText("solid {}\n".format(Name)) for i in range(tris.GetNumberOfElements()): if normals is not None: self.writeText(" facet normal {}\n".format(" ".join(map(str,normals[i,:])) )) else: p0 = nodes[tris.connectivity[i,0],:] p1 = nodes[tris.connectivity[i,1],:] p2 = nodes[tris.connectivity[i,2],:] normal = np.cross(p1-p0,p2-p0) normal = normal/np.linalg.norm(normal) self.writeText(" facet normal {}\n".format(" ".join(map(str,normal)) )) self.writeText(" outer loop\n") for p in range(3): self.writeText(" vertex {}\n".format(" ".join(map(str,nodes[tris.connectivity[i,p],:] )))) self.writeText(" endloop\n") self.writeText(" endfacet\n") self.writeText("endsolid\n")
from BasicTools.IO.IOFactory import RegisterWriterClass RegisterWriterClass(".stl",StlWriter)
[docs]def CheckIntegrity(): data = u""" solid cube_corner facet normal 0.0 -1.0 0.0 outer loop vertex 0.0 0.0 0.0 vertex 1.0 0.0 0.0 vertex 0.0 0.0 1.0 endloop endfacet facet normal 0.0 0.0 -1.0 outer loop vertex 0.0 0.0 0.0 vertex 0.0 1.0 0.0 vertex 1.0 0.0 0.0 endloop endfacet facet normal -1.0 0.0 0.0 outer loop vertex 0.0 0.0 0.0 vertex 0.0 0.0 1.0 vertex 0.0 1.0 0.0 endloop endfacet facet normal 0.577 0.577 0.577 outer loop vertex 1.0 0.0 0.0 vertex 0.0 1.0 0.0 vertex 0.0 0.0 1.0 endloop endfacet endsolid""" from BasicTools.IO.StlReader import ReadStl as ReadStl from BasicTools.Helpers.Tests import TestTempDir res = ReadStl(string=data) print(res) tempdir = TestTempDir.GetTempPath() WriteMeshToStl(tempdir+"Test_StlWriter.stl",res) WriteMeshToStl(tempdir+"Test_StlWriter_with_normals.stl",res, normals =res.elemFields["normals"]) ow = StlWriter() print(ow) return("ok")
if __name__ == '__main__': print(CheckIntegrity())# pragma: no cover