mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2025-12-22 23:30:35 +08:00
point mesh distances
Summary: Implementation of point to mesh distances. The current diff contains two types: (a) Point to Edge (b) Point to Face ``` Benchmark Avg Time(μs) Peak Time(μs) Iterations -------------------------------------------------------------------------------- POINT_MESH_EDGE_4_100_300_5000_cuda:0 2745 3138 183 POINT_MESH_EDGE_4_100_300_10000_cuda:0 4408 4499 114 POINT_MESH_EDGE_4_100_3000_5000_cuda:0 4978 5070 101 POINT_MESH_EDGE_4_100_3000_10000_cuda:0 9076 9187 56 POINT_MESH_EDGE_4_1000_300_5000_cuda:0 1411 1487 355 POINT_MESH_EDGE_4_1000_300_10000_cuda:0 4829 5030 104 POINT_MESH_EDGE_4_1000_3000_5000_cuda:0 7539 7620 67 POINT_MESH_EDGE_4_1000_3000_10000_cuda:0 12088 12272 42 POINT_MESH_EDGE_8_100_300_5000_cuda:0 3106 3222 161 POINT_MESH_EDGE_8_100_300_10000_cuda:0 8561 8648 59 POINT_MESH_EDGE_8_100_3000_5000_cuda:0 6932 7021 73 POINT_MESH_EDGE_8_100_3000_10000_cuda:0 24032 24176 21 POINT_MESH_EDGE_8_1000_300_5000_cuda:0 5272 5399 95 POINT_MESH_EDGE_8_1000_300_10000_cuda:0 11348 11430 45 POINT_MESH_EDGE_8_1000_3000_5000_cuda:0 17478 17683 29 POINT_MESH_EDGE_8_1000_3000_10000_cuda:0 25961 26236 20 POINT_MESH_EDGE_16_100_300_5000_cuda:0 8244 8323 61 POINT_MESH_EDGE_16_100_300_10000_cuda:0 18018 18071 28 POINT_MESH_EDGE_16_100_3000_5000_cuda:0 19428 19544 26 POINT_MESH_EDGE_16_100_3000_10000_cuda:0 44967 45135 12 POINT_MESH_EDGE_16_1000_300_5000_cuda:0 7825 7937 64 POINT_MESH_EDGE_16_1000_300_10000_cuda:0 18504 18571 28 POINT_MESH_EDGE_16_1000_3000_5000_cuda:0 65805 66132 8 POINT_MESH_EDGE_16_1000_3000_10000_cuda:0 90885 91089 6 -------------------------------------------------------------------------------- Benchmark Avg Time(μs) Peak Time(μs) Iterations -------------------------------------------------------------------------------- POINT_MESH_FACE_4_100_300_5000_cuda:0 1561 1685 321 POINT_MESH_FACE_4_100_300_10000_cuda:0 2818 2954 178 POINT_MESH_FACE_4_100_3000_5000_cuda:0 15893 16018 32 POINT_MESH_FACE_4_100_3000_10000_cuda:0 16350 16439 31 POINT_MESH_FACE_4_1000_300_5000_cuda:0 3179 3278 158 POINT_MESH_FACE_4_1000_300_10000_cuda:0 2353 2436 213 POINT_MESH_FACE_4_1000_3000_5000_cuda:0 16262 16336 31 POINT_MESH_FACE_4_1000_3000_10000_cuda:0 9334 9448 54 POINT_MESH_FACE_8_100_300_5000_cuda:0 4377 4493 115 POINT_MESH_FACE_8_100_300_10000_cuda:0 9728 9822 52 POINT_MESH_FACE_8_100_3000_5000_cuda:0 26428 26544 19 POINT_MESH_FACE_8_100_3000_10000_cuda:0 42238 43031 12 POINT_MESH_FACE_8_1000_300_5000_cuda:0 3891 3982 129 POINT_MESH_FACE_8_1000_300_10000_cuda:0 5363 5429 94 POINT_MESH_FACE_8_1000_3000_5000_cuda:0 20998 21084 24 POINT_MESH_FACE_8_1000_3000_10000_cuda:0 39711 39897 13 POINT_MESH_FACE_16_100_300_5000_cuda:0 5955 6001 84 POINT_MESH_FACE_16_100_300_10000_cuda:0 12082 12144 42 POINT_MESH_FACE_16_100_3000_5000_cuda:0 44996 45176 12 POINT_MESH_FACE_16_100_3000_10000_cuda:0 73042 73197 7 POINT_MESH_FACE_16_1000_300_5000_cuda:0 8292 8374 61 POINT_MESH_FACE_16_1000_300_10000_cuda:0 19442 19506 26 POINT_MESH_FACE_16_1000_3000_5000_cuda:0 36059 36194 14 POINT_MESH_FACE_16_1000_3000_10000_cuda:0 64644 64822 8 -------------------------------------------------------------------------------- ``` Reviewed By: jcjohnson Differential Revision: D20590462 fbshipit-source-id: 42a39837b514a546ac9471bfaff60eefe7fae829
This commit is contained in:
committed by
Facebook GitHub Bot
parent
474c8b456a
commit
487d4d6607
@@ -147,36 +147,38 @@ class Meshes(object):
|
||||
Total number of unique edges = sum(E_n)
|
||||
|
||||
# SPHINX IGNORE
|
||||
Name | Size | Example from above
|
||||
------------------------------|-------------------------|----------------------
|
||||
| |
|
||||
edges_packed | size = (sum(E_n), 2) | tensor([
|
||||
| | [0, 1],
|
||||
| | [0, 2],
|
||||
| | [1, 2],
|
||||
| | ...
|
||||
| | [10, 11],
|
||||
| | )]
|
||||
| | size = (18, 2)
|
||||
| |
|
||||
num_edges_per_mesh | size = (N) | tensor([3, 5, 10])
|
||||
| | size = (3)
|
||||
| |
|
||||
edges_packed_to_mesh_idx | size = (sum(E_n)) | tensor([
|
||||
| | 0, 0, 0,
|
||||
| | . . .
|
||||
| | 2, 2, 2
|
||||
| | ])
|
||||
| | size = (18)
|
||||
| |
|
||||
faces_packed_to_edges_packed | size = (sum(F_n), 3) | tensor([
|
||||
| | [2, 1, 0],
|
||||
| | [5, 4, 3],
|
||||
| | . . .
|
||||
| | [12, 14, 16],
|
||||
| | ])
|
||||
| | size = (10, 3)
|
||||
| |
|
||||
Name | Size | Example from above
|
||||
-------------------------------|-------------------------|----------------------
|
||||
| |
|
||||
edges_packed | size = (sum(E_n), 2) | tensor([
|
||||
| | [0, 1],
|
||||
| | [0, 2],
|
||||
| | [1, 2],
|
||||
| | ...
|
||||
| | [10, 11],
|
||||
| | )]
|
||||
| | size = (18, 2)
|
||||
| |
|
||||
num_edges_per_mesh | size = (N) | tensor([3, 5, 10])
|
||||
| | size = (3)
|
||||
| |
|
||||
edges_packed_to_mesh_idx | size = (sum(E_n)) | tensor([
|
||||
| | 0, 0, 0,
|
||||
| | . . .
|
||||
| | 2, 2, 2
|
||||
| | ])
|
||||
| | size = (18)
|
||||
| |
|
||||
faces_packed_to_edges_packed | size = (sum(F_n), 3) | tensor([
|
||||
| | [2, 1, 0],
|
||||
| | [5, 4, 3],
|
||||
| | . . .
|
||||
| | [12, 14, 16],
|
||||
| | ])
|
||||
| | size = (10, 3)
|
||||
| |
|
||||
mesh_to_edges_packed_first_idx | size = (N) | tensor([0, 3, 8])
|
||||
| | size = (3)
|
||||
----------------------------------------------------------------------------
|
||||
# SPHINX IGNORE
|
||||
"""
|
||||
@@ -197,6 +199,7 @@ class Meshes(object):
|
||||
"_num_faces_per_mesh",
|
||||
"_edges_packed",
|
||||
"_edges_packed_to_mesh_idx",
|
||||
"_mesh_to_edges_packed_first_idx",
|
||||
"_faces_packed_to_edges_packed",
|
||||
"_num_edges_per_mesh",
|
||||
"_verts_padded_to_packed_idx",
|
||||
@@ -278,6 +281,7 @@ class Meshes(object):
|
||||
# Map from packed edges to corresponding mesh index.
|
||||
self._edges_packed_to_mesh_idx = None # sum(E_n)
|
||||
self._num_edges_per_mesh = None # N
|
||||
self._mesh_to_edges_packed_first_idx = None # N
|
||||
|
||||
# Map from packed faces to packed edges. This represents the index of
|
||||
# the edge opposite the vertex for each vertex in the face. E.g.
|
||||
@@ -611,6 +615,17 @@ class Meshes(object):
|
||||
self._compute_edges_packed()
|
||||
return self._edges_packed_to_mesh_idx
|
||||
|
||||
def mesh_to_edges_packed_first_idx(self):
|
||||
"""
|
||||
Return a 1D tensor x with length equal to the number of meshes such that
|
||||
the first edge of the ith mesh is edges_packed[x[i]].
|
||||
|
||||
Returns:
|
||||
1D tensor of indices of first items.
|
||||
"""
|
||||
self._compute_edges_packed()
|
||||
return self._mesh_to_edges_packed_first_idx
|
||||
|
||||
def faces_packed_to_edges_packed(self):
|
||||
"""
|
||||
Get the packed representation of the faces in terms of edges.
|
||||
@@ -955,6 +970,7 @@ class Meshes(object):
|
||||
self._faces_packed_to_mesh_idx,
|
||||
self._edges_packed_to_mesh_idx,
|
||||
self._num_edges_per_mesh,
|
||||
self._mesh_to_edges_packed_first_idx,
|
||||
]
|
||||
)
|
||||
):
|
||||
@@ -1023,13 +1039,24 @@ class Meshes(object):
|
||||
face_to_edge = inverse_idxs[face_to_edge]
|
||||
self._faces_packed_to_edges_packed = face_to_edge
|
||||
|
||||
# Compute number of edges per mesh
|
||||
num_edges_per_mesh = torch.zeros(self._N, dtype=torch.int32, device=self.device)
|
||||
ones = torch.ones(1, dtype=torch.int32, device=self.device).expand(
|
||||
self._edges_packed_to_mesh_idx.shape
|
||||
)
|
||||
self._num_edges_per_mesh = num_edges_per_mesh.scatter_add(
|
||||
num_edges_per_mesh = num_edges_per_mesh.scatter_add_(
|
||||
0, self._edges_packed_to_mesh_idx, ones
|
||||
)
|
||||
self._num_edges_per_mesh = num_edges_per_mesh
|
||||
|
||||
# Compute first idx for each mesh in edges_packed
|
||||
mesh_to_edges_packed_first_idx = torch.zeros(
|
||||
self._N, dtype=torch.int64, device=self.device
|
||||
)
|
||||
num_edges_cumsum = num_edges_per_mesh.cumsum(dim=0)
|
||||
mesh_to_edges_packed_first_idx[1:] = num_edges_cumsum[:-1].clone()
|
||||
|
||||
self._mesh_to_edges_packed_first_idx = mesh_to_edges_packed_first_idx
|
||||
|
||||
def _compute_laplacian_packed(self, refresh: bool = False):
|
||||
"""
|
||||
|
||||
@@ -963,3 +963,44 @@ class Pointclouds(object):
|
||||
new._features_list = None
|
||||
new._features_packed = None
|
||||
return new
|
||||
|
||||
def inside_box(self, box):
|
||||
"""
|
||||
Finds the points inside a 3D box.
|
||||
|
||||
Args:
|
||||
box: FloatTensor of shape (2, 3) or (N, 2, 3) where N is the number
|
||||
of clouds.
|
||||
box[..., 0, :] gives the min x, y & z.
|
||||
box[..., 1, :] gives the max x, y & z.
|
||||
Returns:
|
||||
idx: BoolTensor of length sum(P_i) indicating whether the packed points are within the input box.
|
||||
"""
|
||||
if box.dim() > 3 or box.dim() < 2:
|
||||
raise ValueError("Input box must be of shape (2, 3) or (N, 2, 3).")
|
||||
|
||||
if box.dim() == 3 and box.shape[0] != 1 and box.shape[0] != self._N:
|
||||
raise ValueError(
|
||||
"Input box dimension is incompatible with pointcloud size."
|
||||
)
|
||||
|
||||
if box.dim() == 2:
|
||||
box = box[None]
|
||||
|
||||
if (box[..., 0, :] > box[..., 1, :]).any():
|
||||
raise ValueError("Input box is invalid: min values larger than max values.")
|
||||
|
||||
points_packed = self.points_packed()
|
||||
sumP = points_packed.shape[0]
|
||||
|
||||
if box.shape[0] == 1:
|
||||
box = box.expand(sumP, 2, 3)
|
||||
elif box.shape[0] == self._N:
|
||||
box = box.unbind(0)
|
||||
box = [
|
||||
b.expand(p, 2, 3) for (b, p) in zip(box, self.num_points_per_cloud())
|
||||
]
|
||||
box = torch.cat(box, 0)
|
||||
|
||||
idx = (points_packed >= box[:, 0]) * (points_packed <= box[:, 1])
|
||||
return idx
|
||||
|
||||
Reference in New Issue
Block a user