chiark / gitweb /
Add back the ultimaker platform, and made the platform mesh simpler.
[cura.git] / Cura / slice / cura_sf / fabmetheus_utilities / geometry / geometry_tools / face.py
1 """
2 Face of a triangle mesh.
3
4 """
5
6 from __future__ import absolute_import
7
8 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
9 from fabmetheus_utilities import xml_simple_reader
10 from fabmetheus_utilities import xml_simple_writer
11 import cStringIO
12
13
14 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
15 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
16 __date__ = '$Date: 2008/02/05 $'
17 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
18
19
20 def addFaces(geometryOutput, faces):
21         'Add the faces.'
22         if geometryOutput.__class__ == list:
23                 for element in geometryOutput:
24                         addFaces(element, faces)
25                 return
26         if geometryOutput.__class__ != dict:
27                 return
28         for geometryOutputKey in geometryOutput.keys():
29                 geometryOutputValue = geometryOutput[geometryOutputKey]
30                 if geometryOutputKey == 'face':
31                         for face in geometryOutputValue:
32                                 faces.append(face)
33                 else:
34                         addFaces(geometryOutputValue, faces)
35
36 def addGeometryList(elementNode, faces):
37         "Add vertex elements to an xml element."
38         for face in faces:
39                 faceElement = xml_simple_reader.ElementNode()
40                 face.addToAttributes( faceElement.attributes )
41                 faceElement.localName = 'face'
42                 faceElement.parentNode = elementNode
43                 elementNode.childNodes.append( faceElement )
44
45 def getCommonVertexIndex( edgeFirst, edgeSecond ):
46         "Get the vertex index that both edges have in common."
47         for edgeFirstVertexIndex in edgeFirst.vertexIndexes:
48                 if edgeFirstVertexIndex == edgeSecond.vertexIndexes[0] or edgeFirstVertexIndex == edgeSecond.vertexIndexes[1]:
49                         return edgeFirstVertexIndex
50         print("Inconsistent GNU Triangulated Surface")
51         print(edgeFirst)
52         print(edgeSecond)
53         return 0
54
55 def getFaces(geometryOutput):
56         'Get the faces.'
57         faces = []
58         addFaces(geometryOutput, faces)
59         return faces
60
61 def processElementNode(elementNode):
62         "Process the xml element."
63         face = Face()
64         face.index = len(elementNode.parentNode.xmlObject.faces)
65         for vertexIndexIndex in xrange(3):
66                 face.vertexIndexes.append(evaluate.getEvaluatedInt(None, elementNode, 'vertex' + str(vertexIndexIndex)))
67         elementNode.parentNode.xmlObject.faces.append(face)
68
69
70 class Edge(object):
71         "An edge of a triangle mesh."
72         def __init__(self):
73                 "Set the face indexes to None."
74                 self.faceIndexes = []
75                 self.vertexIndexes = []
76                 self.zMaximum = None
77                 self.zMinimum = None
78         
79         def __repr__(self):
80                 "Get the string representation of this Edge."
81                 return str( self.index ) + ' ' + str( self.faceIndexes ) + ' ' + str(self.vertexIndexes)
82
83         def addFaceIndex( self, faceIndex ):
84                 "Add first None face index to input face index."
85                 self.faceIndexes.append( faceIndex )
86
87         def getFromVertexIndexes( self, edgeIndex, vertexIndexes ):
88                 "Initialize from two vertex indices."
89                 self.index = edgeIndex
90                 self.vertexIndexes = vertexIndexes[:]
91                 self.vertexIndexes.sort()
92                 return self
93
94
95 class Face(object):
96         "A face of a triangle mesh."
97         def __init__(self):
98                 "Initialize."
99                 self.edgeIndexes = []
100                 self.index = None
101                 self.vertexIndexes = []
102
103         def __repr__(self):
104                 "Get the string representation of this object info."
105                 output = cStringIO.StringIO()
106                 self.addXML( 2, output )
107                 return output.getvalue()
108
109         def addToAttributes(self, attributes):
110                 "Add to the attribute dictionary."
111                 for vertexIndexIndex in xrange(len(self.vertexIndexes)):
112                         vertexIndex = self.vertexIndexes[vertexIndexIndex]
113                         attributes['vertex' + str(vertexIndexIndex)] = str(vertexIndex)
114
115         def addXML(self, depth, output):
116                 "Add the xml for this object."
117                 attributes = {}
118                 self.addToAttributes(attributes)
119                 xml_simple_writer.addClosedXMLTag( attributes, depth, 'face', output )
120
121         def copy(self):
122                 'Get the copy of this face.'
123                 faceCopy = Face()
124                 faceCopy.edgeIndexes = self.edgeIndexes[:]
125                 faceCopy.index = self.index
126                 faceCopy.vertexIndexes = self.vertexIndexes[:]
127                 return faceCopy
128
129         def getFromEdgeIndexes( self, edgeIndexes, edges, faceIndex ):
130                 "Initialize from edge indices."
131                 if len(self.vertexIndexes) > 0:
132                         return
133                 self.index = faceIndex
134                 self.edgeIndexes = edgeIndexes
135                 for edgeIndex in edgeIndexes:
136                         edges[ edgeIndex ].addFaceIndex( faceIndex )
137                 for triangleIndex in xrange(3):
138                         indexFirst = ( 3 - triangleIndex ) % 3
139                         indexSecond = ( 4 - triangleIndex ) % 3
140                         self.vertexIndexes.append( getCommonVertexIndex( edges[ edgeIndexes[ indexFirst ] ], edges[ edgeIndexes[ indexSecond ] ] ) )
141                 return self
142
143         def setEdgeIndexesToVertexIndexes( self, edges, edgeTable ):
144                 "Set the edge indexes to the vertex indexes."
145                 if len(self.edgeIndexes) > 0:
146                         return
147                 for triangleIndex in xrange(3):
148                         indexFirst = ( 3 - triangleIndex ) % 3
149                         indexSecond = ( 4 - triangleIndex ) % 3
150                         vertexIndexFirst = self.vertexIndexes[ indexFirst ]
151                         vertexIndexSecond = self.vertexIndexes[ indexSecond ]
152                         vertexIndexPair = [ vertexIndexFirst, vertexIndexSecond ]
153                         vertexIndexPair.sort()
154                         edgeIndex = len( edges )
155                         if str( vertexIndexPair ) in edgeTable:
156                                 edgeIndex = edgeTable[ str( vertexIndexPair ) ]
157                         else:
158                                 edgeTable[ str( vertexIndexPair ) ] = edgeIndex
159                                 edge = Edge().getFromVertexIndexes( edgeIndex, vertexIndexPair )
160                                 edges.append( edge )
161                         edges[ edgeIndex ].addFaceIndex( self.index )
162                         self.edgeIndexes.append( edgeIndex )