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 is_collapse_topo_allowed (mesh, eid, protected_edges) :
    """Test wether collapse of the edge is safe.

    mesh: a topomesh object
    eid: id of the edge to flip
    """
    #collapse enabled only if faces are triangle or square
    for fid in mesh.regions(1,eid) :
        if mesh.nb_borders(2,fid) not in (3,4) :
            return False
    #construct a local copy of the mesh
    #including all the faces that touch one
    #of the extremity of the edge
    #find relevant elements
    fids = set()
    for pid in mesh.borders(1,eid) :
        for bid in mesh.regions(0,pid) :
            fids.update(mesh.regions(1,bid))

    eids = set()
    pids = set()
    for fid in fids :
        eids.update(mesh.borders(2,fid))
        pids.update(mesh.borders(2,fid,2))
    elms = (pids,eids,fids)
    if mesh.degree() == 3 :
        cids = set()
        for fid in fids :
            cids.update(mesh.regions(2,fid))
        elms = elms + (cids,)
    
    #construct local mesh
    lmesh = Topomesh(mesh.degree(),"max")
    for deg,wids in enumerate(elms) :
        for wid in wids :
            lmesh.add_wisp(deg,wid)
    for deg,wids in enumerate(elms[:-1]) :
        for wid in wids :
            for rid in set(mesh.regions(deg,wid)) & elms[deg + 1] :
                lmesh.link(deg + 1,rid,wid)
    #collapse edge on this local copy
    try :
    	pid1,pid2 = collapse_edge(lmesh,eid,protected_edges)
    except UserWarning :
    	return False
    #test the result
    #edges without any face
    for wid in lmesh.wisps(1) :
        if lmesh.nb_regions(1,wid) == 0 :
            return False
    #surperposed faces
    #TODO optimization
    for ref_fid in lmesh.wisps(2) :
        ref_pids = set(lmesh.borders(2,ref_fid,2) )
        for fid in [wid for wid in lmesh.wisps(2) if wid != ref_fid] :
            pids = set(lmesh.borders(2,fid,2) )
            if len(pids) == len(ref_pids) :
                if pids == ref_pids :
                    return False
            elif len(pids) > len(ref_pids) :
                if len(pids - ref_pids) == 1 :
                    return False
            else :
                if len(ref_pids - pids) == 1 :
                    return False
    #return
Exemple #4
0
def is_collapse_topo_allowed(mesh, eid, protected_edges):
    """Test wether collapse of the edge is safe.

    mesh: a topomesh object
    eid: id of the edge to flip
    """
    #collapse enabled only if faces are triangle or square
    for fid in mesh.regions(1, eid):
        if mesh.nb_borders(2, fid) not in (3, 4):
            return False
    #construct a local copy of the mesh
    #including all the faces that touch one
    #of the extremity of the edge
    #find relevant elements
    fids = set()
    for pid in mesh.borders(1, eid):
        for bid in mesh.regions(0, pid):
            fids.update(mesh.regions(1, bid))

    eids = set()
    pids = set()
    for fid in fids:
        eids.update(mesh.borders(2, fid))
        pids.update(mesh.borders(2, fid, 2))
    elms = (pids, eids, fids)
    if mesh.degree() == 3:
        cids = set()
        for fid in fids:
            cids.update(mesh.regions(2, fid))
        elms = elms + (cids, )

    #construct local mesh
    lmesh = Topomesh(mesh.degree(), "max")
    for deg, wids in enumerate(elms):
        for wid in wids:
            lmesh.add_wisp(deg, wid)
    for deg, wids in enumerate(elms[:-1]):
        for wid in wids:
            for rid in set(mesh.regions(deg, wid)) & elms[deg + 1]:
                lmesh.link(deg + 1, rid, wid)
    #collapse edge on this local copy
    try:
        pid1, pid2 = collapse_edge(lmesh, eid, protected_edges)
    except UserWarning:
        return False
    #test the result
    #edges without any face
    for wid in lmesh.wisps(1):
        if lmesh.nb_regions(1, wid) == 0:
            return False
    #surperposed faces
    #TODO optimization
    for ref_fid in lmesh.wisps(2):
        ref_pids = set(lmesh.borders(2, ref_fid, 2))
        for fid in [wid for wid in lmesh.wisps(2) if wid != ref_fid]:
            pids = set(lmesh.borders(2, fid, 2))
            if len(pids) == len(ref_pids):
                if pids == ref_pids:
                    return False
            elif len(pids) > len(ref_pids):
                if len(pids - ref_pids) == 1:
                    return False
            else:
                if len(ref_pids - pids) == 1:
                    return False
    #return
    return True