generated from dongliangcao/pytorch-framework
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathshape_util.py
72 lines (59 loc) · 2.27 KB
/
shape_util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import os
import numpy as np
import trimesh
import networkx as nx
import open3d as o3d
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import shortest_path
from sklearn import neighbors
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
def compute_geodesic_distmat(verts, faces):
"""
Compute geodesic distance matrix using Dijkstra algorithm
Args:
verts (np.ndarray): array of vertices coordinates [n, 3]
faces (np.ndarray): array of triangular faces [m, 3]
Returns:
geo_dist: geodesic distance matrix [n, n]
"""
NN = 500
# get adjacency matrix
mesh = trimesh.Trimesh(vertices=verts, faces=faces, process=False)
vertex_adjacency = mesh.vertex_adjacency_graph
assert nx.is_connected(vertex_adjacency), 'Graph not connected'
vertex_adjacency_matrix = nx.adjacency_matrix(vertex_adjacency, range(verts.shape[0]))
# get adjacency distance matrix
graph_x_csr = neighbors.kneighbors_graph(verts, n_neighbors=NN, mode='distance', include_self=False)
distance_adj = csr_matrix((verts.shape[0], verts.shape[0])).tolil()
distance_adj[vertex_adjacency_matrix != 0] = graph_x_csr[vertex_adjacency_matrix != 0]
# compute geodesic matrix
geodesic_x = shortest_path(distance_adj, directed=False)
if np.any(np.isinf(geodesic_x)):
print('Inf number in geodesic distance. Increase NN.')
return geodesic_x
def read_shape(file, as_cloud=False):
"""
Read mesh from file.
Args:
file (str): file name
as_cloud (bool, optional): read shape as point cloud. Default False
Returns:
verts (np.ndarray): vertices [V, 3]
faces (np.ndarray): faces [F, 3] or None
"""
if as_cloud:
verts = np.asarray(o3d.io.read_point_cloud(file).points)
faces = None
else:
mesh = o3d.io.read_triangle_mesh(file)
verts, faces = np.asarray(mesh.vertices), np.asarray(mesh.triangles)
return verts, faces
def write_off(file, verts, faces):
with open(file, 'w') as f:
f.write("OFF\n")
f.write(f"{verts.shape[0]} {faces.shape[0]} {0}\n")
for x in verts:
f.write(f"{' '.join(map(str, x))}\n")
for x in faces:
f.write(f"{len(x)} {' '.join(map(str, x))}\n")