Refactored into modules and test scripts.
This commit is contained in:
parent
6a69a99706
commit
2f4d648f55
0
surf/__init__.py
Normal file
0
surf/__init__.py
Normal 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
0
surf/subd/__init__.py
Normal file
70
surf/subd/cc.py
Normal file
70
surf/subd/cc.py
Normal 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
84
surf/util.py
Normal 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
24
test/test00.py
Normal 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
11
test/test01.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user