added code to subdivide faces, not quite finished but looks promising

This commit is contained in:
William Blattman 2012-03-18 17:03:07 -07:00
parent 66593129e6
commit c6434469fb
1 changed files with 120 additions and 43 deletions

View File

@ -104,6 +104,8 @@ class Edge(object):
self.vertices = []
self.faces = []
self.edges = []
self.__edgeVertex = None
self.__subEdges = []
def neighborFace(self, neighborFace):
if neighborFace == self.faces[0]:
@ -111,27 +113,37 @@ class Edge(object):
else:
return self.faces[0]
def edgeVertex(self):
def __getSubEdges(self):
if not self.__subEdges:
self.__subEdges = [Edge(), Edge()]
self.__subEdges[0].vertices = [self.vertices[0], self.edgeVertex]
self.__subEdges[1].vertices = [self.edgeVertex, self.vertices[1]]
return self.__subEdges
subEdges = property(fget=__getSubEdges)
def __getEdgeVertex(self):
'''
Set each edge vertices to be the average of the two neighboring
face vertices and its two original end vertices.
'''
# two neighboring face vertices:
neighborVertices = [face.centroid for face in self.faces]
vertices = list(self.vertices)
vertices.extend(neighborVertices)
return self.__averageVertices(vertices)
if not self.__edgeVertex:
# two neighboring face vertices:
neighboringFaceVertices = [face.centroid for face in self.faces]
neighboringFaceVertices.extend(self.vertices)
xs = [vertex.x for vertex in neighboringFaceVertices]
ys = [vertex.y for vertex in neighboringFaceVertices]
zs = [vertex.z for vertex in neighboringFaceVertices]
x = sum(xs)/len(xs)
y = sum(ys)/len(ys)
z = sum(zs)/len(zs)
self.__edgeVertex = Vertex(x, y, z)
self.__edgeVertex.edges.extend(self.__subEdges)
return self.__edgeVertex
edgeVertex = property(fget=__getEdgeVertex)
def __averageVertices(self, vertices):
xs = [vertex.x for vertex in vertices]
ys = [vertex.y for vertex in vertices]
zs = [vertex.z for vertex in vertices]
x = sum(xs)/len(xs)
y = sum(ys)/len(ys)
z = sum(zs)/len(zs)
return Vertex(x, y, z)
return
class Face(object):
'''
@ -139,25 +151,94 @@ class Face(object):
'''
def __init__(self):
self.edges = []
self.__centroid = None
self.__interiorEdges = []
self.__subFaces = []
def __getCentroid(self):
# gather all vertex coords
faceVertices = self.__getFaceVertices()
xs = [vertex.x for vertex in faceVertices]
ys = [vertex.y for vertex in faceVertices]
zs = [vertex.z for vertex in faceVertices]
# average each vertex component
x = sum(xs) / len(xs)
y = sum(ys) / len(ys)
z = sum(zs) / len(zs)
return Vertex(x, y, z)
if not self.__centroid:
# gather all face vertex coords
faceVertices = list(set([vertex for edge in self.edges for vertex in edge.vertices]))
xs = [vertex.x for vertex in faceVertices]
ys = [vertex.y for vertex in faceVertices]
zs = [vertex.z for vertex in faceVertices]
# average each vertex component
x = sum(xs) / len(xs)
y = sum(ys) / len(ys)
z = sum(zs) / len(zs)
self.__centroid = Vertex(x, y, z)
return self.__centroid
centroid = property(fget=__getCentroid)
def __getFaceVertices(self):
return list([vertex for edge in self.edges for vertex in edge.vertices])
vertices = property(fget=__getFaceVertices)
def __getSubFaces(self):
self.__setupSubDivisions()
return self.__subFaces
subFaces = property(fget=__getSubFaces)
def __getInteriorEdges(self):
self.__setupSubDivisions()
return self.__interiorEdges
interiorEdges = property(fget=__getInteriorEdges )
def __setupSubDivisions(self):
'''
v0 ev0 v1
*------e0-----*
| | |
| | |
ev3 e|11----f5----e|1 ev1
| | |
| | |
*------e2-----*
v3 ev2 v2
'''
if not self.__subFaces:
# create empty subFaces that will be filled with edge references below
# these need to at least exist so the interior edges have something to reference
self.__subFaces = [Face() for edge in self.edges]
if not self.__interiorEdges:
# set up empty edge objects to be filled below
self.__interiorEdges = [Edge() for edge in self.edges]
# each interior edge connects the exterior edge vertex (mid-point) to the faceVertex (centroid)
for index in range(len(self.edges)):
prevIndex = (index - 1) % len(self.edges)
nextIndex = (index + 1) % len(self.edges)
# end vertices are face centroid and currEdge edgeVertex
self.__interiorEdges[index].vertices = [self.edges[index].edgeVertex,
self.centroid]
# wing edges are the current edge's subEdges (ordered same as vertex order) and the prev and next interior edges
self.__interiorEdges[index].edges = [self.edges[index].subEdges[0],
self.edges[index].subEdges[1],
self.__interiorEdges[prevIndex],
self.__interiorEdges[nextIndex]]
# edge faces are the new subFaces (current and next faces), the current will be define below
# and the next will be defined on the next iteration (or already defined on the last iteration)
self.__interiorEdges[index].faces = [self.__subFaces[index],
self.__subFaces[nextIndex]]
# now reference the current edge back into the faces,
# and the edge.subEdges, and the edge.edgeVertex
# current subFace (same index as current interior edge)
# set its edges to reference the same edges used to setup the interior edge
# order will be pretty important on these steps...
self.__subFaces[index].edges = [self.edges[index].subEdges[0],
self.__interiorEdges[index],
self.__interiorEdges[prevIndex],
self.edges[prevIndex].subEdges[1]]
# just set one of the vertex edges, the other belongs to another face and will get added when that face is run
self.edges[index].edgeVertex.edges.append(self.__interiorEdges[index])
self.edges[index].subEdges[0].faces.append(self.__subFaces[index])
self.edges[index].subEdges[0].faces.append(self.__subFaces[index])
class Polygon(object):
'''
@ -170,10 +251,8 @@ class Polygon(object):
self.edges = edges
self.faces = faces
def __getFaceNeighbors(self, testFace):
for face in self.faces:
testFace.isNeighbor(face)
def __repr__(self):
return str([edge for edge in self.edges])
def catmullClarkRefine(self):
'''
For each face, add a face vertex
@ -184,17 +263,16 @@ class Polygon(object):
For each original vertex P, take the average F of all n face vertices for faces touching P, and take the average R of all n edge midvertices for edges touching P, where each edge midvertex is the average of its two endvertex vertices. Move each original vertex to the vertex
'''
# this calculates and returns the averaged vertex point
print self.faces[0].edges[0].edgeVertex()
# each face knows how to subdivide and create a set of subfaces, including interior edges and setup their references correctly... <- not completely finished...
# this returns a vertex at the face centroid
print self.faces[0].centroid
for face in self.faces:
for subFace in face.subFaces:
for edge in subFace.edges:
for vertex in edge.vertices:
print vertex
# this will get to the first neighborFace...
# each face knows its faceVertex, and all of its edgeVertices
neighborFace = self.faces[0].edges[0].neighborFace(self.faces[0])
# plotting these in excel seems to show the correct values (at first glace...)
print neighborFace.centroid
# so now what.........
@ -290,7 +368,6 @@ polygon = Polygon(v, e, f)
polygon.catmullClarkRefine()
# from numpy import *
# import pylab
# import mpl_toolkits.mplot3d.axes3d as p3