81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
from __future__ import division
|
|
|
|
from itertools import combinations
|
|
|
|
from surf.geometry import PolygonMesh, Vertex
|
|
|
|
|
|
def _get_third_point(mesh, eid, fid):
|
|
evids = set(mesh.edges[eid])
|
|
fvids = set(mesh.faces[fid])
|
|
other_vid = fvids - evids
|
|
assert len(other_vid) == 1
|
|
other_vid = other_vid.pop()
|
|
return other_vid
|
|
|
|
|
|
def _make_edge_point(mesh, eid):
|
|
final_vert = Vertex()
|
|
|
|
a = 1 / 2
|
|
b = 1 / 8
|
|
c = -1 / 16
|
|
|
|
a_verts = [mesh.vertices[v] for v in mesh.edges[eid]]
|
|
for v in a_verts:
|
|
final_vert += a * v
|
|
|
|
for fid in mesh.faces_for_edge[eid]:
|
|
other_vid = _get_third_point(mesh, eid, fid)
|
|
final_vert += b * mesh.vertices[other_vid]
|
|
|
|
other_edges = [e for e in mesh.edges_for_face[fid] if e != eid]
|
|
for other_edge in other_edges:
|
|
wing_face = [f for f in mesh.faces_for_edge[other_edge]
|
|
if f != fid]
|
|
assert len(wing_face) == 1
|
|
vid = _get_third_point(mesh, other_edge, wing_face[0])
|
|
final_vert += c * mesh.vertices[vid]
|
|
|
|
return final_vert
|
|
|
|
|
|
def refine(mesh):
|
|
new_verts = list(mesh.vertices)
|
|
nv_offset = len(new_verts)
|
|
new_edges = []
|
|
new_faces = []
|
|
|
|
for eid, verts_for_edge in enumerate(mesh.edges):
|
|
new_vert = _make_edge_point(mesh, eid)
|
|
new_verts.append(new_vert)
|
|
|
|
# populate *some* of the new edges (missing all edges on a face ...)
|
|
new_vert_id = eid + nv_offset
|
|
for evid in mesh.edges[eid]:
|
|
new_edge = [evid, new_vert_id]
|
|
new_edges.append(new_edge)
|
|
|
|
for fid in range(len(mesh.faces)):
|
|
# join all new edge points on a face:
|
|
new_center_face = [i + nv_offset for i in mesh.edges_for_face[fid]]
|
|
inner_edges = list(combinations(new_center_face, 2))
|
|
new_edges.extend(inner_edges)
|
|
|
|
# make new faces: center face
|
|
new_faces.append(new_center_face)
|
|
|
|
# three new faces, one per old vertex:
|
|
for fvid in mesh.faces[fid]:
|
|
possible_edges = mesh.edges_for_vert[fvid]
|
|
face_edges = mesh.edges_for_face[fid]
|
|
edges_for_fvid = list(set(possible_edges) & set(face_edges))
|
|
assert len(edges_for_fvid) == 2
|
|
new_faces.append([
|
|
edges_for_fvid[0] + nv_offset,
|
|
fvid,
|
|
edges_for_fvid[1] + nv_offset
|
|
])
|
|
|
|
return PolygonMesh(new_verts, new_faces, new_edges)
|