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.
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
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'
28 def convertElementNode(elementNode, geometryOutput):
29 'Convert the xml element by geometryOutput.'
30 if geometryOutput == None:
32 if len(geometryOutput) < 1:
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)
43 convertElementNodeByPath(elementNode, firstElement)
45 convertElementNodeByPath(elementNode, geometryOutput)
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)
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)
61 def createLinkPath(elementNode):
62 'Create and link a path object.'
63 elementNode.localName = 'path'
64 elementNode.linkObject(Path())
66 def processElementNode(elementNode):
67 'Process the xml element.'
68 evaluate.processArchivable(Path, elementNode)
71 class Path(dictionary.Dictionary):
75 dictionary.Dictionary.__init__(self)
76 self.matrix4X4 = matrix.Matrix()
77 self.oldChainTetragrid = None
78 self.transformedPath = None
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)
87 def getFabricationExtension(self):
88 'Get fabrication extension.'
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)
98 def getMatrix4X4(self):
100 return self.matrix4X4
102 def getMatrixChainTetragrid(self):
103 'Get the matrix chain tetragrid.'
104 return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid)
108 self.transformedPath = None
109 if len(self.vertexes) > 0:
110 return dictionary.getAllPaths([self.vertexes], self)
111 return dictionary.getAllPaths([], self)
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)
128 class SVGFabricationCarving:
130 def __init__(self, addLayerTemplate, elementNode):
132 self.addLayerTemplate = addLayerTemplate
133 self.elementNode = elementNode
134 self.layerHeight = 1.0
138 'Get the string representation of this carving.'
139 return self.getCarvedSVG()
141 def addXML(self, depth, output):
142 'Add xml for this object.'
143 xml_simple_writer.addXMLFromObjects(depth, self.loopLayers, output)
145 def getCarveBoundaryLayers(self):
146 'Get the boundary layers.'
147 return self.loopLayers
149 def getCarveCornerMaximum(self):
150 'Get the corner maximum of the vertexes.'
151 return self.cornerMaximum
153 def getCarveCornerMinimum(self):
154 'Get the corner minimum of the vertexes.'
155 return self.cornerMinimum
157 def getCarvedSVG(self):
158 'Get the carved svg text.'
159 return svg_writer.getSVGByLoopLayers(self.addLayerTemplate, self, self.loopLayers)
161 def getCarveLayerHeight(self):
162 'Get the layer height.'
163 return self.layerHeight
165 def getFabmetheusXML(self):
166 'Return the fabmetheus XML.'
167 return self.elementNode.getOwnerDocument().getOriginalRoot()
169 def getInterpretationSuffix(self):
170 'Return the suffix for a carving.'
173 def processSVGElement(self, fileName):
174 'Parse SVG element and store the layers.'
175 self.fileName = fileName
176 paths = self.elementNode.xmlObject.getPaths()
184 loopLayer = euclidean.LoopLayer(z)
185 self.loopLayers.append(loopLayer)
187 loopLayer.loops.append(euclidean.getComplexPath(path))
188 if len(self.loopLayers) < 1:
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)
194 def setCarveImportRadius( self, importRadius ):
195 'Set the import radius.'
198 def setCarveIsCorrectMesh( self, isCorrectMesh ):
199 'Set the is correct mesh flag.'
202 def setCarveLayerHeight( self, layerHeight ):
203 'Set the layer height.'
204 self.layerHeight = layerHeight