def test_ambient_occlusion(self):
        n = igl.per_vertex_normals(self.v2, self.f2)
        s = igl.ambient_occlusion(self.v2, self.f2, self.v2, n, 2)

        self.assertEqual(s.dtype, self.v1.dtype)
        self.assertEqual(len(s.shape), 1)
        self.assertTrue(s.flags.c_contiguous)
예제 #2
0
def vertex_normals(verts, faces, n_neighbors_cloud=30):
    verts_np = toNP(verts)
    if isinstance(faces, list):
        is_cloud = faces == []
    else:
        is_cloud = faces.numel() == 0
    if is_cloud:  # point cloud

        _, neigh_inds = find_knn(verts,
                                 verts,
                                 n_neighbors_cloud,
                                 omit_diagonal=True,
                                 method='cpu_kd')
        neigh_points = verts_np[neigh_inds, :]
        neigh_points = neigh_points - verts_np[:, np.newaxis, :]
        normals = neighborhood_normal(neigh_points)

    else:  # mesh

        normals = igl.per_vertex_normals(verts_np, toNP(faces))

        # if any are NaN, wiggle slightly and recompute
        bad_normals_mask = np.isnan(normals).any(axis=1, keepdims=True)
        if bad_normals_mask.any():
            bbox = np.amax(verts_np, axis=0) - np.amin(verts_np, axis=0)
            scale = np.linalg.norm(bbox) * 1e-4
            wiggle = (np.random.RandomState(seed=777).rand(*verts.shape) -
                      0.5) * scale
            wiggle_verts = verts_np + bad_normals_mask * wiggle
            normals = igl.per_vertex_normals(wiggle_verts, toNP(faces))

        # if still NaN assign random normals (probably means unreferenced verts in mesh)
        bad_normals_mask = np.isnan(normals).any(axis=1)
        if bad_normals_mask.any():
            normals[bad_normals_mask, :] = (
                np.random.RandomState(seed=777).rand(*verts.shape) -
                0.5)[bad_normals_mask, :]
            normals = normals / np.linalg.norm(normals, axis=-1)[:, np.newaxis]

    normals = torch.from_numpy(normals).to(device=verts.device,
                                           dtype=verts.dtype)

    if torch.any(torch.isnan(normals)): raise ValueError("NaN normals :(")

    return normals
예제 #3
0
 def getNormals(self, mesh=None):
     """
     Computes the normals for a mesh
     :param mesh: This should be some class that has mesh.vertices and mesh.faces of Vertex and Face class respectively
     :return: Puts vectors in self.vectors
     """
     vertices = np.row_stack([vertex.coords for vertex in mesh.vertices])
     faces = np.row_stack([face.vertex_ids for face in mesh.faces])
     self.vectors = igl.per_vertex_normals(vertices, faces, weighting=1)
예제 #4
0
 def set_parameters(self, V, F):
     # reset
     self.reset()
     # compute property given V and F
     self.N = igl.per_vertex_normals(V, F)
     self.L = igl.cotmatrix(V, F)
     VA = igl.massmatrix(V, F, 0)
     self.VA = VA.diagonal()
     # get face adjacency list
     VF, NI = igl.vertex_triangle_adjacency(F, V.shape[0])
     adjFList = construct_adjacency_list(VF, NI)
     # arap
     self.K = igl.arap_rhs(V, F, d=3, energy=1)
     # they are all list since length can be different
     self.hEList = [None] * V.shape[0]
     self.WVecList = [None] * V.shape[0]
     self.dVList = [None] * V.shape[0]
     for i in range(0, V.shape[0]):
         adjF = adjFList[i]
         len_adjF = adjF.shape[0]
         self.hEList[i] = np.zeros((len_adjF * 3, 2), dtype=int)
         self.WVecList[i] = np.zeros(len_adjF * 3)
         self.dVList[i] = np.zeros((3, 3 * len_adjF))
         for j in range(0, len_adjF):
             vIdx = adjF[j]
             v0 = F[vIdx, 0]
             v1 = F[vIdx, 1]
             v2 = F[vIdx, 2]
             # half edge indices
             # hE = np.array([[v0, v1], [v1, v2], [v2, v0]])
             # self.hEList[i] = hE
             self.hEList[i][3 * j, 0] = v0
             self.hEList[i][3 * j, 1] = v1
             self.hEList[i][3 * j + 1, 0] = v1
             self.hEList[i][3 * j + 1, 1] = v2
             self.hEList[i][3 * j + 2, 0] = v2
             self.hEList[i][3 * j + 2, 1] = v0
             # weight vec
             self.WVecList[i][3 * j] = self.L[v0, v1]
             self.WVecList[i][3 * j + 1] = self.L[v1, v2]
             self.WVecList[i][3 * j + 2] = self.L[v2, v0]
         V_hE0 = V[self.hEList[i][:, 0], :]
         V_hE1 = V[self.hEList[i][:, 1], :]
         self.dVList[i] = np.transpose(V_hE1 - V_hE0)
         self.WVecList[i] = np.diag(self.WVecList[i])
     # other var
     numV = V.shape[0]
     self.zAll = np.random.rand(3, numV) * 2.0 - 1.0
     self.uAll = np.random.rand(3, numV) * 2.0 - 1.0
     self.zAll = np.zeros((3, numV))
     self.uAll = np.zeros((3, numV))
     self.rhoAll = np.full(numV, self.param.rhoInit)
