WIP: find_region

This commit is contained in:
Michael Krayer 2021-08-11 11:31:02 +02:00
parent 6623c67c86
commit fdbe6fb70b
1 changed files with 63 additions and 26 deletions

View File

@ -771,11 +771,11 @@ class Features3d:
# of the normal has to be chosen which defaults to the z-component and is set by # of the normal has to be chosen which defaults to the z-component and is set by
# 'cellvol_normal_component'. # 'cellvol_normal_component'.
if report: print('[Features3d.triangulate] calculating area and volume per cell...') if report: print('[Features3d.triangulate] calculating area and volume per cell...')
X = points[faces[:,1],:] U = points[faces[:,1],:]
Y = points[faces[:,2],:] V = points[faces[:,2],:]
Z = points[faces[:,3],:] W = points[faces[:,3],:]
cn = np.cross(X-Z,Y-X) cn = np.cross(U-W,V-U)
cc = (X+Y+Z)/3 cc = (U+V+W)/3
area = 0.5*np.sqrt(np.square(cn).sum(axis=1)) area = 0.5*np.sqrt(np.square(cn).sum(axis=1))
vol = 0.5*cn[:,cellvol_normal_component]*cc[:,cellvol_normal_component] vol = 0.5*cn[:,cellvol_normal_component]*cc[:,cellvol_normal_component]
# Now the label is known per cell. We only need to find all cells with the same label # Now the label is known per cell. We only need to find all cells with the same label
@ -784,7 +784,6 @@ class Features3d:
if report: print('[Features3d.triangulate] finalizing internal data...') if report: print('[Features3d.triangulate] finalizing internal data...')
offset = np.zeros((nfeatures+1,),dtype=np.int64) offset = np.zeros((nfeatures+1,),dtype=np.int64)
offset[1:] = np.cumsum(np.bincount(cell_labels)) offset[1:] = np.cumsum(np.bincount(cell_labels))
print(nfeatures,np.bincount(cell_labels),offset)
ind = np.argsort(cell_labels) ind = np.argsort(cell_labels)
self._offset = offset self._offset = offset
self._faces = faces[ind,:] self._faces = faces[ind,:]
@ -797,14 +796,20 @@ class Features3d:
@property @property
def threshold(self): return self._threshold def threshold(self): return self._threshold
@property
def nfeatures(self): return self._nfeatures
@property
def faces(self): return np.split(self._faces,self._offset)
@property @property
def points(self): return self._points def points(self): return self._points
@property @property
def faces(self): return self._faces def cell_areas(self): return np.split(self._cell_areas,self._offset[1:-1])
@property @property
def nfeatures(self): return self._nfeatures def cell_volumes(self): return np.split(self._cell_volumes,self._offset[1:-1])
def fill_holes(self,report=False): def fill_holes(self,report=False):
'''Remove triangulation which is fully enclosed by another. These regions '''Remove triangulation which is fully enclosed by another. These regions
@ -851,18 +856,6 @@ class Features3d:
self.clean_points(report=report) self.clean_points(report=report)
return return
@property
def faces(self): return np.split(self._faces,self._offset)
@property
def points(self): return self._points
@property
def cell_areas(self): return np.split(self._cell_areas,self._offset[1:-1])
@property
def cell_volumes(self): return np.split(self._cell_volumes,self._offset[1:-1])
def area(self,feature): def area(self,feature):
'''Returns the surface area of feature. If feature is None, total surface '''Returns the surface area of feature. If feature is None, total surface
area of all features is returned.''' area of all features is returned.'''
@ -887,12 +880,56 @@ class Features3d:
'''Returns an array with volumes of all features.''' '''Returns an array with volumes of all features.'''
return np.add.reduceat(self._cell_volumes,self._offset[:-1]) return np.add.reduceat(self._cell_volumes,self._offset[:-1])
def find_feature(self,coords): def find_feature(self):
coords = np.array(coords) # coords = np.array(coords)
assert coords.ndim==2 and coords.shape[1]==3, "'coords' need to be provided as 3xN array." # assert coords.ndim==2 and coords.shape[1]==3, "'coords' need to be provided as Nx3 array."
# if method=='binary': from time import time
# idx = np.round() from scipy import spatial
# elif method=='triangulation':
t = time()
xmin = np.amin(self._points[self._faces[:,1:],0],axis=1)
xmax = np.amax(self._points[self._faces[:,1:],0],axis=1)
zmin = np.amin(self._points[self._faces[:,1:],2],axis=1)
zmax = np.amax(self._points[self._faces[:,1:],2],axis=1)
center = np.stack((0.5*(xmax+xmin),0.5*(zmax+zmin)),axis=1)
radius = np.sqrt(2.0)*np.maximum(
np.amax(0.5*(xmax-xmin)),
np.amax(0.5*(zmax-zmin)))
print('Preparation for KD tree in',time()-t)
t = time()
kd = spatial.KDTree(center,leafsize=100,compact_nodes=False,copy_data=False,balanced_tree=False)
# kd = spatial.KDTree(center,leafsize=10,compact_nodes=True,copy_data=False,balanced_tree=True)
# kd = spatial.KDTree(self.points[:,1:],leafsize=20,compact_nodes=False,copy_data=False,balanced_tree=False)
# kd = spatial.KDTree(self._points[:,1:],leafsize=10,compact_nodes=True,copy_data=False,balanced_tree=True)
print('KD tree built in',time()-t)
query = np.random.random((10000,2))
# t = time()
# map_ = self._points.shape[0]*[[]]
# for ii,face in enumerate(self._faces[:,1:].ravel()):
# map_[face].append(ii)
# faces_connected_to_vertex = {}
# for face_index,face in enumerate(self._faces[:,1:]):
# for vertex_index in face:
# faces_connected_to_vertex.setdefault(vertex_index,[]).append(face_index)
# print('Inverted cells-faces',time()-t)
radius = np.sqrt(np.sum(self.spacing[1:]**2))
t = time()
kd.query_ball_point(query,radius)
print('KD tree query',time()-t)
# print(radius)
# print(len(kd.query_ball_point((0.5,0.0),radius,return_sorted=True)),self._points.shape[0])
# yset = set(x.data for x in sorted(treey.at(0.0)))
# zset = set(x.data for x in sorted(treez.at(0.0)))
return return
def clean_points(self,report=False): def clean_points(self,report=False):