Refactored into modules and test scripts.

This commit is contained in:
Stephen M. McQuay 2012-03-19 20:38:40 -06:00
parent 6a69a99706
commit 2f4d648f55
7 changed files with 475 additions and 464 deletions

0
surf/__init__.py Normal file
View File

View File

@ -1,4 +1,6 @@
# import scipy from __future__ import division
import pprint
import json
''' '''
http://en.wikipedia.org/wiki/Polygon_mesh http://en.wikipedia.org/wiki/Polygon_mesh
@ -131,7 +133,7 @@ class Edge(object):
else: else:
return self.faces[0] return self.faces[0]
def __getMidPoint(self): def __getMidPoint(self):
return sum(self.vertices, Vertex())/len(self.vertices) return sum(self.vertices) / len(self.vertices)
midPoint = property(fget=__getMidPoint) midPoint = property(fget=__getMidPoint)
def __getSubEdges(self): def __getSubEdges(self):
@ -267,198 +269,18 @@ class Polygon(object):
it needs to average vertices with all adjoinging faces it needs to average vertices with all adjoinging faces
''' '''
def __init__(self): def __init__(self, v=None, e=None, f=None):
self.vertices = [] self.vertices = v or []
self.edges = [] self.edges = e or []
self.faces = [] self.faces = f or []
def catmullClarkRefine(self): def __unicode__(self):
''' d = {
For each face, add a face vertex 'vertices': self.vertices,
Set each face vertex to be the centroid of all original vertices for the respective face. 'edges': self.edges,
For each edge, add an edge vertex. 'faces': self.faces,
Set each edge vertex to be the average of the two neighbouring face vertices and its two original endvertices. }
For each face vertex, add an edge for every edge of the face, connecting the face vertex to each edge vertex for the face. return pprint.pformat(d)
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
'''
__str__ = __unicode__
__repr__ = __unicode__
# each face knows how to subdivide and create a set of subfaces, including interior edges and setup their references correctly... <- not completely finished...
p = Polygon()
edges = []
vertices = []
faces = []
for face in self.faces:
for subFace in face.subFaces:
faces.append(subFace)
for edge in subFace.edges:
edges.append(edge)
for vertex in edge.vertices:
vertices.append(vertex)
newVertices = []
for vertex in self.vertices:
faceVertices = []
edgeMidPoints = []
for edge in vertex.edges:
print edge.midPoint
edgeMidPoints.append(edge.midPoint)
for face in edge.faces:
print face.centroid
faceVertices.append(face.centroid)
print edgeMidPoints
print vertex
print faceVertices
f = sum(list(set(faceVertices)), Vertex())/len(list(set(faceVertices)))
# print f
r = sum(list(set(edgeMidPoints)), Vertex())/len(list(set(edgeMidPoints)))
# print r
p = vertex
# print p
n = len(vertex.edges)
# print n
v = (f + 2.0 * r + (n - 3.0) * p) / n
# print v
# print v
newVertices.append(v)
for vertex, newVertex in zip(self.vertices, newVertices):
vertex.x = newVertex.x
vertex.y = newVertex.y
vertex.z = newVertex.z
# so now what.........
# (F + 2R + (n-3) P) / n
#
# F = average of all face vertices touching P
# R = average of all edge vertices touching P
# P original point
# n = number of edges connecting to P
p.faces = faces
p.vertices = vertices
p.edges = edges
# plotting these in excel seems to show the correct values (at first glace...)
# so now what.........
# (F + 2R + (n-3) P) / n
#
# F = average of all face vertices touching P
# R = average of all edge vertices touching P
# P original point
# n = face vertices or edge vertices (should be the same number)
return p
def createPolygon():
v = []
v.append(Vertex(0.0, 1.0, 0.0))
v.append(Vertex(1.0, 1.0, 0.0))
v.append(Vertex(1.0, 0.0, 0.0))
v.append(Vertex(0.0, 0.0, 0.0))
v.append(Vertex(0.0, 1.0, 1.0))
v.append(Vertex(1.0, 1.0, 1.0))
v.append(Vertex(1.0, 0.0, 1.0))
v.append(Vertex(0.0, 0.0, 1.0))
e = []
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
f = []
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
# vertex list
v[0].edges = [e[0], e[3], e[4]]
v[1].edges = [e[0], e[5], e[1]]
v[2].edges = [e[1], e[6], e[2]]
v[3].edges = [e[2], e[7], e[3]]
v[4].edges = [e[4], e[11], e[8]]
v[5].edges = [e[5], e[9], e[8]]
v[6].edges = [e[6], e[9], e[10]]
v[7].edges = [e[7], e[10], e[11]]
# face list
f[0].edges = [e[0], e[1], e[2], e[3]]
f[1].edges = [e[1], e[5], e[9], e[6]]
f[2].edges = [e[2], e[6], e[10], e[7]]
f[3].edges = [e[4], e[3], e[7], e[11]]
f[4].edges = [e[8], e[5], e[0], e[4]]
f[5].edges = [e[10], e[9], e[8], e[11]]
#winged edges ordered by face, then by vertex reference
e[0].vertices, e[0].faces, e[0].edges = [v[0], v[1]], [f[0], f[4]], [e[3], e[1], e[4], e[5]]
e[1].vertices, e[1].faces, e[1].edges = [v[1], v[2]], [f[0], f[1]], [e[0], e[2], e[5], e[6]]
e[2].vertices, e[2].faces, e[2].edges = [v[2], v[3]], [f[0], f[2]], [e[1], e[3], e[6], e[7]]
e[3].vertices, e[3].faces, e[3].edges = [v[3], v[0]], [f[3], f[0]], [e[4], e[7], e[0], e[2]]
e[4].vertices, e[4].faces, e[4].edges = [v[0], v[4]], [f[3], f[4]], [e[11], e[3], e[0], e[8]]
e[5].vertices, e[5].faces, e[5].edges = [v[5], v[1]], [f[4], f[1]], [e[8], e[0], e[9], e[1]]
e[6].vertices, e[6].faces, e[6].edges = [v[2], v[6]], [f[1], f[2]], [e[1], e[9], e[2], e[10]]
e[7].vertices, e[7].faces, e[7].edges = [v[7], v[3]], [f[3], f[2]], [e[11], e[3], e[10], e[2]]
e[8].vertices, e[8].faces, e[8].edges = [v[4], v[5]], [f[4], f[5]], [e[4], e[5], e[11], e[9]]
e[9].vertices, e[9].faces, e[9].edges = [v[5], v[6]], [f[1], f[5]], [e[5], e[6], e[8], e[10]]
e[10].vertices, e[10].faces, e[10].edges = [v[7], v[6]], [f[2], f[5]], [e[7], e[6], e[11], e[9]]
e[11].vertices, e[11].faces, e[11].edges = [v[4], v[7]], [f[3], f[5]], [e[4], e[7], e[8], e[10]]
# just to prove to myself that the objects are the same, this is what years of pass by value have done to me...
# print id(v[0].x)
# print id(e[0].vertices[0].x)
# print id(f[0].edges[0].vertices[0].x)
# v[0].x = 9
# print id(v[0].x)
# print id(e[0].vertices[0].x)
# print id(f[0].edges[0].vertices[0].x)
# print v[0].x
# print e[0].vertices[0].x
# print f[0].edges[0].vertices[0].x
p = Polygon()
p.vertices = v
p.edges = e
p.faces = f
return p
polygon = createPolygon()
newPolygon = polygon.catmullClarkRefine()
from numpy import *
import pylab
import mpl_toolkits.mplot3d.axes3d as p3
fig = pylab.figure()
ax = p3.Axes3D(fig)
for edge in newPolygon.edges:
xs = [vertex.x for vertex in edge.vertices]
ys = [vertex.y for vertex in edge.vertices]
zs = [vertex.z for vertex in edge.vertices]
ax.plot_wireframe(xs, ys, zs)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
pylab.show()

