def triangulate_polygon (pids, pos) : """Sort pids in tuples of 3 points .. seealso:: Compared to `topo_triangulate_polygon`, this function will use geometrical informations to produce nice triangles :Parameters: - `pids` (list of pid) - ordered list of points that form a closed polygon - `pos` (dict of (pid|Vector) ) - position of points in the mesh. :Returns Type: list of (pid,pid,pid) """ triangles = topo_triangulate_polygon(pids) if len(triangles) == 1 : return triangles #change triangles to tends towards equilateral one #local triangulated mesh mesh = Topomesh(2) for pid in pids : mesh.add_wisp(0,pid) edge = {} for pid1,pid2,pid3 in triangles : tid = mesh.add_wisp(2) for pida,pidb in [(pid1,pid2),(pid2,pid3),(pid3,pid1)] : key = (min(pida,pidb),max(pida,pidb) ) try : eid = edge[key] except KeyError : eid = mesh.add_wisp(1) mesh.link(1,eid,pida) mesh.link(1,eid,pidb) edge[key] = eid mesh.link(2,tid,eid) #flip edges test = True while test : test = False for eid in tuple(mesh.wisps(1) ) : if flip_necessary(mesh,eid,pos) : flip_edge(mesh,eid) test = True return [tuple(mesh.borders(2,fid,2) ) for fid in mesh.wisps(2)]
def triangulate_polygon(pids, pos): """Sort pids in tuples of 3 points .. seealso:: Compared to `topo_triangulate_polygon`, this function will use geometrical informations to produce nice triangles :Parameters: - `pids` (list of pid) - ordered list of points that form a closed polygon - `pos` (dict of (pid|Vector) ) - position of points in the mesh. :Returns Type: list of (pid,pid,pid) """ triangles = topo_triangulate_polygon(pids) if len(triangles) == 1: return triangles #change triangles to tends towards equilateral one #local triangulated mesh mesh = Topomesh(2) for pid in pids: mesh.add_wisp(0, pid) edge = {} for pid1, pid2, pid3 in triangles: tid = mesh.add_wisp(2) for pida, pidb in [(pid1, pid2), (pid2, pid3), (pid3, pid1)]: key = (min(pida, pidb), max(pida, pidb)) try: eid = edge[key] except KeyError: eid = mesh.add_wisp(1) mesh.link(1, eid, pida) mesh.link(1, eid, pidb) edge[key] = eid mesh.link(2, tid, eid) #flip edges test = True while test: test = False for eid in tuple(mesh.wisps(1)): if flip_necessary(mesh, eid, pos): flip_edge(mesh, eid) test = True return [tuple(mesh.borders(2, fid, 2)) for fid in mesh.wisps(2)]
def triangulate (mesh, fid) : """Triangulate the given face of a mesh :Parameters: - `mesh` (Mesh) - `fid` (did) - id of face to triangulate. Must be of degree 2 :Warning: Modify mesh in place. :Note: This method does not introduce new points in the mesh. """ #store info edges = tuple(mesh.borders(fid) ) if len(edges) == 3 :#face is already a triangle return if len(edges) < 3 : raise UserWarning("face is not geometricaly defined") cells = tuple(mesh.regions(fid) ) #remove face mesh.remove_dart(fid) #walk along edges edge_pool = list(edges) front_eid = edge_pool.pop() ref_pid, front_pid = mesh.borders(front_eid) ref_pos = mesh.position(ref_pid) new_edges = [] while len(edge_pool) > 2 :#remaining two edges will #naturally form a triangle #find next edge next_eid, = (eid for eid in edge_pool \ if front_pid in mesh.borders(eid) ) next_pid, = (pid for pid in mesh.borders(next_eid) \ if pid != front_pid) #triangulate, create an edge between ref_pid and #next_pid new_eid = mesh.add_dart(1) mesh.link(new_eid, ref_pid) mesh.link(new_eid, next_pid) l = norm(mesh.position(next_pid) - ref_pos) new_edges.append( (l, new_eid) ) #create new facet fid = mesh.add_dart(2) for cid in cells : mesh.link(cid, fid) for eid in (front_eid, next_eid, new_eid) : mesh.link(fid, eid) #increment step edge_pool.remove(next_eid) front_eid = new_eid front_pid = next_pid #create last facet fid = mesh.add_dart(2) for cid in cells : mesh.link(cid, fid) for eid in edge_pool + [front_eid] : mesh.link(fid, eid) #improve triangulation quality new_edges.sort() for l, eid in new_edges : if is_flip_better(mesh, eid) : flip_edge(mesh, eid)