chiark / gitweb /
Add uppercase STL and HEX to file dialog filters for linux/MacOS
[cura.git] / Cura / cura_sf / fabmetheus_utilities / geometry / geometry_tools / path.py
1 """
2 Path.
3
4 """
5
6 from __future__ import absolute_import
7 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
8 import __init__
9
10 from fabmetheus_utilities.geometry.geometry_tools import dictionary
11 from fabmetheus_utilities.geometry.geometry_tools import vertex
12 from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting
13 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
14 from fabmetheus_utilities.geometry.geometry_utilities import matrix
15 from fabmetheus_utilities.vector3 import Vector3
16 from fabmetheus_utilities import euclidean
17 from fabmetheus_utilities import svg_writer
18 from fabmetheus_utilities import xml_simple_reader
19 from fabmetheus_utilities import xml_simple_writer
20
21
22 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
23 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
24 __date__ = '$Date: 2008/02/05 $'
25 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
26
27
28 def convertElementNode(elementNode, geometryOutput):
29         'Convert the xml element by geometryOutput.'
30         if geometryOutput == None:
31                 return
32         if len(geometryOutput) < 1:
33                 return
34         if len(geometryOutput) == 1:
35                 firstLoop = geometryOutput[0]
36                 if firstLoop.__class__ == list:
37                         geometryOutput = firstLoop
38         firstElement = geometryOutput[0]
39         if firstElement.__class__ == list:
40                 if len(firstElement) > 1:
41                         convertElementNodeRenameByPaths(elementNode, geometryOutput)
42                 else:
43                         convertElementNodeByPath(elementNode, firstElement)
44         else:
45                 convertElementNodeByPath(elementNode, geometryOutput)
46
47 def convertElementNodeByPath(elementNode, geometryOutput):
48         'Convert the xml element to a path xml element.'
49         createLinkPath(elementNode)
50         elementNode.xmlObject.vertexes = geometryOutput
51         vertex.addGeometryList(elementNode, geometryOutput)
52
53 def convertElementNodeRenameByPaths(elementNode, geometryOutput):
54         'Convert the xml element to a path xml element and add paths.'
55         createLinkPath(elementNode)
56         for geometryOutputChild in geometryOutput:
57                 pathElement = xml_simple_reader.ElementNode()
58                 pathElement.setParentAddToChildNodes(elementNode)
59                 convertElementNodeByPath(pathElement, geometryOutputChild)
60
61 def createLinkPath(elementNode):
62         'Create and link a path object.'
63         elementNode.localName = 'path'
64         elementNode.linkObject(Path())
65
66 def processElementNode(elementNode):
67         'Process the xml element.'
68         evaluate.processArchivable(Path, elementNode)
69
70
71 class Path(dictionary.Dictionary):
72         'A path.'
73         def __init__(self):
74                 'Add empty lists.'
75                 dictionary.Dictionary.__init__(self)
76                 self.matrix4X4 = matrix.Matrix()
77                 self.oldChainTetragrid = None
78                 self.transformedPath = None
79                 self.vertexes = []
80
81         def addXMLInnerSection(self, depth, output):
82                 'Add the xml section for this object.'
83                 if self.matrix4X4 != None:
84                         self.matrix4X4.addXML(depth, output)
85                 xml_simple_writer.addXMLFromVertexes(depth, output, self.vertexes)
86
87         def getFabricationExtension(self):
88                 'Get fabrication extension.'
89                 return 'svg'
90
91         def getFabricationText(self, addLayerTemplate):
92                 'Get fabrication text.'
93                 carving = SVGFabricationCarving(addLayerTemplate, self.elementNode)
94                 carving.setCarveLayerHeight(setting.getSheetThickness(self.elementNode))
95                 carving.processSVGElement(self.elementNode.getOwnerDocument().fileName)
96                 return str(carving)
97
98         def getMatrix4X4(self):
99                 "Get the matrix4X4."
100                 return self.matrix4X4
101
102         def getMatrixChainTetragrid(self):
103                 'Get the matrix chain tetragrid.'
104                 return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid)
105
106         def getPaths(self):
107                 'Get all paths.'
108                 self.transformedPath = None
109                 if len(self.vertexes) > 0:
110                         return dictionary.getAllPaths([self.vertexes], self)
111                 return dictionary.getAllPaths([], self)
112
113         def getTransformedPaths(self):
114                 'Get all transformed paths.'
115                 if self.elementNode == None:
116                         return dictionary.getAllPaths([self.vertexes], self)
117                 chainTetragrid = self.getMatrixChainTetragrid()
118                 if self.oldChainTetragrid != chainTetragrid:
119                         self.oldChainTetragrid = chainTetragrid
120                         self.transformedPath = None
121                 if self.transformedPath == None:
122                         self.transformedPath = matrix.getTransformedVector3s(chainTetragrid, self.vertexes)
123                 if len(self.transformedPath) > 0:
124                         return dictionary.getAllTransformedPaths([self.transformedPath], self)
125                 return dictionary.getAllTransformedPaths([], self)
126
127
128 class SVGFabricationCarving:
129         'An svg carving.'
130         def __init__(self, addLayerTemplate, elementNode):
131                 'Add empty lists.'
132                 self.addLayerTemplate = addLayerTemplate
133                 self.elementNode = elementNode
134                 self.layerHeight = 1.0
135                 self.loopLayers = []
136
137         def __repr__(self):
138                 'Get the string representation of this carving.'
139                 return self.getCarvedSVG()
140
141         def addXML(self, depth, output):
142                 'Add xml for this object.'
143                 xml_simple_writer.addXMLFromObjects(depth, self.loopLayers, output)
144
145         def getCarveBoundaryLayers(self):
146                 'Get the  boundary layers.'
147                 return self.loopLayers
148
149         def getCarveCornerMaximum(self):
150                 'Get the corner maximum of the vertexes.'
151                 return self.cornerMaximum
152
153         def getCarveCornerMinimum(self):
154                 'Get the corner minimum of the vertexes.'
155                 return self.cornerMinimum
156
157         def getCarvedSVG(self):
158                 'Get the carved svg text.'
159                 return svg_writer.getSVGByLoopLayers(self.addLayerTemplate, self, self.loopLayers)
160
161         def getCarveLayerHeight(self):
162                 'Get the layer height.'
163                 return self.layerHeight
164
165         def getFabmetheusXML(self):
166                 'Return the fabmetheus XML.'
167                 return self.elementNode.getOwnerDocument().getOriginalRoot()
168
169         def getInterpretationSuffix(self):
170                 'Return the suffix for a carving.'
171                 return 'svg'
172
173         def processSVGElement(self, fileName):
174                 'Parse SVG element and store the layers.'
175                 self.fileName = fileName
176                 paths = self.elementNode.xmlObject.getPaths()
177                 oldZ = None
178                 self.loopLayers = []
179                 loopLayer = None
180                 for path in paths:
181                         if len(path) > 0:
182                                 z = path[0].z
183                                 if z != oldZ:
184                                         loopLayer = euclidean.LoopLayer(z)
185                                         self.loopLayers.append(loopLayer)
186                                         oldZ = z
187                                 loopLayer.loops.append(euclidean.getComplexPath(path))
188                 if len(self.loopLayers) < 1:
189                         return
190                 self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0)
191                 self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0)
192                 svg_writer.setSVGCarvingCorners(self.cornerMaximum, self.cornerMinimum, self.layerHeight, self.loopLayers)
193
194         def setCarveImportRadius( self, importRadius ):
195                 'Set the import radius.'
196                 pass
197
198         def setCarveIsCorrectMesh( self, isCorrectMesh ):
199                 'Set the is correct mesh flag.'
200                 pass
201
202         def setCarveLayerHeight( self, layerHeight ):
203                 'Set the layer height.'
204                 self.layerHeight = layerHeight