def __init__(self, degree=3, topomesh=None, **kwds): self._successors = [IdDict(idgenerator = "set") for i in xrange(degree+1)] self._predecessors = [IdDict(idgenerator = "set") for i in xrange(degree+1)] PropertyTopomesh.__init__(self, degree, topomesh, **kwds) if topomesh is not None: for d in xrange(degree+1): for w in self.wisps(d): self._successors[d][w] = array("L") self._predecessors[d][w] = array("L")
def vertex_topomesh(positions, **kwargs): positions = array_dict(positions) start_time = time() print "--> Generating vertex topomesh" vertex_topomesh = PropertyTopomesh(3) for c in positions.keys(): vertex_topomesh.add_wisp(0,c) vertex_topomesh.update_wisp_property('barycenter',0,positions.values(positions.keys()),keys=positions.keys()) end_time = time() print "<-- Generating vertex topomesh [",end_time-start_time,"s]" return vertex_topomesh
def edge_topomesh(edges, positions, **kwargs): positions = array_dict(positions) start_time = time() print "--> Generating edge topomesh" edge_topomesh = PropertyTopomesh(3) for c in np.unique(edges): edge_topomesh.add_wisp(0,c) for e in edges: eid = edge_topomesh.add_wisp(1) for pid in e: edge_topomesh.link(1,eid,pid) edge_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(edges)),keys=np.unique(edges)) end_time = time() print "<-- Generating edge topomesh [",end_time-start_time,"s]" return edge_topomesh
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
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
def save_property_topomesh(topomesh, path, cells_to_save=None, properties_to_save=dict([(0,['barycenter']),(1,[]),(2,[]),(3,[])]),**kwargs): if cells_to_save is None: cells_to_save = np.array(list(topomesh.wisps(3))) triangles_to_save = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(3,c))) for c in cells_to_save])),int) edges_to_save = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(2,t))) for t in triangles_to_save])),int) vertices_to_save = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(1,e))) for e in edges_to_save])),int) original_pids = kwargs.get('original_pids',False) original_eids = kwargs.get('original_eids',False) original_fids = kwargs.get('original_fids',False) original_cids = kwargs.get('original_cids',True) sub_topomesh = PropertyTopomesh(3) vertices_to_pids = {} for v in vertices_to_save: if original_pids: pid = sub_topomesh.add_wisp(0,v) else: pid = sub_topomesh.add_wisp(0) vertices_to_pids[v] = pid edges_to_eids = {} for e in edges_to_save: if original_eids: eid = sub_topomesh.add_wisp(1,e) else: eid = sub_topomesh.add_wisp(1) edges_to_eids[e] = eid for v in topomesh.borders(1,e): sub_topomesh.link(1,eid,vertices_to_pids[v]) triangles_to_fids = {} for t in triangles_to_save: if original_fids: fid = sub_topomesh.add_wisp(2,t) else: fid = sub_topomesh.add_wisp(2) triangles_to_fids[t] = fid for e in topomesh.borders(2,t): sub_topomesh.link(2,fid,edges_to_eids[e]) cells_to_cids = {} for c in cells_to_save: if original_cids: cid = sub_topomesh.add_wisp(3,c) else: cid = sub_topomesh.add_wisp(3,c) cells_to_cids[c] = cid for t in topomesh.borders(3,c): sub_topomesh.link(3,cid,triangles_to_fids[t]) wisps_to_save = {} wisps_to_save[0] = vertices_to_save wisps_to_save[1] = edges_to_save wisps_to_save[2] = triangles_to_save wisps_to_save[3] = cells_to_save wisps_to_wids = {} wisps_to_wids[0] = vertices_to_pids wisps_to_wids[1] = edges_to_eids wisps_to_wids[2] = triangles_to_fids wisps_to_wids[3] = cells_to_cids if not 0 in properties_to_save.keys(): properties_to_save[0] = [] if not 'barycenter' in properties_to_save[0]: properties_to_save[0].append('barycenter') for degree in properties_to_save.keys(): for property_name in properties_to_save[degree]: print "Property ",property_name,'(',degree,')' if topomesh.has_wisp_property(property_name,degree=degree,is_computed=True): wids_to_save = array_dict(wisps_to_wids[degree]).values(wisps_to_save[degree]) sub_topomesh.update_wisp_property(property_name,degree,array_dict(topomesh.wisp_property(property_name,degree).values(wisps_to_save[degree]),wids_to_save)) pickle.dump(sub_topomesh,open(path,"wb"))
for f in element_properties['volume'][c]['face_index']: face_cells[triangle_matching[f]] = face_cells[triangle_matching[f]].union({cell_matching[c]}) else: for f in xrange(len(unique_triangles)): face_cells[triangle_matching[f]] = {0} else: cell_matching[0] = 0 for f in xrange(len(unique_triangles)): face_cells[triangle_matching[f]] = {0} element_matching['volume'] = cell_matching if verbose: print len(cell_matching)," Cells" if timecheck: print 'cell unicity test:',time()-check_time if timecheck: check_time =time() topomesh = PropertyTopomesh(3) for pid in xrange(len(unique_points)): topomesh.add_wisp(0,pid) for fid in xrange(len(unique_triangles)): topomesh.add_wisp(2,fid) for cid in face_cells[fid]: if not topomesh.has_wisp(3, cid): topomesh.add_wisp(3,cid) topomesh.link(3,cid,fid) for eid,e in enumerate(unique_edges): topomesh.add_wisp(1,eid) for pid in e: topomesh.link(1,eid,pid)
def implicit_surface_topomesh(density_field,size,resolution,iso=0.5,center=True): import numpy as np from scipy.cluster.vq import kmeans, vq from openalea.container import array_dict, PropertyTopomesh surface_points, surface_triangles = vtk_marching_cubes(density_field,iso) surface_points = (np.array(surface_points))*(size*resolution/np.array(density_field.shape)) if center: surface_points -= np.array(density_field.shape)*resolution/2. # points_ids = np.arange(len(surface_points)) # points_to_delete = [] # for p,point in enumerate(surface_points): # matching_points = np.sort(np.where(vq(surface_points,np.array([point]))[1] == 0)[0]) # if len(matching_points) > 1: # points_to_fuse = matching_points[1:] # for m_p in points_to_fuse: # surface_triangles[np.where(surface_triangles==m_p)] = matching_points[0] # points_to_delete.append(m_p) # points_to_delete = np.unique(points_to_delete) # print len(points_to_delete),"points deleted" # surface_points = np.delete(surface_points,points_to_delete,0) # points_ids = np.delete(points_ids,points_to_delete,0) # surface_triangles = array_dict(np.arange(len(surface_points)),points_ids).values(surface_triangles) # for p,point in enumerate(surface_points): # matching_points = np.where(vq(surface_points,np.array([point]))[1] == 0)[0] # if len(matching_points) > 1: # print p,point # raw_input() # triangles_to_delete = [] # for t,triangle in enumerate(surface_triangles): # if len(np.unique(triangle)) < 3: # triangles_to_delete.append(t) # # elif triangle.max() >= len(surface_points): # # triangles_to_delete.append(t) # surface_triangles = np.delete(surface_triangles,triangles_to_delete,0) surface_topomesh = PropertyTopomesh(3) for p in surface_points: pid = surface_topomesh.add_wisp(0) triangle_edge_list = np.array([[1, 2],[0, 2],[0, 1]]) surface_edges = np.sort(np.concatenate(surface_triangles[:,triangle_edge_list])) _,unique_edges = np.unique(np.ascontiguousarray(surface_edges).view(np.dtype((np.void,surface_edges.dtype.itemsize * surface_edges.shape[1]))),return_index=True) surface_edges = surface_edges[unique_edges] for e in surface_edges: eid = surface_topomesh.add_wisp(1) for pid in e: surface_topomesh.link(1,eid,pid) surface_triangle_edges = np.sort(np.concatenate(surface_triangles[:,triangle_edge_list])) surface_triangle_edge_matching = vq(surface_triangle_edges,surface_edges)[0].reshape(surface_triangles.shape[0],3) for t in surface_triangles: fid = surface_topomesh.add_wisp(2) for eid in surface_triangle_edge_matching[fid]: surface_topomesh.link(2,fid,eid) cid = surface_topomesh.add_wisp(3) for fid in surface_topomesh.wisps(2): surface_topomesh.link(3,cid,fid) surface_topomesh.update_wisp_property('barycenter',0,array_dict(surface_points),keys=list(surface_topomesh.wisps(0))) return surface_topomesh
def triangle_topomesh(triangles, positions, **kwargs): triangles = np.array(triangles) positions = array_dict(positions) edges = array_unique(np.sort(np.concatenate(triangles[:,triangle_edge_list],axis=0))) triangle_edges = np.sort(np.concatenate(triangles[:,triangle_edge_list])) start_time = time() print "--> Generating triangle topomesh" triangle_edge_matching = vq(triangle_edges,edges)[0] triangle_topomesh = PropertyTopomesh(3) for c in np.unique(triangles): triangle_topomesh.add_wisp(0,c) for e in edges: eid = triangle_topomesh.add_wisp(1) for pid in e: triangle_topomesh.link(1,eid,pid) for t in triangles: fid = triangle_topomesh.add_wisp(2) for eid in triangle_edge_matching[3*fid:3*fid+3]: triangle_topomesh.link(2,fid,eid) triangle_topomesh.add_wisp(3,0) for fid in triangle_topomesh.wisps(2): triangle_topomesh.link(3,0,fid) triangle_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(triangles)),keys=np.unique(triangles)) end_time = time() print "<-- Generating triangle topomesh [",end_time-start_time,"s]" return triangle_topomesh
def tetrahedra_topomesh(tetrahedra, positions, **kwargs): tetrahedra = np.array(tetrahedra) positions = array_dict(positions) tetrahedra_triangles = array_unique(np.concatenate(np.sort(tetrahedra[:,tetra_triangle_list]))) tetrahedra_triangle_edges = tetrahedra_triangles[:,triangle_edge_list] tetrahedra_triangle_vectors = positions.values(tetrahedra_triangle_edges[...,1]) - positions.values(tetrahedra_triangle_edges[...,0]) tetrahedra_triangle_lengths = np.linalg.norm(tetrahedra_triangle_vectors,axis=2) tetrahedra_triangle_perimeters = tetrahedra_triangle_lengths.sum(axis=1) tetrahedra_edges = array_unique(np.concatenate(tetrahedra_triangles[:,triangle_edge_list],axis=0)) start_time = time() print "--> Generating tetrahedra topomesh" triangle_edges = np.concatenate(tetrahedra_triangles[:,triangle_edge_list],axis=0) triangle_edge_matching = vq(triangle_edges,tetrahedra_edges)[0] tetrahedra_faces = np.concatenate(np.sort(tetrahedra[:,tetra_triangle_list])) tetrahedra_triangle_matching = vq(tetrahedra_faces,tetrahedra_triangles)[0] tetrahedra_topomesh = PropertyTopomesh(3) for c in np.unique(tetrahedra_triangles): tetrahedra_topomesh.add_wisp(0,c) for e in tetrahedra_edges: eid = tetrahedra_topomesh.add_wisp(1) for pid in e: tetrahedra_topomesh.link(1,eid,pid) for t in tetrahedra_triangles: fid = tetrahedra_topomesh.add_wisp(2) for eid in triangle_edge_matching[3*fid:3*fid+3]: tetrahedra_topomesh.link(2,fid,eid) for t in tetrahedra: cid = tetrahedra_topomesh.add_wisp(3) for fid in tetrahedra_triangle_matching[4*cid:4*cid+4]: tetrahedra_topomesh.link(3,cid,fid) tetrahedra_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(tetrahedra_triangles)),keys=np.unique(tetrahedra_triangles)) end_time = time() print "<-- Generating tetrahedra topomesh [",end_time-start_time,"s]" return tetrahedra_topomesh
def dual_topomesh(topomesh,degree=2,vertex_positions='barycenter'): dual_topomesh = PropertyTopomesh(topomesh.degree()) if degree == 2: for d in xrange(3): if d<2: dual_topomesh._regions[d] = deepcopy(topomesh._borders[2-d]) if d>0: dual_topomesh._borders[d] = deepcopy(topomesh._regions[2-d]) dual_topomesh._borders[3] = dict(zip(dual_topomesh._borders[2].keys(),[[w] for w in dual_topomesh._borders[2].keys()])) dual_topomesh._regions[2] = dict(zip(dual_topomesh._borders[2].keys(),[[w] for w in dual_topomesh._borders[2].keys()])) edges_to_remove = [e for e in dual_topomesh.wisps(1) if len(list(dual_topomesh.borders(1,e)))<2] faces_to_remove = [f for f in dual_topomesh.wisps(2) if np.any([e in edges_to_remove for e in dual_topomesh.borders(2,f)])] cells_to_remove = faces_to_remove for e in edges_to_remove: dual_topomesh.remove_wisp(1,e) for f in faces_to_remove: dual_topomesh.remove_wisp(2,f) for c in cells_to_remove: dual_topomesh.remove_wisp(3,c) if 'voronoi' in vertex_positions: assert is_triangular(topomesh) if degree==2: from openalea.cellcomplex.property_topomesh.utils.geometry_tools import triangle_geometric_features compute_topomesh_property(topomesh,'vertices',2) triangles = topomesh.wisp_property('vertices',2).values(list(dual_topomesh.wisps(0))) positions = topomesh.wisp_property('barycenter',0) if vertex_positions == 'projected_voronoi': centers = triangle_geometric_features(triangles,positions,features=['projected_circumscribed_circle_center'])[:,0] else: centers = triangle_geometric_features(triangles,positions,features=['circumscribed_circle_center'])[:,0] dual_positions = array_dict(centers,list(dual_topomesh.wisps(0))) else: compute_topomesh_property(topomesh,'barycenter',degree) dual_positions = array_dict(topomesh.wisp_property('barycenter',degree).values(list(dual_topomesh.wisps(0))),list(dual_topomesh.wisps(0))) dual_topomesh.update_wisp_property('barycenter',0,dual_positions) return dual_topomesh
def poly_topomesh(polys, positions, faces_as_cells=False, **kwargs): polys = np.array(polys) positions = array_dict(positions) poly_lengths = np.array(map(len,polys)) poly_edge_list = [np.transpose([np.arange(l),(np.arange(l)+1)%l]) for l in poly_lengths] edges = array_unique(np.sort(np.concatenate([np.array(p)[l] for p,l in zip(polys,poly_edge_list)],axis=0))) poly_edges = np.sort(np.concatenate([np.array(p)[l] for p,l in zip(polys,poly_edge_list)],axis=0)) start_time = time() print "--> Generating poly topomesh" poly_edge_matching = vq(poly_edges,edges)[0] poly_topomesh = PropertyTopomesh(3) for c in np.unique(polys): poly_topomesh.add_wisp(0,c) for e in edges: eid = poly_topomesh.add_wisp(1) for pid in e: poly_topomesh.link(1,eid,pid) total_poly_length = 0 for q,l in zip(polys,poly_lengths): fid = poly_topomesh.add_wisp(2) for eid in poly_edge_matching[total_poly_length:total_poly_length+l]: poly_topomesh.link(2,fid,eid) total_poly_length += l if not faces_as_cells: poly_topomesh.add_wisp(3,0) for fid in poly_topomesh.wisps(2): poly_topomesh.link(3,0,fid) else: for fid in poly_topomesh.wisps(2): poly_topomesh.add_wisp(3,fid) poly_topomesh.link(3,fid,fid) poly_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(polys)),keys=np.unique(polys)) end_time = time() print "<-- Generating poly topomesh [",end_time-start_time,"s]" return poly_topomesh
def quad_topomesh(quads, positions, faces_as_cells=False, **kwargs): quads = np.array(quads) positions = array_dict(positions) edges = array_unique(np.sort(np.concatenate(quads[:,quad_edge_list],axis=0))) quad_edges = np.sort(np.concatenate(quads[:,quad_edge_list])) start_time = time() print "--> Generating quad topomesh" quad_edge_matching = vq(quad_edges,edges)[0] quad_topomesh = PropertyTopomesh(3) for c in np.unique(quads): quad_topomesh.add_wisp(0,c) for e in edges: eid = quad_topomesh.add_wisp(1) for pid in e: quad_topomesh.link(1,eid,pid) for q in quads: fid = quad_topomesh.add_wisp(2) for eid in quad_edge_matching[4*fid:4*fid+4]: quad_topomesh.link(2,fid,eid) if not faces_as_cells: quad_topomesh.add_wisp(3,0) for fid in quad_topomesh.wisps(2): quad_topomesh.link(3,0,fid) else: for fid in quad_topomesh.wisps(2): quad_topomesh.add_wisp(3,fid) quad_topomesh.link(3,fid,fid) quad_topomesh.update_wisp_property('barycenter',0,positions.values(np.unique(quads)),keys=np.unique(quads)) end_time = time() print "<-- Generating quad topomesh [",end_time-start_time,"s]" return quad_topomesh