From 198a7d7ca89694082b204b94ce24c835c7524d37 Mon Sep 17 00:00:00 2001 From: "Stephen M. McQuay" Date: Wed, 9 May 2012 09:24:26 -0600 Subject: [PATCH] Fixed bug in my CC implementation - Wasn't calculating faces for a give original vert correctly - vertices generated by surf.subd.cc.refine look about right - still missing edge and face connectivity --- surf/geometry.py | 12 ++++++++++++ surf/subd/cc.py | 32 +++++++++++++++++++------------- surf/test/subd/cc.py | 3 ++- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/surf/geometry.py b/surf/geometry.py index 20f721a..fbd7e83 100644 --- a/surf/geometry.py +++ b/surf/geometry.py @@ -25,6 +25,7 @@ def cross(a, b): k = a.x * b.y - a.y * b.x return Vertex(i, j, k) + def centroid(verts): xs = [v.x for v in verts] ys = [v.y for v in verts] @@ -37,6 +38,7 @@ def centroid(verts): return Vertex(x, y, z) + class Vertex(object): ''' A vertex is a position along with other information such as color, normal @@ -72,6 +74,16 @@ class Vertex(object): raise TypeError("{0} has an unexpected type: {1}".format( other, type(other))) + def __iter__(self): + """Added to be able to conveniently convert a Vertex into a list + + >>> v = Vertex(0, 1, 2) + >>> assert list(v) == [0, 1, 2] + """ + yield self.x + yield self.y + yield self.z + def __rmul__(self, other): return self.__mul__(other) diff --git a/surf/subd/cc.py b/surf/subd/cc.py index aec6f93..e6dc6f9 100644 --- a/surf/subd/cc.py +++ b/surf/subd/cc.py @@ -2,17 +2,18 @@ from collections import defaultdict from surf.geometry import PolygonMesh, centroid -from pprint import pprint as pp # XXX - def refine(mesh): new_vertices = list(mesh.vertices) f_vert_offset = len(new_vertices) edge_vids_for = defaultdict(list) - face_vids_for = defaultdict(list) + face_ids_for_v = defaultdict(list) + # TODO: not completely populated yet: new_edges = list(mesh.edges) + + # TODO: must be populated: new_faces = [] # For each face, add a face point @@ -26,6 +27,8 @@ def refine(mesh): # below new_face_point = mesh.centroid(cur_face) new_vertices.append(new_face_point) + for i in cur_face: + face_ids_for_v[i].append(cur_face_id) e_vert_offset = len(new_vertices) @@ -41,7 +44,7 @@ def refine(mesh): # Set each edge point to be the average of the two neighbouring, (very # recently calculated) face points ... tmp_verts.extend([new_vertices[f + f_vert_offset] for f in face_ids_for_edge]) - + # ... and its two original endpoints. tmp_verts.extend([mesh.vertices[vid] for vid in cur_edge]) @@ -55,14 +58,18 @@ def refine(mesh): for edge_vid in edge_vids_for[trunc_vid]: new_edges.append([edge_vid, overall_vid]) - # pp(new_edges) + # v_vert_offset = len(new_vertices) # For each original point P - assert f_vert_offset == len(mesh.vertices) for new_vid in xrange(f_vert_offset): # take the average F of all n face points for faces touching P ... - F = centroid([mesh.vertices[vid] for vid in mesh.faces_for_vert[new_vid]]) - print ">>>", F + + new_face_ids = face_ids_for_v[new_vid] + F_verts = [] + for fid in new_face_ids: + F_verts.append(new_vertices[f_vert_offset + fid]) + + F = centroid(F_verts) # and take the average R of all n edge midpoints for edges touching P # wiki is wrong ... it should be the edge points, not midpoints ... @@ -74,18 +81,17 @@ def refine(mesh): R = centroid(e_verts) # where each edge midpoint is the average of its two endpoint vertices. # Move each original point to the point (or add it to new_verts) - v = (F + 2 * R + (len(edges) - 3) * new_vertices[new_vid]) / len(edges) - - return None + new_vertex_point = (F + 2 * R + (len(edges) - 3) * new_vertices[new_vid]) / len(edges) + new_vertices.append(new_vertex_point) + return PolygonMesh(vertices=new_vertices, edges=new_edges, faces=new_faces) if __name__ == '__main__': import json - from surf.geometry import PolygonMesh from surf.subd.cc import refine - cube = json.load(open('blender/samples/cube.json', 'r')) p = PolygonMesh(**cube) q = refine(p) + print q diff --git a/surf/test/subd/cc.py b/surf/test/subd/cc.py index 1b51ecc..76b08c9 100644 --- a/surf/test/subd/cc.py +++ b/surf/test/subd/cc.py @@ -18,7 +18,8 @@ class TestCC(unittest.TestCase): def test_refine(self): p = PolygonMesh(**self.cube) p2 = cc.refine(p) - print p2 + # TODO: this test is meaningless ... + p2 if __name__ == '__main__': unittest.main(verbosity=3)