added code to subdivide faces, not quite finished but looks promising
This commit is contained in:
parent
66593129e6
commit
c6434469fb
141
geometry.py
141
geometry.py
@ -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.
|
||||
'''
|
||||
|
||||
if not self.__edgeVertex:
|
||||
# two neighboring face vertices:
|
||||
neighborVertices = [face.centroid for face in self.faces]
|
||||
|
||||
vertices = list(self.vertices)
|
||||
vertices.extend(neighborVertices)
|
||||
return self.__averageVertices(vertices)
|
||||
|
||||
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]
|
||||
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)
|
||||
return Vertex(x, y, z)
|
||||
self.__edgeVertex = Vertex(x, y, z)
|
||||
self.__edgeVertex.edges.extend(self.__subEdges)
|
||||
return self.__edgeVertex
|
||||
edgeVertex = property(fget=__getEdgeVertex)
|
||||
|
||||
def __averageVertices(self, vertices):
|
||||
|
||||
return
|
||||
|
||||
class Face(object):
|
||||
'''
|
||||
@ -139,10 +151,14 @@ 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()
|
||||
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]
|
||||
@ -152,12 +168,77 @@ class Face(object):
|
||||
y = sum(ys) / len(ys)
|
||||
z = sum(zs) / len(zs)
|
||||
|
||||
return Vertex(x, y, z)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user