2 Face of a triangle mesh.
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_utilities import evaluate
11 from fabmetheus_utilities.geometry.geometry_utilities import matrix
12 from fabmetheus_utilities.vector3 import Vector3
13 from fabmetheus_utilities.vector3index import Vector3Index
14 from fabmetheus_utilities import euclidean
15 from fabmetheus_utilities import gcodec
16 from fabmetheus_utilities import intercircle
17 from fabmetheus_utilities import xml_simple_reader
18 from fabmetheus_utilities import xml_simple_writer
23 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
24 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
25 __date__ = '$Date: 2008/02/05 $'
26 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
29 def addFaces(geometryOutput, faces):
31 if geometryOutput.__class__ == list:
32 for element in geometryOutput:
33 addFaces(element, faces)
35 if geometryOutput.__class__ != dict:
37 for geometryOutputKey in geometryOutput.keys():
38 geometryOutputValue = geometryOutput[geometryOutputKey]
39 if geometryOutputKey == 'face':
40 for face in geometryOutputValue:
43 addFaces(geometryOutputValue, faces)
45 def addGeometryList(elementNode, faces):
46 "Add vertex elements to an xml element."
48 faceElement = xml_simple_reader.ElementNode()
49 face.addToAttributes( faceElement.attributes )
50 faceElement.localName = 'face'
51 faceElement.parentNode = elementNode
52 elementNode.childNodes.append( faceElement )
54 def getCommonVertexIndex( edgeFirst, edgeSecond ):
55 "Get the vertex index that both edges have in common."
56 for edgeFirstVertexIndex in edgeFirst.vertexIndexes:
57 if edgeFirstVertexIndex == edgeSecond.vertexIndexes[0] or edgeFirstVertexIndex == edgeSecond.vertexIndexes[1]:
58 return edgeFirstVertexIndex
59 print("Inconsistent GNU Triangulated Surface")
64 def getFaces(geometryOutput):
67 addFaces(geometryOutput, faces)
70 def processElementNode(elementNode):
71 "Process the xml element."
73 face.index = len(elementNode.parentNode.xmlObject.faces)
74 for vertexIndexIndex in xrange(3):
75 face.vertexIndexes.append(evaluate.getEvaluatedInt(None, elementNode, 'vertex' + str(vertexIndexIndex)))
76 elementNode.parentNode.xmlObject.faces.append(face)
80 "An edge of a triangle mesh."
82 "Set the face indexes to None."
84 self.vertexIndexes = []
89 "Get the string representation of this Edge."
90 return str( self.index ) + ' ' + str( self.faceIndexes ) + ' ' + str(self.vertexIndexes)
92 def addFaceIndex( self, faceIndex ):
93 "Add first None face index to input face index."
94 self.faceIndexes.append( faceIndex )
96 def getFromVertexIndexes( self, edgeIndex, vertexIndexes ):
97 "Initialize from two vertex indices."
98 self.index = edgeIndex
99 self.vertexIndexes = vertexIndexes[:]
100 self.vertexIndexes.sort()
105 "A face of a triangle mesh."
108 self.edgeIndexes = []
110 self.vertexIndexes = []
113 "Get the string representation of this object info."
114 output = cStringIO.StringIO()
115 self.addXML( 2, output )
116 return output.getvalue()
118 def addToAttributes(self, attributes):
119 "Add to the attribute dictionary."
120 for vertexIndexIndex in xrange(len(self.vertexIndexes)):
121 vertexIndex = self.vertexIndexes[vertexIndexIndex]
122 attributes['vertex' + str(vertexIndexIndex)] = str(vertexIndex)
124 def addXML(self, depth, output):
125 "Add the xml for this object."
127 self.addToAttributes(attributes)
128 xml_simple_writer.addClosedXMLTag( attributes, depth, 'face', output )
131 'Get the copy of this face.'
133 faceCopy.edgeIndexes = self.edgeIndexes[:]
134 faceCopy.index = self.index
135 faceCopy.vertexIndexes = self.vertexIndexes[:]
138 def getFromEdgeIndexes( self, edgeIndexes, edges, faceIndex ):
139 "Initialize from edge indices."
140 if len(self.vertexIndexes) > 0:
142 self.index = faceIndex
143 self.edgeIndexes = edgeIndexes
144 for edgeIndex in edgeIndexes:
145 edges[ edgeIndex ].addFaceIndex( faceIndex )
146 for triangleIndex in xrange(3):
147 indexFirst = ( 3 - triangleIndex ) % 3
148 indexSecond = ( 4 - triangleIndex ) % 3
149 self.vertexIndexes.append( getCommonVertexIndex( edges[ edgeIndexes[ indexFirst ] ], edges[ edgeIndexes[ indexSecond ] ] ) )
152 def setEdgeIndexesToVertexIndexes( self, edges, edgeTable ):
153 "Set the edge indexes to the vertex indexes."
154 if len(self.edgeIndexes) > 0:
156 for triangleIndex in xrange(3):
157 indexFirst = ( 3 - triangleIndex ) % 3
158 indexSecond = ( 4 - triangleIndex ) % 3
159 vertexIndexFirst = self.vertexIndexes[ indexFirst ]
160 vertexIndexSecond = self.vertexIndexes[ indexSecond ]
161 vertexIndexPair = [ vertexIndexFirst, vertexIndexSecond ]
162 vertexIndexPair.sort()
163 edgeIndex = len( edges )
164 if str( vertexIndexPair ) in edgeTable:
165 edgeIndex = edgeTable[ str( vertexIndexPair ) ]
167 edgeTable[ str( vertexIndexPair ) ] = edgeIndex
168 edge = Edge().getFromVertexIndexes( edgeIndex, vertexIndexPair )
170 edges[ edgeIndex ].addFaceIndex( self.index )
171 self.edgeIndexes.append( edgeIndex )