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
This commit is contained in:
parent
ba1ec89c27
commit
198a7d7ca8
@ -25,6 +25,7 @@ def cross(a, b):
|
|||||||
k = a.x * b.y - a.y * b.x
|
k = a.x * b.y - a.y * b.x
|
||||||
return Vertex(i, j, k)
|
return Vertex(i, j, k)
|
||||||
|
|
||||||
|
|
||||||
def centroid(verts):
|
def centroid(verts):
|
||||||
xs = [v.x for v in verts]
|
xs = [v.x for v in verts]
|
||||||
ys = [v.y for v in verts]
|
ys = [v.y for v in verts]
|
||||||
@ -37,6 +38,7 @@ def centroid(verts):
|
|||||||
|
|
||||||
return Vertex(x, y, z)
|
return Vertex(x, y, z)
|
||||||
|
|
||||||
|
|
||||||
class Vertex(object):
|
class Vertex(object):
|
||||||
'''
|
'''
|
||||||
A vertex is a position along with other information such as color, normal
|
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(
|
raise TypeError("{0} has an unexpected type: {1}".format(
|
||||||
other, type(other)))
|
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):
|
def __rmul__(self, other):
|
||||||
return self.__mul__(other)
|
return self.__mul__(other)
|
||||||
|
|
||||||
|
@ -2,17 +2,18 @@ from collections import defaultdict
|
|||||||
|
|
||||||
from surf.geometry import PolygonMesh, centroid
|
from surf.geometry import PolygonMesh, centroid
|
||||||
|
|
||||||
from pprint import pprint as pp # XXX
|
|
||||||
|
|
||||||
|
|
||||||
def refine(mesh):
|
def refine(mesh):
|
||||||
new_vertices = list(mesh.vertices)
|
new_vertices = list(mesh.vertices)
|
||||||
f_vert_offset = len(new_vertices)
|
f_vert_offset = len(new_vertices)
|
||||||
|
|
||||||
edge_vids_for = defaultdict(list)
|
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)
|
new_edges = list(mesh.edges)
|
||||||
|
|
||||||
|
# TODO: must be populated:
|
||||||
new_faces = []
|
new_faces = []
|
||||||
|
|
||||||
# For each face, add a face point
|
# For each face, add a face point
|
||||||
@ -26,6 +27,8 @@ def refine(mesh):
|
|||||||
# below
|
# below
|
||||||
new_face_point = mesh.centroid(cur_face)
|
new_face_point = mesh.centroid(cur_face)
|
||||||
new_vertices.append(new_face_point)
|
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)
|
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
|
# Set each edge point to be the average of the two neighbouring, (very
|
||||||
# recently calculated) face points ...
|
# recently calculated) face points ...
|
||||||
tmp_verts.extend([new_vertices[f + f_vert_offset] for f in face_ids_for_edge])
|
tmp_verts.extend([new_vertices[f + f_vert_offset] for f in face_ids_for_edge])
|
||||||
|
|
||||||
# ... and its two original endpoints.
|
# ... and its two original endpoints.
|
||||||
tmp_verts.extend([mesh.vertices[vid] for vid in cur_edge])
|
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]:
|
for edge_vid in edge_vids_for[trunc_vid]:
|
||||||
new_edges.append([edge_vid, overall_vid])
|
new_edges.append([edge_vid, overall_vid])
|
||||||
|
|
||||||
# pp(new_edges)
|
# v_vert_offset = len(new_vertices)
|
||||||
|
|
||||||
# For each original point P
|
# For each original point P
|
||||||
assert f_vert_offset == len(mesh.vertices)
|
|
||||||
for new_vid in xrange(f_vert_offset):
|
for new_vid in xrange(f_vert_offset):
|
||||||
# take the average F of all n face points for faces touching P ...
|
# 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
|
# 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 ...
|
# wiki is wrong ... it should be the edge points, not midpoints ...
|
||||||
@ -74,18 +81,17 @@ def refine(mesh):
|
|||||||
R = centroid(e_verts)
|
R = centroid(e_verts)
|
||||||
# where each edge midpoint is the average of its two endpoint vertices.
|
# 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)
|
# 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)
|
new_vertex_point = (F + 2 * R + (len(edges) - 3) * new_vertices[new_vid]) / len(edges)
|
||||||
|
new_vertices.append(new_vertex_point)
|
||||||
return None
|
|
||||||
|
|
||||||
|
return PolygonMesh(vertices=new_vertices, edges=new_edges, faces=new_faces)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import json
|
import json
|
||||||
from surf.geometry import PolygonMesh
|
|
||||||
from surf.subd.cc import refine
|
from surf.subd.cc import refine
|
||||||
|
|
||||||
|
|
||||||
cube = json.load(open('blender/samples/cube.json', 'r'))
|
cube = json.load(open('blender/samples/cube.json', 'r'))
|
||||||
p = PolygonMesh(**cube)
|
p = PolygonMesh(**cube)
|
||||||
q = refine(p)
|
q = refine(p)
|
||||||
|
print q
|
||||||
|
@ -18,7 +18,8 @@ class TestCC(unittest.TestCase):
|
|||||||
def test_refine(self):
|
def test_refine(self):
|
||||||
p = PolygonMesh(**self.cube)
|
p = PolygonMesh(**self.cube)
|
||||||
p2 = cc.refine(p)
|
p2 = cc.refine(p)
|
||||||
print p2
|
# TODO: this test is meaningless ...
|
||||||
|
p2
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(verbosity=3)
|
unittest.main(verbosity=3)
|
||||||
|
Loading…
Reference in New Issue
Block a user