Source code for svcco.implicit.sampling
from tqdm import tqdm
from .weingarten_map import *
import numpy as np
[docs]def sampling(points,angle=0,max_local_size=20,min_local_size=10,normals=None,l=0.5,quiet=True):
"""
"""
# want to sample points that have high absolute
# gaussian curvature because the local behavior
# deviates from a parabolic shape thus more
# patches will be needed to better approximate.
curvature,idx,KDT = estimate_gaussian_curvature(points,quiet=quiet)
abs_curvature = abs(curvature)
sorted_abs_curvature_idx = abs_curvature.flatten().argsort().tolist()
patches = []
patch_idx = []
centers = []
total_length = len(sorted_abs_curvature_idx)
dist, idx = KDT.query(points,k=max_local_size+1)
if quiet:
while len(sorted_abs_curvature_idx) > 0:
center = sorted_abs_curvature_idx[0]
count = 0
patch_idxs = []
for k in idx[center,:]:
#if abs(abs_curvature[center] - abs_curvature[k]) > 0.1:
# pass
if np.isclose(np.dot(normals[center],normals[k]),1) and np.all(points[center]==points[k]):
patch_idxs.append(count)
elif np.dot(normals[center],normals[k]) <= angle or abs(abs_curvature[center] - abs_curvature[k]) > 0.2:
if len(patch_idxs) > min_local_size:
break
else:
patch_idxs.append(count)
#if np.dot(normals[center],normals[k]) <= angle or abs(abs_curvature[center] - abs_curvature[k]) > 0.2:#np.all(points[center]==points[k]):
# if len(patch_idxs) > min_local_size:
# break
#else:
# patch_idxs.append(count)
# #pass
count += 1
#limit = count//3
if len(patch_idxs) < round(min_local_size*0.5):
limit = len(patch_idxs)
else:
limit = round(len(patch_idxs)*l)
#if len(patch_idxs) >= min_local_size:
# #if limit == 0:
# # limit += 1
# #if limit >= 1:
# patches.append(points[idx[center,patch_idxs],:])
# patch_idx.append(idx[center,patch_idxs])
# centers.append(center)
# for i in idx[center,patch_idxs]:
# if i in sorted_abs_curvature_idx:
# sorted_abs_curvature_idx.remove(i)
#else:
# #if idx[center,patch_idxs[0]] in sorted_abs_curvature_idx:
# # sorted_abs_curvature_idx.remove(idx[center,patch_idxs[0]])
# sorted_abs_curvature_idx.remove(center)
patches.append(points[idx[center,patch_idxs],:])
patch_idx.append(idx[center,patch_idxs])
centers.append(center)
#print(points[idx[center,patch_idxs],:])
for i in idx[center,patch_idxs[:limit]]:
if i in sorted_abs_curvature_idx:
sorted_abs_curvature_idx.remove(i)
#if limit-1 > 0:
# pbar.update(limit-1)
return patches,patch_idx,KDT,centers
with tqdm(total=total_length,desc='Determining Curvature ') as pbar:
while len(sorted_abs_curvature_idx) > 0:
center = sorted_abs_curvature_idx[0]
count = 0
patch_idxs = []
for k in idx[center,:]:
#if abs(abs_curvature[center] - abs_curvature[k]) > 0.1:
if np.dot(normals[center],normals[k]) <= angle:
if count > min_local_size:
break
else:
patch_idxs.append(count)
#pass
count += 1
#limit = count//3
limit = round(len(patch_idxs)*l)
if len(patch_idxs) >= min_local_size:
#if limit == 0:
# limit += 1
#if limit >= 1:
patches.append(points[idx[center,patch_idxs],:])
patch_idx.append(idx[center,patch_idxs])
centers.append(center)
for i in idx[center,patch_idxs]:
if i in sorted_abs_curvature_idx:
sorted_abs_curvature_idx.remove(i)
pbar.update(1)
else:
#if idx[center,patch_idxs[0]] in sorted_abs_curvature_idx:
# sorted_abs_curvature_idx.remove(idx[center,patch_idxs[0]])
sorted_abs_curvature_idx.remove(center)
pbar.update(1)
#if limit-1 > 0:
# pbar.update(limit-1)
return patches,patch_idx,KDT,centers