예제 #5
0
    def select_views(self, views_e, F):
        """ Select a subset views that contain the most information about F.

        The pipeline is as follows:
        TSDF --> Mesh --> Simplify Mesh --> Normals --> Sample points weighted by curvature
          --> Compute scores for each view --> Greedily select best subset of views

        Args:
            F       : 3D Fusion volume
            views_e : list of views expressed in end-effector space.
        """
        # Project views from end-effector space

        f_T_e = np.linalg.inv(self.tsdf_vol_params.e_T_f)
        views_f = views_e_to_f(views_e, f_T_e)

        print("TSDF to mesh...")
        verts, faces = self.tsdf_to_mesh(F)

        print("Smooth data...")
        # success, verts, faces = self.simplify_mesh(verts, faces)
        v_star = smooth_data(verts, faces, self.params.w_smooth)

        print("Normals...")
        normals = igl.per_vertex_normals(v_star, faces)

        print("Sample vertices ...")
        verts_choice, _ = self.sample_verts_from_mesh(v_star, faces)

        # NOTE sample from original vertices
        verts = verts[verts_choice, :]
        normals = normals[verts_choice, :]

        num_views = len(views_e)
        scores = np.ndarray((num_views, self.params.n_sample_pts))

        print("Compute scores ...")
        for i in range(num_views):
            scores[i, :] = self.compute_geometry_values(
                views_f[i], verts, normals)
            visibility = self.compute_visibility_values(views_f[i], verts, F)
            scores[i, :] *= visibility

        print("Greedy best subset ...")
        best_views, _ = self.greedy_best_subset(scores)

        return best_views
예제 #6
0
def ScalpReconstruct(V, nilr, cpc_inners=99, fibonacci_samples = 9801 * 0): 
    if fibonacci_samples == 0:   
        R, t = calibrate_nilr(nilr[0], nilr[1], nilr[2], nilr[3])
        nilr = np.dot(nilr-t, R.T)
        
        mriV = np.dot(V-t, R.T)
        if len(V) > 1000:
            mriV = spherical_clip(np.dot(V-t, R.T), np.linalg.norm(nilr[-1])*0.8)
        # np.savetxt("runtime/mriV.obj", np.dot(mriV, R)+T, fmt="v %f %f %f")
        
        mV, mF, mCtrl, nilr_idx = MinimalSurface(mriV, nilr[0], nilr[1], nilr[2], nilr[3]) 
        Nzidx, Izidx, Alidx, Aridx = nilr_idx

        cpc_V, cpc_CPC, cpc_F = CPCSampling.generate_cpcmesh(mV, mF, Nzidx, Izidx, Alidx, Aridx, n=cpc_inners)
        cpc_N = igl.per_vertex_normals(cpc_V, cpc_F, igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE)
        T, B, N = TNBFrame.TNB_frame(cpc_V, cpc_N, cpc_inners)
        cpc_V, T, B, N = np.dot(cpc_V, R)+t, np.dot(T, R), np.dot(B, R), np.dot(N, R)
        return cpc_V, cpc_F, cpc_CPC, T, B, N

    else:
        _V, _F, _V_CPC, _T, _N, _B = ScalpReconstruct(V, nilr, cpc_inners=699)
        index, fb_CPC, fb_F = CPCSampling.load_fibonacci(fibonacci_samples)
        fb_V, fb_T, fb_N, fb_B = _V[index], _T[index], _N[index], _B[index]
        return fb_V, fb_F, fb_CPC, fb_T, fb_B, fb_N
      return True
    elif key == ord('3'):
      viewer.data.set_normals(N_corners)
      return True
    return False

# Load a mesh in OFF format
igl.readOFF("../../tutorial/shared/fandisk.off", V, F);

# Compute per-face normals
N_faces = igl.eigen.MatrixXd()
igl.per_face_normals(V,F,N_faces)

# Compute per-vertex normals
N_vertices = igl.eigen.MatrixXd()
igl.per_vertex_normals(V,F,igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA,N_vertices)

# Compute per-corner normals, |dihedral angle| > 20 degrees --> crease
N_corners = igl.eigen.MatrixXd()
igl.per_corner_normals(V,F,20,N_corners)

