def calc_curvatures(self, max_radius: int = 5, min_radius: int = 2) -> np.ndarray: """ Calculating Principal and Gaussian curvature features of each mesh face Parameters: vertices: np.ndarray - (x, y, z) coordinates of the mesh vertices faces: np.ndarray - indices of the mesh vertices forming faces areas: np.ndarray - surface areas of the mesh faces max_radius: int - controls the size of the neighbourhood used min_radius: int - minimum value of radius used in calculation of principal curvatures Returns: curvatures: np.ndarray - curvature statistics """ curvatures = [] for radius in range(min_radius, min_radius + max_radius): pd1, pd2, pv1, pv2 = igl.principal_curvature(v=self.vertices, f=self.faces, radius=radius, use_k_ring=True) pv1 = pv1[self.faces] pv2 = pv2[self.faces] curv_vals = [ pv1.mean(axis=1), np.abs(pv1).mean(axis=1), pv2.mean(axis=1), np.abs(pv2).mean(axis=1), (pv1 * pv2).mean(axis=1), np.abs(pv1 * pv2).mean(axis=1), ((pv1 + pv2) / 2).mean(axis=1), np.abs((pv1 + pv2) / 2).mean(axis=1), (pv1 - pv2).mean(axis=1) ] curv_vals = np.swapaxes(curv_vals, 0, 1) curv_dirs = [ pd1[self.faces].mean(axis=1), pd2[self.faces].mean(axis=1) ] curv_dirs = np.hstack(curv_dirs) curvatures.append(np.hstack((curv_vals, curv_dirs))) curvatures = np.hstack(curvatures) gauss_curv = igl.gaussian_curvature(self.vertices, self.faces) gauss_curv = np.expand_dims(gauss_curv[self.faces].mean(axis=1), axis=1) return np.hstack((curvatures, gauss_curv)) * self.areas[:, None]
def run(self): if not self.copyData(): return if self.geo.getNumFaces() == 0 or self.geo.getNumVertexes() == 0: return mesh = self.geo.getTriangulateMesh() r = igl.gaussian_curvature(mesh.points(), mesh.face_vertex_indices()) s = self.get_property("Scale") self.geo.setVertexAttribData(self.get_property("Attribute Name"), r * s, attribType='float', defaultValue=0.0)
def sample_verts_from_mesh(self, verts, faces): """ Sample verts from mesh. Vertices with higher curvature get higher weight. """ curvature = igl.gaussian_curvature(verts, faces) # clip values q95 = np.quantile(curvature, 0.95) curvature[np.isnan(curvature)] = q95 mask = np.abs(curvature) > q95 curvature[mask] = np.sign(curvature[mask]) * q95 # Compute weights/ probabilities p = np.abs(curvature) p /= np.sum(p) verts_choice = np.random.choice(np.arange(verts.shape[0]), self.params.n_sample_pts, replace=False, p=p) return verts_choice, p
def test_gaussian_curvature(self): g = igl.gaussian_curvature(self.v, self.f) self.assertTrue(g.shape == (self.v.shape[0],)) self.assertTrue(g.dtype == self.v.dtype) self.assertTrue(type(g) == np.ndarray) self.assertTrue(g.flags.c_contiguous)
# Add the igl library to the modules search path import sys, os sys.path.insert(0, os.getcwd() + "/../") import igl # Load mesh V = igl.eigen.MatrixXd() F = igl.eigen.MatrixXi() igl.readOFF("../../tutorial/shared/bumpy.off",V,F); # Compute Gaussian curvature K = igl.eigen.MatrixXd(); igl.gaussian_curvature(V,F,K); # Compute pseudocolor C = igl.eigen.MatrixXd(); igl.jet(K,True,C); # Plot the mesh with pseudocolors viewer = igl.viewer.Viewer() viewer.data.set_mesh(V, F) viewer.data.set_colors(C) viewer.launch()