0
surf/subd/__init__.py Normal file
View File

70
surf/subd/cc.py Normal file
View File

@ -0,0 +1,70 @@
from surf.geometry import *
def refine(poly):
'''
For each face, add a face vertex
Set each face vertex to be the centroid of all original vertices for the respective face.
For each edge, add an edge vertex.
Set each edge vertex to be the average of the two neighbouring face vertices and its two original endvertices.
For each face vertex, add an edge for every edge of the face, connecting the face vertex to each edge vertex for the face.
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
'''
# each face knows how to subdivide and create a set of subfaces, including interior edges and setup their references correctly... <- not completely finished...
p = Polygon()
edges = []
vertices = []
faces = []
for face in poly.faces:
for subFace in face.subFaces:
faces.append(subFace)
for edge in subFace.edges:
edges.append(edge)
for vertex in edge.vertices:
vertices.append(vertex)
newVertices = []
for vertex in poly.vertices:
faceVertices = []
edgeMidPoints = []
for edge in vertex.edges:
edgeMidPoints.append(edge.midPoint)
for face in edge.faces:
faceVertices.append(face.centroid)
f = sum(list(set(faceVertices)), Vertex())/len(list(set(faceVertices)))
r = sum(list(set(edgeMidPoints)), Vertex())/len(list(set(edgeMidPoints)))
p = vertex
n = len(vertex.edges)
v = (f + 2.0 * r + (n - 3.0) * p) / n
newVertices.append(v)
for vertex, newVertex in zip(poly.vertices, newVertices):
vertex.x = newVertex.x
vertex.y = newVertex.y
vertex.z = newVertex.z
# so now what.........
# (F + 2R + (n-3) P) / n
#
# F = average of all face vertices touching P
# R = average of all edge vertices touching P
# P original point
# n = number of edges connecting to P
p.faces = faces
p.vertices = vertices
p.edges = edges
# plotting these in excel seems to show the correct values (at first glace...)
# so now what.........
# (F + 2R + (n-3) P) / n
#
# F = average of all face vertices touching P
# R = average of all edge vertices touching P
# P original point
# n = face vertices or edge vertices (should be the same number)
return Polygon(vertices, edges, faces)

84
surf/util.py Normal file
View File

