2012-05-08 23:32:34 -07:00
|
|
|
from collections import defaultdict
|
2012-03-19 19:38:40 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
from surf.geometry import PolygonMesh, centroid
|
2012-04-14 19:35:05 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
from pprint import pprint as pp # XXX
|
2012-04-14 19:35:05 -07:00
|
|
|
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
def refine(mesh):
|
|
|
|
new_vertices = list(mesh.vertices)
|
|
|
|
f_vert_offset = len(new_vertices)
|
2012-04-16 00:11:27 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
edge_vids_for = defaultdict(list)
|
|
|
|
face_vids_for = defaultdict(list)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
new_edges = list(mesh.edges)
|
|
|
|
new_faces = []
|
2012-04-16 00:11:27 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# For each face, add a face point
|
|
|
|
for cur_face_id, cur_face in enumerate(mesh.faces):
|
|
|
|
# Set each face point to be the centroid of all original points for the
|
|
|
|
# respective face.
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# here we have already created a list that is a copy of the original
|
|
|
|
# verts. we append the new face points to that same list, and simply
|
|
|
|
# keep track of offsets into the new vert list ... see e_vert_offset
|
|
|
|
# below
|
|
|
|
new_face_point = mesh.centroid(cur_face)
|
|
|
|
new_vertices.append(new_face_point)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
e_vert_offset = len(new_vertices)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# For each edge, add an edge point.
|
|
|
|
for cur_edge_id, cur_edge in enumerate(mesh.edges):
|
|
|
|
# make mapping from edge -> new_face_vert for later
|
|
|
|
face_ids_for_edge = mesh.faces_for_edge[cur_edge_id]
|
|
|
|
for fid in face_ids_for_edge:
|
|
|
|
edge_vids_for[fid].append(cur_edge_id)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
tmp_verts = []
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# 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])
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# centroid == average
|
|
|
|
new_vertices.append(centroid(tmp_verts))
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# For each face point, add an edge for every edge of the face, connecting
|
|
|
|
# the face point to each edge point for the face.
|
|
|
|
for trunc_vid in xrange(len(new_vertices[f_vert_offset:e_vert_offset])):
|
|
|
|
overall_vid = f_vert_offset + trunc_vid
|
|
|
|
for edge_vid in edge_vids_for[trunc_vid]:
|
|
|
|
new_edges.append([edge_vid, overall_vid])
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# pp(new_edges)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# 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
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
# 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 ...
|
|
|
|
edges = [mesh.edges[eid] for eid in mesh.edges_for_vert[new_vid]]
|
|
|
|
e_verts = []
|
|
|
|
for edge in edges:
|
|
|
|
e_verts.extend([mesh.vertices[vid] for vid in edge])
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
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)
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
return None
|
2012-05-07 22:19:54 -07:00
|
|
|
|
|
|
|
|
2012-04-14 19:35:05 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
if __name__ == '__main__':
|
|
|
|
import json
|
|
|
|
from surf.geometry import PolygonMesh
|
|
|
|
from surf.subd.cc import refine
|
2012-05-07 22:19:54 -07:00
|
|
|
|
2012-04-14 19:35:05 -07:00
|
|
|
|
2012-05-08 23:32:34 -07:00
|
|
|
cube = json.load(open('blender/samples/cube.json', 'r'))
|
|
|
|
p = PolygonMesh(**cube)
|
|
|
|
q = refine(p)
|