예제 #1
0
def layer_triangle_topomesh_construction(layer_edge_topomesh, positions, omega_criteria = {'distance':1.0,'wall_surface':2.0,'clique':10.0}, **kwargs):

    compute_topomesh_property(layer_edge_topomesh,'length',1)

    edge_weights = np.zeros(layer_edge_topomesh.nb_wisps(1))
    if omega_criteria.has_key('distance'):
        edge_weights += omega_criteria['distance']*np.exp(-np.power(layer_edge_topomesh.wisp_property('length',1).values()/15.0,1))
    
    if omega_criteria.has_key('wall_surface'):
        img_wall_surfaces = kwargs.get('wall_surfaces',None)
        img_volumes = kwargs.get('cell_volumes',dict(zip(positions.keys(),np.ones_like(positions.keys()))))
        assert layer_edge_topomesh.has_wisp_property('wall_surface',1) or img_wall_surfaces is not None
        if not layer_edge_topomesh.has_wisp_property('wall_surface',1):
            layer_edge_vertices = np.sort([list(layer_edge_topomesh.borders(1,e)) for e in layer_edge_topomesh.wisps(1)])
            layer_edge_wall_surface = np.array([img_wall_surfaces[tuple(e)]/np.power(img_volumes.values(e).mean(),2./3.) for e in layer_edge_vertices])
            layer_edge_topomesh.update_wisp_property('wall_surface',1,array_dict(layer_edge_wall_surface,list(layer_edge_topomesh.wisps(1))))
        
        edge_weights += omega_criteria['wall_surface']*layer_edge_topomesh.wisp_property('wall_surface',1).values() 
    
    edge_weights = array_dict(edge_weights,list(layer_edge_topomesh.wisps(1)))
    
    edge_neighbor_vertices = [np.concatenate([list(set(layer_edge_topomesh.region_neighbors(0,c)))+[c] for c in layer_edge_topomesh.borders(1,e)]) for e in layer_edge_topomesh.wisps(1)]
    edge_neighbor_vertices_edges = [np.concatenate([list(layer_edge_topomesh.regions(0,n_v)) for n_v in n_vertices]) for n_vertices in edge_neighbor_vertices]
    edge_triangle_edges = [np.unique(e)[nd.sum(np.ones_like(e),e,index=np.unique(e))>3] for e in edge_neighbor_vertices_edges]
    
    if omega_criteria.has_key('clique'):
        edge_neighbor_weights = array_dict([edge_weights.values(e).min() - omega_criteria['clique']*(len(e)>3) for e in edge_triangle_edges],list(layer_edge_topomesh.wisps(1)))
    else:
        edge_neighbor_weights = array_dict([edge_weights.values(e).min() for e in edge_triangle_edges],list(layer_edge_topomesh.wisps(1)))
    edge_triangle_edges = array_dict(edge_triangle_edges,list(layer_edge_topomesh.wisps(1)))
    
    triangulation_edges = np.array(list(layer_edge_topomesh.wisps(1)))[np.array(map(len,edge_triangle_edges))>=3]
    
    layer_triangulation_topomesh = PropertyTopomesh(3)
    layer_triangulation_topomesh.add_wisp(3,1)
    
    initial_edge = np.array(list(layer_edge_topomesh.wisps(1)))[triangulation_edges][np.argmax(edge_neighbor_weights.values(triangulation_edges))]
    free_edges = [initial_edge]
        
    while len(free_edges) > 0:
        eid_to_add = free_edges.pop(0)
        print "--> Edge",list(layer_edge_topomesh.borders(1,eid_to_add))," : ",edge_neighbor_weights[eid_to_add]
        
        edge_vertex_edges = np.concatenate([list(set(layer_edge_topomesh.regions(0,c)).difference({eid_to_add})) for c in layer_edge_topomesh.borders(1,eid_to_add)])
        edge_vertex_edge_vertices =  np.concatenate([c*np.ones(layer_edge_topomesh.nb_regions(0,c)-1) for c in layer_edge_topomesh.borders(1,eid_to_add)])
        edge_vertex_edge_neighbor_vertices = np.array([list(set(layer_edge_topomesh.borders(1,e)).difference({v}))[0] for e,v in zip(edge_vertex_edges,edge_vertex_edge_vertices)])
    
        candidate_triangle_vertices = np.unique(edge_vertex_edge_neighbor_vertices)[nd.sum(np.ones_like(edge_vertex_edge_neighbor_vertices),edge_vertex_edge_neighbor_vertices,index=np.unique(edge_vertex_edge_neighbor_vertices))==2]
        candidate_triangle_edges = np.array([np.concatenate([[eid_to_add],edge_vertex_edges[edge_vertex_edge_neighbor_vertices==c]]) for c in candidate_triangle_vertices])
        
        if len(candidate_triangle_edges)>0:
            candidate_triangle_free_edges = np.array([np.sum([e in free_edges for e in triangle_edges]) for triangle_edges in candidate_triangle_edges])
            candidate_triangle_edge_weights = edge_weights.values(candidate_triangle_edges[:,1:]).min(axis=1)
            
            if (candidate_triangle_free_edges ==candidate_triangle_free_edges.max()).sum() == 1:
                sorted_candidate_triangle_edges = candidate_triangle_edges[np.argsort(-candidate_triangle_free_edges)]
            else:
                sorted_candidate_triangle_edges = candidate_triangle_edges[np.argsort(-candidate_triangle_edge_weights)]
            
            for triangle_edges in sorted_candidate_triangle_edges:
                if np.all(np.array([0 if not layer_triangulation_topomesh.has_wisp(1,e) else layer_triangulation_topomesh.nb_regions(1,e) for e in triangle_edges])<2):
                    triangle_vertices = np.unique([list(layer_edge_topomesh.borders(1,e)) for e in triangle_edges])
                    if layer_triangulation_topomesh.nb_wisps(2)!=1 or vq(np.sort([triangle_vertices]),np.sort([list(layer_triangulation_topomesh.borders(2,t,2)) for t in layer_triangulation_topomesh.wisps(2)]))[1][0]>0:
                        fid = layer_triangulation_topomesh.add_wisp(2)
                        layer_triangulation_topomesh.link(3,1,fid)
                        print "  --> Triangle",fid,triangle_vertices," : ",edge_weights.values(triangle_edges[1:]).min()
                        for c in triangle_vertices:
                            if not layer_triangulation_topomesh.has_wisp(0,c):
                                layer_triangulation_topomesh.add_wisp(0,c)
                        for e in triangle_edges:
                            if not layer_triangulation_topomesh.has_wisp(1,e):
                                layer_triangulation_topomesh.add_wisp(1,e)
                                for c in layer_edge_topomesh.borders(1,e):
                                    layer_triangulation_topomesh.link(1,e,c)
                            layer_triangulation_topomesh.link(2,fid,e)
                        
                            if layer_triangulation_topomesh.nb_regions(1,e)<2:
                                if not e in free_edges:
                                    free_edges.append(e)
                                edge_future_triangle_edges = list(set(edge_triangle_edges[e]).difference(set(layer_triangulation_topomesh.wisps(1)).difference(set(free_edges))))
                                
                                if omega_criteria.has_key('clique'):
                                    edge_neighbor_weights[e] = np.min(edge_weights.values(edge_future_triangle_edges)) - omega_criteria['clique']*(len(edge_future_triangle_edges)>3)
                                else:
                                    edge_neighbor_weights[e] = np.min(edge_weights.values(edge_future_triangle_edges))
            
            print free_edges
            if len(free_edges)>0:
                free_edges = list(np.array(free_edges)[np.argsort(-edge_neighbor_weights.values(free_edges))])                    
        layer_triangulation_topomesh.update_wisp_property('barycenter',0,array_dict(positions.values(list(layer_triangulation_topomesh.wisps(0))),list(layer_triangulation_topomesh.wisps(0))))
    return layer_triangulation_topomesh