@ -0,0 +1,84 @@
from surf.geometry import Vertex, Edge, Face, Polygon
def cube():
v = []
v.append(Vertex(0.0, 1.0, 0.0))
v.append(Vertex(1.0, 1.0, 0.0))
v.append(Vertex(1.0, 0.0, 0.0))
v.append(Vertex(0.0, 0.0, 0.0))
v.append(Vertex(0.0, 1.0, 1.0))
v.append(Vertex(1.0, 1.0, 1.0))
v.append(Vertex(1.0, 0.0, 1.0))
v.append(Vertex(0.0, 0.0, 1.0))
e = []
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
e.append(Edge())
f = []
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
f.append(Face())
# vertex list
v[0].edges = [e[0], e[3], e[4]]
v[1].edges = [e[0], e[5], e[1]]
v[2].edges = [e[1], e[6], e[2]]
v[3].edges = [e[2], e[7], e[3]]
v[4].edges = [e[4], e[11], e[8]]
v[5].edges = [e[5], e[9], e[8]]
v[6].edges = [e[6], e[9], e[10]]
v[7].edges = [e[7], e[10], e[11]]
# face list
f[0].edges = [e[0], e[1], e[2], e[3]]
f[1].edges = [e[1], e[5], e[9], e[6]]
f[2].edges = [e[2], e[6], e[10], e[7]]
f[3].edges = [e[4], e[3], e[7], e[11]]
f[4].edges = [e[8], e[5], e[0], e[4]]
f[5].edges = [e[10], e[9], e[8], e[11]]
#winged edges ordered by face, then by vertex reference
e[0].vertices, e[0].faces, e[0].edges = [v[0], v[1]], [f[0], f[4]], [e[3], e[1], e[4], e[5]]
e[1].vertices, e[1].faces, e[1].edges = [v[1], v[2]], [f[0], f[1]], [e[0], e[2], e[5], e[6]]
e[2].vertices, e[2].faces, e[2].edges = [v[2], v[3]], [f[0], f[2]], [e[1], e[3], e[6], e[7]]
e[3].vertices, e[3].faces, e[3].edges = [v[3], v[0]], [f[3], f[0]], [e[4], e[7], e[0], e[2]]
e[4].vertices, e[4].faces, e[4].edges = [v[0], v[4]], [f[3], f[4]], [e[11], e[3], e[0], e[8]]
e[5].vertices, e[5].faces, e[5].edges = [v[5], v[1]], [f[4], f[1]], [e[8], e[0], e[9], e[1]]
e[6].vertices, e[6].faces, e[6].edges = [v[2], v[6]], [f[1], f[2]], [e[1], e[9], e[2], e[10]]
e[7].vertices, e[7].faces, e[7].edges = [v[7], v[3]], [f[3], f[2]], [e[11], e[3], e[10], e[2]]
e[8].vertices, e[8].faces, e[8].edges = [v[4], v[5]], [f[4], f[5]], [e[4], e[5], e[11], e[9]]
e[9].vertices, e[9].faces, e[9].edges = [v[5], v[6]], [f[1], f[5]], [e[5], e[6], e[8], e[10]]
e[10].vertices, e[10].faces, e[10].edges = [v[7], v[6]], [f[2], f[5]], [e[7], e[6], e[11], e[9]]
e[11].vertices, e[11].faces, e[11].edges = [v[4], v[7]], [f[3], f[5]], [e[4], e[7], e[8], e[10]]
# just to prove to myself that the objects are the same, this is what years of pass by value have done to me...
# print id(v[0].x)
# print id(e[0].vertices[0].x)
# print id(f[0].edges[0].vertices[0].x)
# v[0].x = 9
# print id(v[0].x)
# print id(e[0].vertices[0].x)
# print id(f[0].edges[0].vertices[0].x)
# print v[0].x
# print e[0].vertices[0].x
# print f[0].edges[0].vertices[0].x
return Polygon(v, e, f)

24
test/test00.py Normal file
View File

@ -0,0 +1,24 @@
from surf.util import cube
from surf.subd import cc
polygon = cube()
refined_poly = cc.refine(polygon)
print polygon
print refined_poly
#
#
# import pylab
# import mpl_toolkits.mplot3d.axes3d as p3
#
# fig = pylab.figure()
# ax = p3.Axes3D(fig)
# for edge in newPolygon.edges:
# xs = [vertex.x for vertex in edge.vertices]
# ys = [vertex.y for vertex in edge.vertices]
# zs = [vertex.z for vertex in edge.vertices]
# ax.plot_wireframe(xs, ys, zs)
# ax.set_xlabel('X')
# ax.set_ylabel('Y')
# ax.set_zlabel('Z')
# pylab.show()

11
test/test01.py Normal file
View File

@ -0,0 +1,11 @@
from __future__ import division
from surf.geometry import Vertex
v1 = Vertex(0.5, 0.25, 1/3.0)
v2 = Vertex(1, 1, 1)
print v1, v2, (v1 + v2) / 2
print v1, v2, (v1 + v2) / 2.0
v = sum((v1, v2), Vertex()) / len((v1, v2))
print v, type(v)