added code to subdivide faces, not quite finished but looks promising
This commit is contained in:
parent
66593129e6
commit
c6434469fb
163
geometry.py
163
geometry.py
@ -104,6 +104,8 @@ class Edge(object):
|
|||||||
self.vertices = []
|
self.vertices = []
|
||||||
self.faces = []
|
self.faces = []
|
||||||
self.edges = []
|
self.edges = []
|
||||||
|
self.__edgeVertex = None
|
||||||
|
self.__subEdges = []
|
||||||
|
|
||||||
def neighborFace(self, neighborFace):
|
def neighborFace(self, neighborFace):
|
||||||
if neighborFace == self.faces[0]:
|
if neighborFace == self.faces[0]:
|
||||||
@ -111,27 +113,37 @@ class Edge(object):
|
|||||||
else:
|
else:
|
||||||
return self.faces[0]
|
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
|
Set each edge vertices to be the average of the two neighboring
|
||||||
face vertices and its two original end vertices.
|
face vertices and its two original end vertices.
|
||||||
'''
|
'''
|
||||||
|
if not self.__edgeVertex:
|
||||||
# two neighboring face vertices:
|
# two neighboring face vertices:
|
||||||
neighborVertices = [face.centroid for face in self.faces]
|
neighboringFaceVertices = [face.centroid for face in self.faces]
|
||||||
|
neighboringFaceVertices.extend(self.vertices)
|
||||||
vertices = list(self.vertices)
|
xs = [vertex.x for vertex in neighboringFaceVertices]
|
||||||
vertices.extend(neighborVertices)
|
ys = [vertex.y for vertex in neighboringFaceVertices]
|
||||||
return self.__averageVertices(vertices)
|
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):
|
def __averageVertices(self, vertices):
|
||||||
xs = [vertex.x for vertex in vertices]
|
|
||||||
ys = [vertex.y for vertex in vertices]
|
return
|
||||||
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)
|
|
||||||
|
|
||||||
class Face(object):
|
class Face(object):
|
||||||
'''
|
'''
|
||||||
@ -139,25 +151,94 @@ class Face(object):
|
|||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.edges = []
|
self.edges = []
|
||||||
|
self.__centroid = None
|
||||||
|
self.__interiorEdges = []
|
||||||
|
self.__subFaces = []
|
||||||
|
|
||||||
def __getCentroid(self):
|
def __getCentroid(self):
|
||||||
# gather all vertex coords
|
if not self.__centroid:
|
||||||
faceVertices = self.__getFaceVertices()
|
# gather all face vertex coords
|
||||||
xs = [vertex.x for vertex in faceVertices]
|
faceVertices = list(set([vertex for edge in self.edges for vertex in edge.vertices]))
|
||||||
ys = [vertex.y for vertex in faceVertices]
|
xs = [vertex.x for vertex in faceVertices]
|
||||||
zs = [vertex.z 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)
|
# average each vertex component
|
||||||
y = sum(ys) / len(ys)
|
x = sum(xs) / len(xs)
|
||||||
z = sum(zs) / len(zs)
|
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)
|
centroid = property(fget=__getCentroid)
|
||||||
|
|
||||||
def __getFaceVertices(self):
|
def __getSubFaces(self):
|
||||||
return list([vertex for edge in self.edges for vertex in edge.vertices])
|
self.__setupSubDivisions()
|
||||||
vertices = property(fget=__getFaceVertices)
|
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):
|
class Polygon(object):
|
||||||
'''
|
'''
|
||||||
@ -170,10 +251,8 @@ class Polygon(object):
|
|||||||
self.edges = edges
|
self.edges = edges
|
||||||
self.faces = faces
|
self.faces = faces
|
||||||
|
|
||||||
def __getFaceNeighbors(self, testFace):
|
def __repr__(self):
|
||||||
for face in self.faces:
|
return str([edge for edge in self.edges])
|
||||||
testFace.isNeighbor(face)
|
|
||||||
|
|
||||||
def catmullClarkRefine(self):
|
def catmullClarkRefine(self):
|
||||||
'''
|
'''
|
||||||
For each face, add a face vertex
|
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
|
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
|
# each face knows how to subdivide and create a set of subfaces, including interior edges and setup their references correctly... <- not completely finished...
|
||||||
print self.faces[0].edges[0].edgeVertex()
|
|
||||||
|
|
||||||
# this returns a vertex at the face centroid
|
for face in self.faces:
|
||||||
print self.faces[0].centroid
|
for subFace in face.subFaces:
|
||||||
|
for edge in subFace.edges:
|
||||||
|
for vertex in edge.vertices:
|
||||||
|
print vertex
|
||||||
|
|
||||||
# this will get to the first neighborFace...
|
# plotting these in excel seems to show the correct values (at first glace...)
|
||||||
# each face knows its faceVertex, and all of its edgeVertices
|
|
||||||
neighborFace = self.faces[0].edges[0].neighborFace(self.faces[0])
|
|
||||||
|
|
||||||
print neighborFace.centroid
|
|
||||||
|
|
||||||
# so now what.........
|
# so now what.........
|
||||||
|
|
||||||
@ -290,7 +368,6 @@ polygon = Polygon(v, e, f)
|
|||||||
polygon.catmullClarkRefine()
|
polygon.catmullClarkRefine()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# from numpy import *
|
# from numpy import *
|
||||||
# import pylab
|
# import pylab
|
||||||
# import mpl_toolkits.mplot3d.axes3d as p3
|
# import mpl_toolkits.mplot3d.axes3d as p3
|
||||||
|
Loading…
Reference in New Issue
Block a user