Source code for cellcomplex.property_topomesh.extraction

# -*- coding: utf-8 -*-
# -*- python -*-
#
#       PropertyTopomesh
#
#       Copyright 2014-2016 INRIA - CIRAD - INRA
#
#       File author(s): Guillaume Cerutti <guillaume.cerutti@inria.fr>
#
#       File contributor(s): Guillaume Cerutti <guillaume.cerutti@inria.fr>
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
#       OpenaleaLab Website : http://virtualplants.github.io/
#
###############################################################################

import numpy as np

from copy import deepcopy

from cellcomplex.utils import array_dict
from cellcomplex.utils import IdDict

from cellcomplex.property_topomesh import PropertyTopomesh
from cellcomplex.property_topomesh.analysis import compute_topomesh_property, is_triangular

from cellcomplex.property_topomesh.utils.geometry_tools import triangle_geometric_features


[docs]def property_filtering_sub_topomesh(input_topomesh, property_name, degree, filter_range): """ """ topomesh = deepcopy(input_topomesh) # assert topomesh.has_wisp_property(property_name,degree,is_computed=True) element_property = topomesh.wisp_property(property_name,degree) elements_to_remove = [w for w in topomesh.wisps(degree) if (element_property[w]<filter_range[0]) or (element_property[w]>filter_range[1])] for w in elements_to_remove: topomesh.remove_wisp(degree,w) if degree<1: edges_to_remove = [e for e in topomesh.wisps(1) if topomesh.nb_borders(1,e) < 2] for e in edges_to_remove: topomesh.remove_wisp(1,e) if degree<2: faces_to_remove = [f for f in topomesh.wisps(2) if topomesh.nb_borders(2,f) < 3] for f in faces_to_remove: topomesh.remove_wisp(2,f) return clean_topomesh(topomesh, clean_properties=True)
[docs]def epidermis_topomesh(topomesh,cells=None): compute_topomesh_property(topomesh,'epidermis',3) compute_topomesh_property(topomesh,'epidermis',2) compute_topomesh_property(topomesh,'epidermis',1) compute_topomesh_property(topomesh,'epidermis',0) if cells is None: epidermis_topomesh = deepcopy(topomesh) else: faces = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(3,c))) for c in cells])),int) edges = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(2,t))) for t in faces])),int) vertices = np.array(np.unique(np.concatenate([np.array(list(topomesh.borders(1,e))) for e in edges])),int) epidermis_topomesh = PropertyTopomesh(3) vertices_to_pids = {} for v in vertices: pid = epidermis_topomesh.add_wisp(0,v) vertices_to_pids[v] = pid edges_to_eids = {} for e in edges: eid = epidermis_topomesh.add_wisp(1,e) edges_to_eids[e] = eid for v in topomesh.borders(1,e): epidermis_topomesh.link(1,eid,vertices_to_pids[v]) faces_to_fids = {} for f in faces: fid = epidermis_topomesh.add_wisp(2,f) faces_to_fids[f] = fid for e in topomesh.borders(2,f): epidermis_topomesh.link(2,fid,edges_to_eids[e]) for c in cells: cid = epidermis_topomesh.add_wisp(3,c) for f in topomesh.borders(3,c): epidermis_topomesh.link(3,cid,faces_to_fids[f]) vertices_to_remove = [] for v in epidermis_topomesh.wisps(0): if not topomesh.wisp_property('epidermis',0)[v]: vertices_to_remove.append(v) for v in vertices_to_remove: epidermis_topomesh.remove_wisp(0,v) edges_to_remove = [] for e in epidermis_topomesh.wisps(1): if not topomesh.wisp_property('epidermis',1)[e]: edges_to_remove.append(e) for e in edges_to_remove: epidermis_topomesh.remove_wisp(1,e) faces_to_remove = [] for f in epidermis_topomesh.wisps(2): if not topomesh.wisp_property('epidermis',2)[f]: faces_to_remove.append(f) for f in faces_to_remove: epidermis_topomesh.remove_wisp(2,f) cells_to_remove = [] for c in epidermis_topomesh.wisps(3): if not topomesh.wisp_property('epidermis',3)[c]: cells_to_remove.append(c) for c in cells_to_remove: epidermis_topomesh.remove_wisp(3,c) epidermis_topomesh.update_wisp_property('barycenter',0,topomesh.wisp_property('barycenter',0).values(list(epidermis_topomesh.wisps(0))),keys=np.array(list(epidermis_topomesh.wisps(0)))) return epidermis_topomesh
[docs]def cut_surface_topomesh(input_topomesh, z_cut=0, z_offset=None, below=True): topomesh = deepcopy(input_topomesh) compute_topomesh_property(topomesh,'vertices',2) if below: triangle_below = array_dict(np.all(topomesh.wisp_property('barycenter',0).values(topomesh.wisp_property('vertices',2).values())[...,2] <= z_cut,axis=1),list(topomesh.wisps(2))) else: triangle_below = array_dict(np.all(topomesh.wisp_property('barycenter',0).values(topomesh.wisp_property('vertices',2).values())[...,2] >= z_cut,axis=1),list(topomesh.wisps(2))) topomesh.update_wisp_property('below',2,triangle_below) triangles_to_remove = [t for t in topomesh.wisps(2) if triangle_below[t]] for t in triangles_to_remove: topomesh.remove_wisp(2,t) topomesh = clean_topomesh(topomesh) compute_topomesh_property(topomesh,'faces',1) compute_topomesh_property(topomesh,'vertices',1) compute_topomesh_property(topomesh,'length',1) topomesh.update_wisp_property('boundary',1,array_dict((np.array(list(map(len,topomesh.wisp_property('faces',1).values())))==1).astype(int),list(topomesh.wisps(1)))) boundary_edges = np.array(list(topomesh.wisps(1)))[topomesh.wisp_property('boundary',1).values()==1] boundary_vertices = np.unique(topomesh.wisp_property('vertices',1).values(boundary_edges)) if z_offset is None: # z_offset = topomesh.wisp_property('barycenter',0).values()[:,2].std()/8. z_offset = np.percentile(topomesh.wisp_property('length',1).values(),10) iso_z_positions = np.array([np.concatenate([topomesh.wisp_property('barycenter',0)[v][:2],[z_cut+(1-2*below)*z_offset]]) if v in boundary_vertices else topomesh.wisp_property('barycenter',0)[v] for v in topomesh.wisps(0)]) topomesh.update_wisp_property('barycenter',0,array_dict(iso_z_positions,list(topomesh.wisps(0)))) clean_topomesh_properties(topomesh) return topomesh
[docs]def clean_topomesh(input_topomesh, clean_properties=False, degree=2): topomesh = deepcopy(input_topomesh) cells_to_remove = [w for w in topomesh.wisps(3) if topomesh.nb_borders(3,w)==0] for w in cells_to_remove: topomesh.remove_wisp(3,w) if degree > 2: triangles_to_remove = [w for w in topomesh.wisps(2) if topomesh.nb_regions(2,w)==0] for w in triangles_to_remove: topomesh.remove_wisp(2,w) edges_to_remove = [w for w in topomesh.wisps(1) if topomesh.nb_regions(1,w)==0] for w in edges_to_remove: topomesh.remove_wisp(1,w) vertices_to_remove = [w for w in topomesh.wisps(0) if topomesh.nb_regions(0,w)==0] for w in vertices_to_remove: topomesh.remove_wisp(0,w) if clean_properties: clean_topomesh_properties(topomesh) return topomesh
[docs]def contiguous_wisps_topomesh(input_topomesh): topomesh = deepcopy(input_topomesh) wisp_conversion = {} for degree in range(topomesh.degree()+1): old_wisps = np.array(list(topomesh.wisps(degree))) new_wisps = np.arange(topomesh.nb_wisps(degree)) wisp_conversion[degree] = array_dict(dict(list(zip(old_wisps,new_wisps)))) for degree in range(topomesh.degree()+1): old_wisps = np.array(list(topomesh.wisps(degree))) new_wisps = np.arange(topomesh.nb_wisps(degree)) if degree>0: new_borders = dict(list(zip(new_wisps,[list(wisp_conversion[degree-1].values(topomesh._borders[degree][o_w])) for o_w in old_wisps]))) topomesh._borders[degree] = IdDict(new_borders) if degree<topomesh.degree(): new_regions = dict(list(zip(new_wisps,[list(wisp_conversion[degree+1].values(topomesh._regions[degree][o_w])) for o_w in old_wisps]))) if degree == 0: topomesh._regions[degree] = IdDict(new_regions) else: topomesh._regions[degree] = new_regions for property_name in topomesh._wisp_properties[degree].keys(): topomesh._wisp_properties[degree][property_name] = array_dict(topomesh._wisp_properties[degree][property_name].values(old_wisps),keys=new_wisps) return topomesh
[docs]def clean_topomesh_properties(topomesh): for degree in range(topomesh.degree()+1): for property_name in topomesh.wisp_property_names(degree): if np.all([topomesh.wisp_property(property_name,degree).has_key(w) for w in topomesh.wisps(degree)]): topomesh.update_wisp_property(property_name,degree,dict(zip(list(topomesh.wisps(degree)),topomesh.wisp_property(property_name,degree).values(list(topomesh.wisps(degree))))))
[docs]def cell_topomesh(input_topomesh, cells=None, copy_properties=False, preserve_ids=True): from time import time start_time = time() #topomesh = PropertyTopomesh(topomesh=input_topomesh) topomesh = PropertyTopomesh(3) if cells is None: cells = set(input_topomesh.wisps(3)) else: cells = set(cells).intersection(set(input_topomesh.wisps(3))) wisp_index = {} wisp_index[3] = dict(zip(cells,range(len(cells)))) faces = set() for c in cells: faces = faces.union(set(input_topomesh._borders[3][c])) wisp_index[2] = dict(zip(faces,range(len(faces)))) edges = set() for f in faces: edges = edges.union(set(input_topomesh._borders[2][f])) wisp_index[1] = dict(zip(edges,range(len(edges)))) vertices = set() for e in edges: vertices = vertices.union(set(input_topomesh._borders[1][e])) wisp_index[0] = dict(zip(vertices,range(len(vertices)))) for c in cells: if preserve_ids: topomesh._borders[3][c] = deepcopy(input_topomesh._borders[3][c]) else: topomesh._borders[3][wisp_index[3][c]] = [wisp_index[2][f] for f in input_topomesh._borders[3][c]] for f in faces: if preserve_ids: topomesh._borders[2][f] = deepcopy(input_topomesh._borders[2][f]) topomesh._regions[2][f] = deepcopy(list(set(input_topomesh._regions[2][f]).intersection(cells))) else: topomesh._borders[2][wisp_index[2][f]] = [wisp_index[1][e] for e in input_topomesh._borders[2][f]] topomesh._regions[2][wisp_index[2][f]] = [wisp_index[3][c] for c in input_topomesh._regions[2][f] if c in cells] for e in edges: if preserve_ids: topomesh._borders[1][e] = deepcopy(input_topomesh._borders[1][e]) topomesh._regions[1][e] = deepcopy(list(set(input_topomesh._regions[1][e]).intersection(faces))) else: topomesh._borders[1][wisp_index[1][e]] = [wisp_index[0][v] for v in input_topomesh._borders[1][e]] topomesh._regions[1][wisp_index[1][e]] = [wisp_index[2][f] for f in input_topomesh._regions[1][e] if f in faces] for v in vertices: if preserve_ids: topomesh._regions[0][v] = deepcopy(list(set(input_topomesh._regions[0][v]).intersection(edges))) else: topomesh._regions[0][wisp_index[0][v]] = [wisp_index[1][e] for e in input_topomesh._regions[0][v] if e in edges] if copy_properties: for degree in range(4): for property_name in input_topomesh.wisp_property_names(degree): input_property = input_topomesh.wisp_property(property_name,degree) property_keys = np.intersect1d(input_property.keys(),list(wisp_index[degree].keys())) if len(property_keys)>0: if preserve_ids: topomesh.update_wisp_property(property_name,degree,array_dict(input_topomesh.wisp_property(property_name,degree).values(property_keys),property_keys)) else: property_key_indices = [wisp_index[degree][w] for w in property_keys] topomesh.update_wisp_property(property_name,degree,array_dict(input_topomesh.wisp_property(property_name,degree).values(property_keys),property_key_indices)) if preserve_ids: topomesh.update_wisp_property('barycenter',0,array_dict(input_topomesh.wisp_property('barycenter',0).values(list(vertices)),list(vertices))) else: topomesh.update_wisp_property('barycenter', 0,array_dict(input_topomesh.wisp_property('barycenter', 0).values(list(vertices)), [wisp_index[0][v] for v in vertices])) # cells_to_remove = [c for c in topomesh.wisps(3) if not c in cells] # cells_to_remove = list(set(topomesh.wisps(3)).difference(set(cells))) # for c in cells_to_remove: # topomesh.remove_wisp(3,c) # faces_to_remove = [w for w in topomesh.wisps(2) if topomesh.nb_regions(2,w)==0] # for w in faces_to_remove: # topomesh.remove_wisp(2,w) # edges_to_remove = [w for w in topomesh.wisps(1) if topomesh.nb_regions(1,w)==0] # for w in edges_to_remove: # topomesh.remove_wisp(1,w) # vertices_to_remove = [w for w in topomesh.wisps(0) if topomesh.nb_regions(0,w)==0] # for w in vertices_to_remove: # topomesh.remove_wisp(0,w) end_time = time() print("<-- Extracting cell topomesh [",end_time-start_time,"s]") return topomesh
[docs]def star_interface_topomesh(topomesh, inner_faces=True, verbose=False): from time import time triangle_edge_list = np.array([[1, 2],[0, 2],[0, 1]]) triangular_topomesh = PropertyTopomesh(3) triangle_vertex_positions = {} for v in topomesh.wisps(0): triangular_topomesh.add_wisp(0,v) triangle_vertex_positions[v] = topomesh.wisp_property('barycenter',0)[v] for e in topomesh.wisps(1): triangular_topomesh.add_wisp(1,e) for v in topomesh.borders(1,e): triangular_topomesh.link(1,e,v) for c in topomesh.wisps(3): triangular_topomesh.add_wisp(3,c) compute_topomesh_property(topomesh,'regions',2) compute_topomesh_property(topomesh,'edges',2) compute_topomesh_property(topomesh,'vertices',1) compute_topomesh_property(topomesh,'vertices',2) face_centers = {} face_triangles = {} start_time = time() print("--> Triangulating Faces") for face in topomesh.wisps(2): if face%1 == 0: face_start_time = time() if topomesh.nb_borders(2,face)>0: face_cells = topomesh.wisp_property('regions',2)[face] face_edges = topomesh.wisp_property('vertices',1).values(topomesh.wisp_property('edges',2)[face]) face_vertices = np.unique(face_edges) print(face_vertices) if (len(face_vertices)>3) and (inner_faces or (len(face_cells) == 1)): face_positions = array_dict(topomesh.wisp_property('barycenter',0).values(face_vertices),face_vertices) face_center = face_positions.values().mean(axis=0) center_pid = triangular_topomesh.add_wisp(0) triangle_vertex_positions[center_pid] = face_center face_centers[face] = center_pid face_triangles[face] = [] vertex_center_edges = {} for v in face_vertices: eid = triangular_topomesh.add_wisp(1) triangular_topomesh.link(1,eid,v) triangular_topomesh.link(1,eid,center_pid) vertex_center_edges[v] = eid for e in topomesh.borders(2,face): fid = triangular_topomesh.add_wisp(2) face_triangles[face] += [fid] triangular_topomesh.link(2,fid,e) for v in topomesh.borders(1,e): triangular_topomesh.link(2,fid,vertex_center_edges[v]) for cid in face_cells: triangular_topomesh.link(3,cid,fid) elif (len(face_vertices)>2) and (inner_faces or (len(face_cells) == 1)): fid = triangular_topomesh.add_wisp(2) for e in topomesh.borders(2,face): face_triangles[face] = [fid] triangular_topomesh.link(2,fid,e) for cid in face_cells: triangular_topomesh.link(3,cid,fid) if verbose: if face%1 == 0: face_end_time = time() # print " --> Face ",face," / ",topomesh.nb_wisps(2),' ',face_cells,' [',face_end_time-face_start_time,'s]' print(" --> Face ",face," / ",topomesh.nb_wisps(2),' [',(face_end_time-face_start_time),'s]') end_time = time() # for property_name in topomesh.wisp_property_names(0): # try: # center_property = [topomesh.wisp_property(property_name,0).values(topomesh.wisp_property('vertices',2)[f]).mean(axis=0) for f in face_centers.keys()] # except: # center_property = [topomesh.wisp_property(property_name,0).values(topomesh.wisp_property('vertices',2)[f])[0] for f in face_centers.keys()] # vertex_property = array_dict(list(topomesh.wisp_property(property_name,0).values(list(topomesh.wisps(0))))+center_property,list(topomesh.wisps(0))+[face_centers[f] for f in face_centers.keys()]) # triangular_topomesh.update_wisp_property(property_name,0,vertex_property) for property_name in topomesh.wisp_property_names(2): triangle_faces = np.concatenate([[f for t in face_triangles[f]] for f in face_triangles.keys()]) triangle_keys = np.concatenate([face_triangles[f] for f in face_triangles.keys()]) triangle_property = array_dict(topomesh.wisp_property(property_name,2).values(triangle_faces),triangle_keys) triangular_topomesh.update_wisp_property(property_name,2,triangle_property) for property_name in topomesh.wisp_property_names(3): triangular_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,3)) print("--> Triangulating Faces [",end_time-start_time,"s]") triangular_topomesh.update_wisp_property('barycenter',degree=0,values=triangle_vertex_positions) return triangular_topomesh
[docs]def surface_dual_topomesh(topomesh, vertex_placement='center', exterior_vertex=None, exterior_distance=0, face_positions=None, vertices_as_cells=None): if vertices_as_cells is None: vertices_as_cells = topomesh.nb_wisps(3) != 1 dual_topomesh = PropertyTopomesh(3) for f in topomesh.wisps(2): dual_topomesh.add_wisp(0,f) for e in topomesh.wisps(1): dual_topomesh.add_wisp(1,e) for f in topomesh.regions(1,e): dual_topomesh.link(1,e,f) for v in topomesh.wisps(0): if v != exterior_vertex: dual_topomesh.add_wisp(2,v) for e in topomesh.regions(0,v): dual_topomesh.link(2,v,e) if vertices_as_cells: dual_topomesh.add_wisp(3,v) dual_topomesh.link(3,v,v) else: for c in topomesh.regions(0,v,3): if not dual_topomesh.has_wisp(3,c): dual_topomesh.add_wisp(3,c) dual_topomesh.link(3,c,v) for degree in [0,1,2]: for property_name in topomesh.wisp_property_names(degree): dual_topomesh.update_wisp_property(property_name,2-degree,topomesh.wisp_property(property_name,degree)) if vertices_as_cells: for property_name in topomesh.wisp_property_names(0): dual_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,0)) else: for property_name in topomesh.wisp_property_names(3): dual_topomesh.update_wisp_property(property_name,3,topomesh.wisp_property(property_name,3)) compute_topomesh_property(topomesh,'barycenter',2) face_centers = topomesh.wisp_property('barycenter',2) positions = topomesh.wisp_property('barycenter',0) if is_triangular(topomesh): compute_topomesh_property(topomesh,'vertices',2) triangle_ids = np.array(list(topomesh.wisps(2))) triangles = topomesh.wisp_property('vertices',2).values(triangle_ids) if exterior_vertex is not None: exterior_triangle_ids = triangle_ids[np.where(np.any(triangles==exterior_vertex,axis=1))] exterior_triangles = triangles[np.where(np.any(triangles==exterior_vertex,axis=1))] exterior_edges = [t[t!=exterior_vertex] for t in exterior_triangles] exterior_edge_ids = np.concatenate([[e for e in topomesh.borders(2,t) if not exterior_vertex in topomesh.borders(1,e)] for t in exterior_triangle_ids]) exterior_edge_triangle_ids = np.concatenate([[t for t in topomesh.regions(1,e) if not exterior_vertex in topomesh.borders(2,t,2)] for e in exterior_edge_ids]) triangle_ids = triangle_ids[np.where(np.all(triangles!=exterior_vertex,axis=1))] triangles = triangles[np.where(np.all(triangles!=exterior_vertex,axis=1))] else: exterior_triangles = [] exterior_triangle_ids = [] exterior_edges = [] exterior_edge_triangle_ids = [] exterior_centers = [] if vertex_placement == 'voronoi': centers = triangle_geometric_features(triangles,positions,['circumscribed_circle_center'])[:,0] elif vertex_placement == 'projected_voronoi': centers = triangle_geometric_features(triangles,positions,['projected_circumscribed_circle_center'])[:,0] elif vertex_placement == 'center': centers = triangle_geometric_features(triangles,positions,['barycenter'])[:,0] if exterior_vertex is not None: exterior_edge_centers = positions.values(exterior_edges).mean(axis=1) exterior_face_centers = face_centers.values(exterior_edge_triangle_ids.astype(int)) exterior_face_dual_centers = array_dict(centers,triangle_ids).values(exterior_edge_triangle_ids.astype(int)) exterior_edge_vectors = np.sign(np.einsum("...ij,...ij->...i",exterior_face_centers-exterior_edge_centers,exterior_face_dual_centers-exterior_edge_centers))[:,np.newaxis]*(exterior_edge_centers-exterior_face_dual_centers) print(exterior_edge_vectors) exterior_edge_vectors = exterior_edge_vectors/np.linalg.norm(exterior_edge_vectors,axis=1)[:,np.newaxis] exterior_dual_distance = np.linalg.norm(exterior_face_dual_centers-exterior_edge_centers,axis=1) #exterior_centers = face_centers.values(exterior_edge_triangle_ids) + exterior_coef*(positions.values(exterior_edges).mean(axis=1)-face_centers.values(exterior_edge_triangle_ids)) exterior_centers = exterior_face_dual_centers + np.maximum(exterior_distance-exterior_dual_distance,0)[:,np.newaxis]*exterior_edge_vectors # print list(triangle_ids),list(exterior_triangle_ids) # print list(topomesh.wisps(2)) dual_topomesh.update_wisp_property('barycenter',0,array_dict(list(centers)+list(exterior_centers),list(triangle_ids)+list(exterior_triangle_ids))) else: dual_topomesh.update_wisp_property('barycenter',0,face_centers) edges_to_remove = [e for e in dual_topomesh.wisps(1) if dual_topomesh.nb_borders(1,e) != 2] for e in edges_to_remove: dual_topomesh.remove_wisp(1,e) return clean_topomesh(dual_topomesh)
[docs]def triangulation_add_exterior(triangulation_topomesh): assert is_triangular(triangulation_topomesh) # print np.min(list(triangulation_topomesh.wisps(0))) positions = triangulation_topomesh.wisp_property('barycenter',0) if not triangulation_topomesh.has_wisp(0,1): exterior_vertex = triangulation_topomesh.add_wisp(0,1) else: exterior_vertex = triangulation_topomesh.add_wisp(0,np.max(list(triangulation_topomesh.wisps(0)))+1) positions[exterior_vertex] = np.zeros(3) boundary_edges = [e for e in triangulation_topomesh.wisps(1) if triangulation_topomesh.nb_regions(1,e)==1] boundary_vertices = np.unique([list(triangulation_topomesh.borders(1,e)) for e in boundary_edges]) exterior_edges = {} for v in boundary_vertices: e = triangulation_topomesh.add_wisp(1) triangulation_topomesh.link(1,e,v) triangulation_topomesh.link(1,e,exterior_vertex) exterior_edges[v] = e for e in boundary_edges: t = triangulation_topomesh.add_wisp(2) for v in triangulation_topomesh.borders(1,e): triangulation_topomesh.link(2,t,exterior_edges[v]) triangulation_topomesh.link(2,t,e) triangulation_topomesh.update_wisp_property('barycenter',0,positions) compute_topomesh_property(triangulation_topomesh,'faces',0) compute_topomesh_property(triangulation_topomesh,'vertices',1) compute_topomesh_property(triangulation_topomesh,'regions',1) compute_topomesh_property(triangulation_topomesh,'faces',1) compute_topomesh_property(triangulation_topomesh,'cells',1) compute_topomesh_property(triangulation_topomesh,'vertices',2) compute_topomesh_property(triangulation_topomesh,'cells',2) compute_topomesh_property(triangulation_topomesh,'regions',2) compute_topomesh_property(triangulation_topomesh,'vertices',3) compute_topomesh_property(triangulation_topomesh,'edges',3) compute_topomesh_property(triangulation_topomesh,'faces',3) compute_topomesh_property(triangulation_topomesh,'vertices',3) compute_topomesh_property(triangulation_topomesh,'epidermis',2) return exterior_vertex
[docs]def triangulation_remove_exterior(triangulation_topomesh, exterior_vertex=1): assert is_triangular(triangulation_topomesh) triangles_to_remove = [] for t in triangulation_topomesh.wisps(2): if exterior_vertex in triangulation_topomesh.borders(2,t,2): triangles_to_remove.append(t) edges_to_remove = [] for e in triangulation_topomesh.wisps(1): if exterior_vertex in triangulation_topomesh.borders(1,e): edges_to_remove.append(e) triangulation_topomesh.remove_wisp(0,exterior_vertex) for e in edges_to_remove: triangulation_topomesh.remove_wisp(1,e) for t in triangles_to_remove: triangulation_topomesh.remove_wisp(2,t) triangulation_topomesh.update_wisp_property('barycenter',0,triangulation_topomesh.wisp_property('barycenter',0).values(list(triangulation_topomesh.wisps(0))),list(triangulation_topomesh.wisps(0))) compute_topomesh_property(triangulation_topomesh,'faces',0) compute_topomesh_property(triangulation_topomesh,'vertices',1) compute_topomesh_property(triangulation_topomesh,'regions',1) compute_topomesh_property(triangulation_topomesh,'faces',1) compute_topomesh_property(triangulation_topomesh,'cells',1) compute_topomesh_property(triangulation_topomesh,'vertices',2) compute_topomesh_property(triangulation_topomesh,'cells',2) compute_topomesh_property(triangulation_topomesh,'regions',2) compute_topomesh_property(triangulation_topomesh,'vertices',3) compute_topomesh_property(triangulation_topomesh,'edges',3) compute_topomesh_property(triangulation_topomesh,'faces',3) compute_topomesh_property(triangulation_topomesh,'vertices',3) compute_topomesh_property(triangulation_topomesh,'epidermis',2)
[docs]def topomesh_connected_components(topomesh,degree=2): if topomesh.nb_wisps(3)>0: new_component = np.max(list(topomesh.wisps(3)))+1 else: new_component = 0 considered_fids = set() component_cells = [] for fid in topomesh.wisps(2): if not fid in considered_fids: c = new_component topomesh.add_wisp(3,c) topomesh.link(3,c,fid) considered_fids |= {fid} neighbor_fids = list(topomesh.border_neighbors(2,fid)) while(len(neighbor_fids) > 0): n_fid = neighbor_fids.pop() if not n_fid in considered_fids: topomesh.link(3,c,n_fid) considered_fids |= {n_fid} neighbor_fids += list(set(list(topomesh.border_neighbors(2,n_fid))).difference(considered_fids)) component_cells += [c] new_component += 1 component_meshes = [cell_topomesh(topomesh,cells=[c],copy_properties=True) for c in component_cells] component_size = [component.nb_wisps(2) for component in component_meshes] for c in component_cells: topomesh.remove_wisp(3,c) return [component_meshes[i] for i in np.argsort(component_size)][::-1]