Ejemplo n.º 1
0
def getMeshCurvature(mesh, gaussian_curvature=True, mean_curvature=True, shape_index=True, remove_outliers=True):
    try:
        import igl
    except ModuleNotFoundError:
        raise ModuleNotFoundError("The dependency 'igl' is required for this functionality!")
    
    v1, v2, k1, k2 = igl.principal_curvature(mesh.vertices, mesh.faces)
    
    k1 = clipOutliers(k1)
    k2 = clipOutliers(k2)
    
    feature_names = []
    features = []
    if gaussian_curvature:
        feature_names.append('gaussian_curvature')
        mesh.vertex_attributes['gaussian_curvature'] = k1*k2
    
    if mean_curvature:
        feature_names.append('mean_curvature')
        mesh.vertex_attributes['mean_curvature'] = (k1 + k2)/2
    
    if shape_index:
        shape_index = -2*np.arctan( (k1 + k2)/(k1 - k2) )/np.pi
        feature_names.append('shape_index')
        mesh.vertex_attributes['shape_index'] = shape_index
    
    return feature_names
Ejemplo n.º 2
0
 def test_principal_curvature(self):
     pd1, pd2, pv1, pv2 = igl.principal_curvature(self.v, self.f)
     qd1, qd2, qv1, qv2 = igl.principal_curvature(self.v, self.f, radius=7, use_k_ring=False)
     self.assertTrue(pd1.shape == qd1.shape == pd2.shape == qd2.shape == self.v.shape)
     self.assertTrue(pv1.shape == qv1.shape == pv2.shape == qv2.shape == (self.v.shape[0],))
     self.assertTrue(pd1.dtype == pd2.dtype == pv1.dtype == pv2.dtype == np.float64)
     v = self.v.copy()
     #v = v.astype(np.float32)
     pd1, pd2, pv1, pv2 = igl.principal_curvature(v, self.f)
     #self.assertTrue(pd1.dtype == pd2.dtype == pv1.dtype == pv2.dtype == np.float32)
     self.assertTrue(type(pd1) == type(pd2) == type(pv1) == type(pv2) == np.ndarray)
     self.assertTrue(pd1.flags.c_contiguous)
     self.assertTrue(pd2.flags.c_contiguous)
     self.assertTrue(pv1.flags.c_contiguous)
     self.assertTrue(pv2.flags.c_contiguous)
     self.assertTrue(qd1.flags.c_contiguous)
     self.assertTrue(qd2.flags.c_contiguous)
     self.assertTrue(qv1.flags.c_contiguous)
     self.assertTrue(qv2.flags.c_contiguous)
Ejemplo n.º 3
0
    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]
Ejemplo n.º 4
0
def getMeshCurvature(mesh, gaussian_curvature=True, mean_curvature=True, shape_index=True, remove_outliers=True):
    
    v1, v2, k1, k2 = igl.principal_curvature(mesh.vertices, mesh.faces)
    
    k1 = clipOutliers(k1)
    k2 = clipOutliers(k2)
    
    feature_names = []
    features = []
    if gaussian_curvature:
        feature_names.append('gaussian_curvature')
        mesh.vertex_attributes['gaussian_curvature'] = k1*k2
    
    if mean_curvature:
        feature_names.append('mean_curvature')
        mesh.vertex_attributes['mean_curvature'] = (k1 + k2)/2
    
    if shape_index:
        shape_index = -2*np.arctan( (k1 + k2)/(k1 - k2) )/np.pi
        feature_names.append('shape_index')
        mesh.vertex_attributes['shape_index'] = shape_index
    
    return feature_names
Ejemplo n.º 5
0
igl.invert_diag(M, Minv)

# Laplace-Beltrami of position
HN = -Minv * (L * V)

# Extract magnitude as mean curvature
H = HN.rowwiseNorm()

# Compute curvature directions via quadric fitting
PD1 = igl.eigen.MatrixXd()
PD2 = igl.eigen.MatrixXd()

PV1 = igl.eigen.MatrixXd()
PV2 = igl.eigen.MatrixXd()

igl.principal_curvature(V, F, PD1, PD2, PV1, PV2)

# Mean curvature
H = 0.5 * (PV1 + PV2)

viewer = igl.viewer.Viewer()
viewer.data.set_mesh(V, F)

# Compute pseudocolor
C = igl.eigen.MatrixXd()
igl.parula(H, True, C)

viewer.data.set_colors(C)

# Average edge length for sizing
avg = igl.avg_edge_length(V, F)
# 1. Install miniconda (python 3.7 version, windows 64 bits)
# 2. In a miniconda terminal run conda install igl
# 3. Swap to this python compiler in pycharm

import igl
import numpy as np
import os

#Change this to point to your subject folder
root_folder = '.'
subject_id_usr = os.path.join(root_folder, 'subjects folder', 'subject_01')

#Make sure you've at least simplified the mesh of the subject
vertices = np.load(os.path.join(subject_id_usr, 'vertices_simple.npy'))
faces = np.load(os.path.join(subject_id_usr, 'faces_simple.npy'))

ret = igl.write_triangle_mesh(os.path.join(subject_id_usr, "bunny_out.obj"),
                              vertices, faces)

v, f = igl.read_triangle_mesh(os.path.join(subject_id_usr, "bunny_out.obj"))
[pd1, pd2, pv1, pv2] = igl.principal_curvature(v, f, radius=5, use_k_ring=True)
#Mean curvature is (pv1+pv2)/2 and Gaussian curvature is pv1*pv2
# k = igl.gaussian_curvature(v, f)
np.save(os.path.join(subject_id_usr, 'mean_curv_simple.npy'), (pv1 + pv2) / 2)

#Deletes temporary object
os.remove(os.path.join(subject_id_usr, "bunny_out.obj"))
igl.invert_diag(M,Minv)

# Laplace-Beltrami of position
HN = -Minv*(L*V)

# Extract magnitude as mean curvature
H = HN.rowwiseNorm()

# Compute curvature directions via quadric fitting
PD1 = igl.eigen.MatrixXd()
PD2 = igl.eigen.MatrixXd()

PV1 = igl.eigen.MatrixXd()
PV2 = igl.eigen.MatrixXd()

igl.principal_curvature(V,F,PD1,PD2,PV1,PV2)

# Mean curvature
H = 0.5*(PV1+PV2)

viewer = igl.viewer.Viewer()
viewer.data.set_mesh(V, F)

# Compute pseudocolor
C = igl.eigen.MatrixXd()
igl.parula(H,True,C)

viewer.data.set_colors(C)

# Average edge length for sizing
avg = igl.avg_edge_length(V,F)
Ejemplo n.º 8
0
 def getGaussCurv(self):
     vertices = np.row_stack([vertex.coords for vertex in self.vertices])
     faces = np.row_stack([face.vertex_ids for face in self.faces])
     self.gaussian_curvature = igl.principal_curvature(vertices,
                                                       faces,
                                                       radius=6)