# Plot the mesh
viewer = igl.viewer.Viewer()
viewer.callback_key_pressed = key_pressed
viewer.core.show_lines = False
viewer.data.set_mesh(V, F)
viewer.data.set_normals(N_faces)
print("Press '1' for per-face normals.")
print("Press '2' for per-vertex normals.")
print("Press '3' for per-corner normals.")
viewer.launch()
            centroid += 0.5*dblA[i,0]/area*BC.row(i)

        U -= centroid.replicate(U.rows(),1)

        # Normalize to unit surface area (important for numerics)
        U = U / math.sqrt(area)
    else:
        return False

    # Send new positions, update normals, recenter
    viewer.data.set_vertices(U)
    viewer.data.compute_normals()
    viewer.core.align_camera_center(U,F)
    return True

# Use original normals as pseudo-colors
N = igl.eigen.MatrixXd()
igl.per_vertex_normals(V,F,N)
C = N.rowwiseNormalized()*0.5+0.5;

# Initialize smoothing with base mesh
U = V
viewer.data.set_mesh(U, F)
viewer.data.set_colors(C)
viewer.callback_key_pressed = key_pressed

print("Press [space] to smooth.")
print("Press [r] to reset.")

viewer.launch()
예제 #9
0

def draw_cpc_wireframe(p: pv.Plotter, V: np.ndarray, n=10):
    for i in np.linspace(0, 100, n + 1, dtype=np.int)[1:-1] - 1:
        p.add_mesh(polyline_from_points(V[i, :]), color=wireframe_color)
    for j in np.linspace(0, 100, n + 1, dtype=np.int)[1:-1] - 1:
        p.add_mesh(polyline_from_points(V[:, j]), color=wireframe_color)


def draw_orient_definition(p: pv.Plotter, V: np.ndarray, N: np.ndarray):
    pass


if __name__ == "__main__":
    V, F = igl.read_triangle_mesh("./data/12034_CPC.obj")
    N = igl.per_vertex_normals(V, F,
                               igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA)
    T, N, B = CPCScalpRecons.TNBFrame.TNB_frame(V, N, cpc_ratio=99)
    scalp = pv.PolyData()
    scalp.points, scalp.faces = V, np.column_stack(
        [np.full((len(F), 1), 3), F])

    p = pv.Plotter()
    # p.add_text("Scalp TBN Frame", font_size=18)
    scalp_ = p.add_mesh(scalp,
                        ambient=0.06,
                        diffuse=0.75,
                        opacity=1,
                        color=(1., 0.8, 0.7))  #, scalars="yz_dot", cmap="jet")

    draw_cpc_wireframe(p, V[:9801, :].reshape((99, 99, -1)))
예제 #10
0
 def test_per_vertex_normals(self):
     n = igl.per_vertex_normals(self.v1, self.f1, 0)
     self.assertEqual(n.shape, (self.v1.shape[0], 3))
     self.assertEqual(n.dtype, self.v1.dtype)
     self.assertTrue(n.flags.c_contiguous)
예제 #11
0
파일: flow.py 프로젝트: Sin-tel/spheremesh
def get_flipped_normals(vertices, faces):
    normals = igl.per_vertex_normals(vertices, faces)
    dot = np.sum(normals * vertices, axis=1)
    return sum(dot < 0) / vertices.shape[0]
예제 #12
0
    Rvec = np.cross(lr_N, N, axis=1)
    Rvec /= np.linalg.norm(Rvec, axis=1)[:, np.newaxis]

    for i in range(len(lr_N)):
        projection_len = np.clip(np.dot(N[i], lr_N[i]), 0, 1)
        R = transform.Rotation.from_rotvec(Rvec[i] * np.arccos(projection_len))
        lr_T[i], lr_N[i], lr_B[i] = map(R.apply, (lr_T[i], lr_N[i], lr_B[i]))

    return lr_T, lr_N, lr_B


if __name__ == "__main__":
    import igl
    cpc_V, cpc_F = igl.read_triangle_mesh("./apps/data/12034_CPC.obj")
    surface_N = igl.per_vertex_normals(
        cpc_V, cpc_F, igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE)
    T, N, B = TNB_frame(cpc_V, surface_N, cpc_ratio=99)

    import pyvista as pv
    scalp = pv.PolyData()
    scalp.points = cpc_V
    scalp.faces = np.column_stack([np.full((len(cpc_F), 1), 3), cpc_F])

    p = pv.Plotter()
    p.add_text("Scalp CPC-TNBFrame", font_size=18)
    p.add_mesh(scalp,
               ambient=0.06,
               diffuse=0.75,
               opacity=1.0,
               color=(1., 0.8, 0.7))  #, scalars="yz_dot", cmap="jet")
예제 #13
0
 def test_per_vertex_normals(self):
     n = igl.per_vertex_normals(self.v1, self.f1, 0)
     self.assertEqual(n.shape, (self.v1.shape[0], 3))
     self.assertEqual(n.dtype, self.v1.dtype)