예제 #2
0
def layered_tetrahedra_topomesh_construction(layer_triangle_topomesh, positions, cell_layer, omega_criteria = {'distance':1.0,'wall_surface':2.0,'clique':10.0}, **kwargs):
    compute_topomesh_property(layer_triangle_topomesh,'length',1)
    compute_topomesh_property(layer_triangle_topomesh,'borders',2)
    compute_topomesh_property(layer_triangle_topomesh,'perimeter',2)
    
    if omega_criteria.has_key('wall_surface'):
        img_wall_surfaces = kwargs.get('wall_surfaces',None)
        img_volumes = kwargs.get('cell_volumes',dict(zip(positions.keys(),np.ones_like(positions.keys()))))
        assert layer_triangle_topomesh.has_wisp_property('wall_surface',1) or img_wall_surfaces is not None
        if not layer_triangle_topomesh.has_wisp_property('wall_surface',1):
            L1_L2_triangle_edge_vertices = np.array([np.sort([list(layer_triangle_topomesh.borders(1,e)) for e in layer_triangle_topomesh.borders(2,t)]) for t in layer_triangle_topomesh.wisps(2)])
            L1_L2_triangle_edge_wall_surface = np.array([[-1. if tuple(e) not in img_wall_surfaces.keys() else img_wall_surfaces[tuple(e)]/np.power(img_volumes.values(e).mean(),2./3.) for e in t] for t in L1_L2_triangle_edge_vertices])
            layer_triangle_topomesh.update_wisp_property('wall_surface',2,array_dict(L1_L2_triangle_edge_wall_surface.min(axis=1),list(layer_triangle_topomesh.wisps(2))))
            layer_triangle_topomesh = layer_triangle_topomesh

    triangle_weights = np.zeros(layer_triangle_topomesh.nb_wisps(2))
    if omega_criteria.has_key('distance'):
        triangle_weights += omega_criteria['distance']*np.exp(-np.power(layer_triangle_topomesh.wisp_property('length',1).values(layer_triangle_topomesh.wisp_property('borders',2).values()).max(axis=1)/15.0,1))
    if omega_criteria.has_key('wall_surface'):
        triangle_weights += omega_criteria['wall_surface']*layer_triangle_topomesh.wisp_property('wall_surface',2).values() 
    triangle_weights = array_dict(triangle_weights,list(layer_triangle_topomesh.wisps(2)))
        
    triangle_neighbor_edges = [np.concatenate([list(set(layer_triangle_topomesh.region_neighbors(1,e)))+[e] for e in layer_triangle_topomesh.borders(2,t)]) for t in layer_triangle_topomesh.wisps(2)]
    triangle_neighbor_edge_triangles = [np.concatenate([list(layer_triangle_topomesh.regions(1,n_e)) for n_e in n_edges]) for n_edges in triangle_neighbor_edges]
    triangle_tetrahedra_triangles = [np.unique(t)[nd.sum(np.ones_like(t),t,index=np.unique(t))>5] for t in triangle_neighbor_edge_triangles]

    if omega_criteria.has_key('clique'):
        triangle_neighbor_weights = array_dict([triangle_weights.values(t).min() - omega_criteria['clique']*(len(t)-4) for t in triangle_tetrahedra_triangles],list(layer_triangle_topomesh.wisps(2)))
    else:
        triangle_neighbor_weights = array_dict([triangle_weights.values(t).min() for t in triangle_tetrahedra_triangles],list(layer_triangle_topomesh.wisps(2)))
    triangle_tetrahedra_triangles = array_dict(triangle_tetrahedra_triangles,list(layer_triangle_topomesh.wisps(2)))

    tetrahedrization_triangles = np.array(list(layer_triangle_topomesh.wisps(2)))[np.array(map(len,triangle_tetrahedra_triangles))>=4]
        
    constructed_triangulation_topomesh = PropertyTopomesh(3)
    initial_triangle = np.array(list(layer_triangle_topomesh.wisps(2)))[tetrahedrization_triangles][np.argmax(triangle_neighbor_weights.values(tetrahedrization_triangles))]
    free_triangles = [initial_triangle]

    while len(free_triangles) > 0:
        fid_to_add = free_triangles.pop(0)
        print "--> Triangle",list(layer_triangle_topomesh.borders(2,fid_to_add))," : ",triangle_neighbor_weights[fid_to_add]
        
        triangle_vertex_edges = np.concatenate([list(set(layer_triangle_topomesh.regions(0,c)).difference(set(layer_triangle_topomesh.borders(2,fid_to_add)))) for c in layer_triangle_topomesh.borders(2,fid_to_add,2)])
        triangle_vertex_edge_vertices = np.concatenate([c*np.ones(layer_triangle_topomesh.nb_regions(0,c)-2) for c in layer_triangle_topomesh.borders(2,fid_to_add,2)])
        triangle_vertex_edge_neighbor_vertices = np.array([list(set(layer_triangle_topomesh.borders(1,e)).difference({v}))[0] for e,v in zip(triangle_vertex_edges,triangle_vertex_edge_vertices)])

        candidate_tetra_vertices = np.unique(triangle_vertex_edge_neighbor_vertices)[nd.sum(np.ones_like(triangle_vertex_edge_neighbor_vertices),triangle_vertex_edge_neighbor_vertices,index=np.unique(triangle_vertex_edge_neighbor_vertices))==3]
        candidate_tetra_edges = np.array([triangle_vertex_edges[triangle_vertex_edge_neighbor_vertices==c] for c in candidate_tetra_vertices])
        
        candidate_tetra_edge_triangles = [np.concatenate([list(set(layer_triangle_topomesh.regions(1,e)).difference({fid_to_add})) for e in candidate_edges]) for candidate_edges in candidate_tetra_edges]
        candidate_tetra_triangles = np.array([np.concatenate([[fid_to_add],np.unique(t)[nd.sum(np.ones_like(t),t,index=np.unique(t))==2]]) for t in candidate_tetra_edge_triangles])
        
        if len(candidate_tetra_triangles)>0:
            candidate_tetra_free_triangles = np.array([np.sum([t in free_triangles for t in tetra_triangles]) for tetra_triangles in candidate_tetra_triangles])
            candidate_tetra_triangle_weights = triangle_weights.values(candidate_tetra_triangles[:,1:]).min(axis=1)
            
            if (candidate_tetra_free_triangles == candidate_tetra_free_triangles.max()).sum() == 1:
                sorted_candidate_tetra_triangles = candidate_tetra_triangles[np.argsort(-candidate_tetra_free_triangles)]
            else:
                sorted_candidate_tetra_triangles = candidate_tetra_triangles[np.argsort(-candidate_tetra_triangle_weights)]
            
            for tetra_triangles in sorted_candidate_tetra_triangles:
                if np.all(np.array([0 if not constructed_triangulation_topomesh.has_wisp(2,t) else constructed_triangulation_topomesh.nb_regions(2,t) for t in tetra_triangles])<2):
                    tetra_vertices = np.unique([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangles])
                    tetra_edges = np.unique([list(layer_triangle_topomesh.borders(2,t)) for t in tetra_triangles])
                    if constructed_triangulation_topomesh.nb_wisps(3)!=1 or vq(np.sort([tetra_vertices]),np.sort([list(constructed_triangulation_topomesh.borders(3,t,3)) for t in constructed_triangulation_topomesh.wisps(3)]))[1][0]>0:
                        if len(np.unique(cell_layer.values(tetra_vertices)))==2:
                            #tetra_triangle_tetras = np.unique([list(constructed_triangulation_topomesh.regions(2,t)) for t in tetra_triangles if constructed_triangulation_topomesh.has_wisp(2,t)])
                            tetra_triangle_tetras = np.array(list(constructed_triangulation_topomesh.wisps(3)))
                            if len(tetra_triangle_tetras)>0:
                                tetra_triangle_tetra_edges = np.unique([list(constructed_triangulation_topomesh.borders(3,t,2)) for t in tetra_triangle_tetras])
                                tetra_triangle_points = positions.values(np.array([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangles]))
                                tetra_triangle_tetra_edge_points = positions.values(np.array([list(layer_triangle_topomesh.borders(1,e)) for e in tetra_triangle_tetra_edges]))
                                tetra_triangle_intersection = np.ravel([intersecting_triangle(edge_points,tetra_triangle_points) for edge_points in tetra_triangle_tetra_edge_points])
                            
                                tetra_triangle_edges = np.unique([list(layer_triangle_topomesh.borders(2,t)) for t in tetra_triangles])
                                tetra_triangle_tetra_triangles = np.unique([list(constructed_triangulation_topomesh.borders(3,t)) for t in tetra_triangle_tetras])
                                tetra_triangle_edge_points = positions.values(np.array([list(layer_triangle_topomesh.borders(1,e)) for e in tetra_triangle_edges]))
                                tetra_triangle_tetra_triangle_points = positions.values(np.array([list(layer_triangle_topomesh.borders(2,t,2)) for t in tetra_triangle_tetra_triangles]))
                                tetra_edge_intersection = np.ravel([intersecting_triangle(edge_points,tetra_triangle_tetra_triangle_points) for edge_points in tetra_triangle_edge_points])
                                tetra_triangle_intersection = np.concatenate([tetra_triangle_intersection,tetra_edge_intersection])
                            else:
                                tetra_triangle_intersection = [False]
                            if not np.any(tetra_triangle_intersection):
                                tid = constructed_triangulation_topomesh.add_wisp(3)
                                print "  --> Tetrahedron",tid,tetra_vertices," : ", triangle_weights.values(tetra_triangles[1:]).min()
                                for c in tetra_vertices:
                                    if not constructed_triangulation_topomesh.has_wisp(0,c):
                                        constructed_triangulation_topomesh.add_wisp(0,c)
                                for e in tetra_edges:
                                    if not constructed_triangulation_topomesh.has_wisp(1,e):
                                        constructed_triangulation_topomesh.add_wisp(1,e)
                                        for c in layer_triangle_topomesh.borders(1,e):
                                            constructed_triangulation_topomesh.link(1,e,c)
                                for t in tetra_triangles:
                                    if not constructed_triangulation_topomesh.has_wisp(2,t):
                                        constructed_triangulation_topomesh.add_wisp(2,t)
                                        for e in layer_triangle_topomesh.borders(2,t):
                                            constructed_triangulation_topomesh.link(2,t,e)
                                    constructed_triangulation_topomesh.link(3,tid,t)
                                    
                                    if constructed_triangulation_topomesh.nb_regions(2,t)<2 and len(np.unique(cell_layer.values(list(constructed_triangulation_topomesh.borders(2,t,2)))))==2:
                                        if not t in free_triangles:
                                            free_triangles.append(t)
                                        
                                        triangle_future_tetra_triangles = list(set(triangle_tetrahedra_triangles[t]).difference(set(constructed_triangulation_topomesh.wisps(2)).difference(set(free_triangles))))
                                        
                                        if omega_criteria.has_key('clique'):
                                            triangle_neighbor_weights[t] = np.min(triangle_weights.values(triangle_future_tetra_triangles)) - omega_criteria['clique']*(len(triangle_future_tetra_triangles)-4)
                                        else:
                                            triangle_neighbor_weights[t] = np.min(triangle_weights.values(triangle_future_tetra_triangles))
        
        # print free_triangles
        if len(free_triangles)>0:
            free_triangles = list(np.array(free_triangles)[np.argsort(-triangle_neighbor_weights.values(free_triangles))])
        constructed_triangulation_topomesh.update_wisp_property('barycenter',0,array_dict(positions.values(list(constructed_triangulation_topomesh.wisps(0))),list(constructed_triangulation_topomesh.wisps(0))))

    return constructed_triangulation_topomesh