MrDraw/SkeinPyPy_NewUI/fabmetheus_utilities/geometry/geometry_tools/face.py
Daid a414a80837 Adding SkeinPyPy_NewUI as development for a brand new user interface.
Experimental, doesn't slice yet, loads of work ahead.
2012-02-20 00:30:49 +01:00

171 lines
5.5 KiB
Python

"""
Face of a triangle mesh.
"""
from __future__ import absolute_import
#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.
import __init__
from fabmetheus_utilities.geometry.geometry_utilities import evaluate
from fabmetheus_utilities.geometry.geometry_utilities import matrix
from fabmetheus_utilities.vector3 import Vector3
from fabmetheus_utilities.vector3index import Vector3Index
from fabmetheus_utilities import euclidean
from fabmetheus_utilities import gcodec
from fabmetheus_utilities import intercircle
from fabmetheus_utilities import xml_simple_reader
from fabmetheus_utilities import xml_simple_writer
import cStringIO
import math
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
def addFaces(geometryOutput, faces):
'Add the faces.'
if geometryOutput.__class__ == list:
for element in geometryOutput:
addFaces(element, faces)
return
if geometryOutput.__class__ != dict:
return
for geometryOutputKey in geometryOutput.keys():
geometryOutputValue = geometryOutput[geometryOutputKey]
if geometryOutputKey == 'face':
for face in geometryOutputValue:
faces.append(face)
else:
addFaces(geometryOutputValue, faces)
def addGeometryList(elementNode, faces):
"Add vertex elements to an xml element."
for face in faces:
faceElement = xml_simple_reader.ElementNode()
face.addToAttributes( faceElement.attributes )
faceElement.localName = 'face'
faceElement.parentNode = elementNode
elementNode.childNodes.append( faceElement )
def getCommonVertexIndex( edgeFirst, edgeSecond ):
"Get the vertex index that both edges have in common."
for edgeFirstVertexIndex in edgeFirst.vertexIndexes:
if edgeFirstVertexIndex == edgeSecond.vertexIndexes[0] or edgeFirstVertexIndex == edgeSecond.vertexIndexes[1]:
return edgeFirstVertexIndex
print("Inconsistent GNU Triangulated Surface")
print(edgeFirst)
print(edgeSecond)
return 0
def getFaces(geometryOutput):
'Get the faces.'
faces = []
addFaces(geometryOutput, faces)
return faces
def processElementNode(elementNode):
"Process the xml element."
face = Face()
face.index = len(elementNode.parentNode.xmlObject.faces)
for vertexIndexIndex in xrange(3):
face.vertexIndexes.append(evaluate.getEvaluatedInt(None, elementNode, 'vertex' + str(vertexIndexIndex)))
elementNode.parentNode.xmlObject.faces.append(face)
class Edge:
"An edge of a triangle mesh."
def __init__(self):
"Set the face indexes to None."
self.faceIndexes = []
self.vertexIndexes = []
self.zMaximum = None
self.zMinimum = None
def __repr__(self):
"Get the string representation of this Edge."
return str( self.index ) + ' ' + str( self.faceIndexes ) + ' ' + str(self.vertexIndexes)
def addFaceIndex( self, faceIndex ):
"Add first None face index to input face index."
self.faceIndexes.append( faceIndex )
def getFromVertexIndexes( self, edgeIndex, vertexIndexes ):
"Initialize from two vertex indices."
self.index = edgeIndex
self.vertexIndexes = vertexIndexes[:]
self.vertexIndexes.sort()
return self
class Face:
"A face of a triangle mesh."
def __init__(self):
"Initialize."
self.edgeIndexes = []
self.index = None
self.vertexIndexes = []
def __repr__(self):
"Get the string representation of this object info."
output = cStringIO.StringIO()
self.addXML( 2, output )
return output.getvalue()
def addToAttributes(self, attributes):
"Add to the attribute dictionary."
for vertexIndexIndex in xrange(len(self.vertexIndexes)):
vertexIndex = self.vertexIndexes[vertexIndexIndex]
attributes['vertex' + str(vertexIndexIndex)] = str(vertexIndex)
def addXML(self, depth, output):
"Add the xml for this object."
attributes = {}
self.addToAttributes(attributes)
xml_simple_writer.addClosedXMLTag( attributes, depth, 'face', output )
def copy(self):
'Get the copy of this face.'
faceCopy = Face()
faceCopy.edgeIndexes = self.edgeIndexes[:]
faceCopy.index = self.index
faceCopy.vertexIndexes = self.vertexIndexes[:]
return faceCopy
def getFromEdgeIndexes( self, edgeIndexes, edges, faceIndex ):
"Initialize from edge indices."
if len(self.vertexIndexes) > 0:
return
self.index = faceIndex
self.edgeIndexes = edgeIndexes
for edgeIndex in edgeIndexes:
edges[ edgeIndex ].addFaceIndex( faceIndex )
for triangleIndex in xrange(3):
indexFirst = ( 3 - triangleIndex ) % 3
indexSecond = ( 4 - triangleIndex ) % 3
self.vertexIndexes.append( getCommonVertexIndex( edges[ edgeIndexes[ indexFirst ] ], edges[ edgeIndexes[ indexSecond ] ] ) )
return self
def setEdgeIndexesToVertexIndexes( self, edges, edgeTable ):
"Set the edge indexes to the vertex indexes."
if len(self.edgeIndexes) > 0:
return
for triangleIndex in xrange(3):
indexFirst = ( 3 - triangleIndex ) % 3
indexSecond = ( 4 - triangleIndex ) % 3
vertexIndexFirst = self.vertexIndexes[ indexFirst ]
vertexIndexSecond = self.vertexIndexes[ indexSecond ]
vertexIndexPair = [ vertexIndexFirst, vertexIndexSecond ]
vertexIndexPair.sort()
edgeIndex = len( edges )
if str( vertexIndexPair ) in edgeTable:
edgeIndex = edgeTable[ str( vertexIndexPair ) ]
else:
edgeTable[ str( vertexIndexPair ) ] = edgeIndex
edge = Edge().getFromVertexIndexes( edgeIndex, vertexIndexPair )
edges.append( edge )
edges[ edgeIndex ].addFaceIndex( self.index )
self.edgeIndexes.append( edgeIndex )