conquer3d 0.2.4__tar.gz → 0.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {conquer3d-0.2.4/conquer3d.egg-info → conquer3d-0.2.5}/PKG-INFO +49 -12
- {conquer3d-0.2.4 → conquer3d-0.2.5}/README.md +48 -11
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/_C.pyi +18 -2
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/_C.so +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/bvh.cpp +52 -1
- conquer3d-0.2.5/conquer3d/csrc/binds/data_structure/mesh_bvh.cpp +36 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/triangle_mesh.cpp +25 -2
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/bvh.cu +89 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/bvh.h +19 -0
- conquer3d-0.2.5/conquer3d/csrc/data_structure/mesh_bvh.cu +205 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/mesh_bvh.h +9 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/triangle_mesh.cu +1 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/triangle_mesh.h +5 -0
- conquer3d-0.2.5/conquer3d/csrc/primitive/ray.h +62 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/triangles.h +71 -21
- {conquer3d-0.2.4 → conquer3d-0.2.5/conquer3d.egg-info}/PKG-INFO +49 -12
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d.egg-info/SOURCES.txt +1 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/pyproject.toml +1 -1
- {conquer3d-0.2.4 → conquer3d-0.2.5}/setup.py +0 -10
- conquer3d-0.2.4/conquer3d/csrc/binds/data_structure/mesh_bvh.cpp +0 -22
- conquer3d-0.2.4/conquer3d/csrc/data_structure/mesh_bvh.cu +0 -98
- {conquer3d-0.2.4 → conquer3d-0.2.5}/LICENSE +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/MANIFEST.in +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/__init__.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/creation/__init__.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/creation/triangle_creation.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/creation/triangle_creation.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/gs_bvh.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/kdtree.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/data_structure/pgs_bvh.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/primitive/gs.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/binds/primitive/pgs.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/check.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/constants.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/creation/triangle_creation.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/gs_bvh.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/kdtree.cu +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/kdtree.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/pgs_bvh.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/data_structure/zcurve.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f2x2.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x1.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x3.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f3x4.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f4x1.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/f4x4.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/maths.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/maths/ops.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/aabb.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/edge.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs.cu +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs_aabb.cu +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/gs_math.cuh +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs.cu +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs.h +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs_aabb.cu +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/primitive/pgs_math.cuh +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/csrc/pybind.cpp +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/data_structure/__init__.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/primitive/__init__.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/primitive/gs.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d/primitive/pgs.py +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d.egg-info/dependency_links.txt +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d.egg-info/not-zip-safe +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d.egg-info/requires.txt +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/conquer3d.egg-info/top_level.txt +0 -0
- {conquer3d-0.2.4 → conquer3d-0.2.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: conquer3d
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Geometric Cuda Tool Box
|
|
5
5
|
Author-email: Do Hoang Khoi <khoido8899@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -68,17 +68,54 @@ twine upload dist/* --verbose
|
|
|
68
68
|
## Research Paper
|
|
69
69
|
```bibtex
|
|
70
70
|
@inproceedings{2383795.2383801,
|
|
71
|
-
author = {Karras, Tero},
|
|
72
|
-
title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
|
|
73
|
-
year = {2012},
|
|
74
|
-
isbn = {9783905674415},
|
|
75
|
-
publisher = {Eurographics Association},
|
|
76
|
-
address = {Goslar, DEU},
|
|
77
|
-
booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
|
|
78
|
-
pages = {33–37},
|
|
79
|
-
numpages = {5},
|
|
80
|
-
location = {Paris, France},
|
|
81
|
-
series = {EGGH-HPG'12}
|
|
71
|
+
author = {Karras, Tero},
|
|
72
|
+
title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
|
|
73
|
+
year = {2012},
|
|
74
|
+
isbn = {9783905674415},
|
|
75
|
+
publisher = {Eurographics Association},
|
|
76
|
+
address = {Goslar, DEU},
|
|
77
|
+
booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
|
|
78
|
+
pages = {33–37},
|
|
79
|
+
numpages = {5},
|
|
80
|
+
location = {Paris, France},
|
|
81
|
+
series = {EGGH-HPG'12}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```bibtex
|
|
86
|
+
@article{10.1080/10867651.1997.10487472,
|
|
87
|
+
author = {M\"{o}ller, Tomas},
|
|
88
|
+
title = {A fast triangle-triangle intersection test},
|
|
89
|
+
year = {1997},
|
|
90
|
+
issue_date = {1997},
|
|
91
|
+
publisher = {A. K. Peters, Ltd.},
|
|
92
|
+
address = {USA},
|
|
93
|
+
volume = {2},
|
|
94
|
+
number = {2},
|
|
95
|
+
issn = {1086-7651},
|
|
96
|
+
url = {https://doi.org/10.1080/10867651.1997.10487472},
|
|
97
|
+
doi = {10.1080/10867651.1997.10487472},
|
|
98
|
+
journal = {J. Graph. Tools},
|
|
99
|
+
month = nov,
|
|
100
|
+
pages = {25–30},
|
|
101
|
+
numpages = {6}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```bibtex
|
|
106
|
+
@inproceedings{10.1145/1198555.1198746,
|
|
107
|
+
author = {M\"{o}ller, Tomas and Trumbore, Ben},
|
|
108
|
+
title = {Fast, minimum storage ray/triangle intersection},
|
|
109
|
+
year = {2005},
|
|
110
|
+
isbn = {9781450378338},
|
|
111
|
+
publisher = {Association for Computing Machinery},
|
|
112
|
+
address = {New York, NY, USA},
|
|
113
|
+
url = {https://doi.org/10.1145/1198555.1198746},
|
|
114
|
+
doi = {10.1145/1198555.1198746},
|
|
115
|
+
pages = {7–es},
|
|
116
|
+
keywords = {base transformation, intersection, ray tracing, ray/triangle-intersection},
|
|
117
|
+
location = {Los Angeles, California},
|
|
118
|
+
series = {SIGGRAPH '05}
|
|
82
119
|
}
|
|
83
120
|
```
|
|
84
121
|
|
|
@@ -44,17 +44,54 @@ twine upload dist/* --verbose
|
|
|
44
44
|
## Research Paper
|
|
45
45
|
```bibtex
|
|
46
46
|
@inproceedings{2383795.2383801,
|
|
47
|
-
author = {Karras, Tero},
|
|
48
|
-
title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
|
|
49
|
-
year = {2012},
|
|
50
|
-
isbn = {9783905674415},
|
|
51
|
-
publisher = {Eurographics Association},
|
|
52
|
-
address = {Goslar, DEU},
|
|
53
|
-
booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
|
|
54
|
-
pages = {33–37},
|
|
55
|
-
numpages = {5},
|
|
56
|
-
location = {Paris, France},
|
|
57
|
-
series = {EGGH-HPG'12}
|
|
47
|
+
author = {Karras, Tero},
|
|
48
|
+
title = {Maximizing parallelism in the construction of BVHs, octrees, and k-d trees},
|
|
49
|
+
year = {2012},
|
|
50
|
+
isbn = {9783905674415},
|
|
51
|
+
publisher = {Eurographics Association},
|
|
52
|
+
address = {Goslar, DEU},
|
|
53
|
+
booktitle = {Proceedings of the Fourth ACM SIGGRAPH / Eurographics Conference on High-Performance Graphics},
|
|
54
|
+
pages = {33–37},
|
|
55
|
+
numpages = {5},
|
|
56
|
+
location = {Paris, France},
|
|
57
|
+
series = {EGGH-HPG'12}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```bibtex
|
|
62
|
+
@article{10.1080/10867651.1997.10487472,
|
|
63
|
+
author = {M\"{o}ller, Tomas},
|
|
64
|
+
title = {A fast triangle-triangle intersection test},
|
|
65
|
+
year = {1997},
|
|
66
|
+
issue_date = {1997},
|
|
67
|
+
publisher = {A. K. Peters, Ltd.},
|
|
68
|
+
address = {USA},
|
|
69
|
+
volume = {2},
|
|
70
|
+
number = {2},
|
|
71
|
+
issn = {1086-7651},
|
|
72
|
+
url = {https://doi.org/10.1080/10867651.1997.10487472},
|
|
73
|
+
doi = {10.1080/10867651.1997.10487472},
|
|
74
|
+
journal = {J. Graph. Tools},
|
|
75
|
+
month = nov,
|
|
76
|
+
pages = {25–30},
|
|
77
|
+
numpages = {6}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```bibtex
|
|
82
|
+
@inproceedings{10.1145/1198555.1198746,
|
|
83
|
+
author = {M\"{o}ller, Tomas and Trumbore, Ben},
|
|
84
|
+
title = {Fast, minimum storage ray/triangle intersection},
|
|
85
|
+
year = {2005},
|
|
86
|
+
isbn = {9781450378338},
|
|
87
|
+
publisher = {Association for Computing Machinery},
|
|
88
|
+
address = {New York, NY, USA},
|
|
89
|
+
url = {https://doi.org/10.1145/1198555.1198746},
|
|
90
|
+
doi = {10.1145/1198555.1198746},
|
|
91
|
+
pages = {7–es},
|
|
92
|
+
keywords = {base transformation, intersection, ray tracing, ray/triangle-intersection},
|
|
93
|
+
location = {Los Angeles, California},
|
|
94
|
+
series = {SIGGRAPH '05}
|
|
58
95
|
}
|
|
59
96
|
```
|
|
60
97
|
|
|
@@ -14,6 +14,10 @@ class BVH:
|
|
|
14
14
|
"""
|
|
15
15
|
Query the BVH with bounding boxes or segments. Returns (query_ids, object_ids).
|
|
16
16
|
"""
|
|
17
|
+
def query_ray(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
|
|
18
|
+
"""
|
|
19
|
+
Query the BVH with rays. Returns (query_ids, object_ids).
|
|
20
|
+
"""
|
|
17
21
|
def query_self(self) -> tuple[torch.Tensor, torch.Tensor]:
|
|
18
22
|
"""
|
|
19
23
|
Query the BVH against itself. Returns unique overlapping (query_ids, object_ids).
|
|
@@ -49,6 +53,10 @@ class MeshBVH(BVH):
|
|
|
49
53
|
"""
|
|
50
54
|
Construct MeshBVH from Triangle AABBs.
|
|
51
55
|
"""
|
|
56
|
+
def get_ray_intersection(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor, vertices: torch.Tensor, triangles: torch.Tensor, return_distance: bool = False) -> typing.Any:
|
|
57
|
+
"""
|
|
58
|
+
Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])
|
|
59
|
+
"""
|
|
52
60
|
def get_self_intersection(self, vertices: torch.Tensor, triangles: torch.Tensor) -> torch.Tensor:
|
|
53
61
|
"""
|
|
54
62
|
Find all self-intersecting triangle pairs
|
|
@@ -87,8 +95,14 @@ class TriangleMesh:
|
|
|
87
95
|
...
|
|
88
96
|
def get_non_manifold_vertices(self) -> torch.Tensor:
|
|
89
97
|
...
|
|
98
|
+
def get_ray_intersection(self, ray_origins: torch.Tensor, ray_dirs: torch.Tensor, return_distance: bool = False) -> typing.Any:
|
|
99
|
+
"""
|
|
100
|
+
Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])
|
|
101
|
+
"""
|
|
90
102
|
def get_self_intersection(self) -> torch.Tensor:
|
|
91
|
-
|
|
103
|
+
"""
|
|
104
|
+
Find all self-intersecting triangle pairs
|
|
105
|
+
"""
|
|
92
106
|
def get_vertices_to_triangle_map(self) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
|
93
107
|
...
|
|
94
108
|
def is_edge_manifold(self, allow_boundary_edge: bool = True) -> bool:
|
|
@@ -96,7 +110,9 @@ class TriangleMesh:
|
|
|
96
110
|
def is_manifold(self, allow_boundary_edge: bool = True) -> bool:
|
|
97
111
|
...
|
|
98
112
|
def is_self_intersection(self) -> bool:
|
|
99
|
-
|
|
113
|
+
"""
|
|
114
|
+
Check if there are any self-intersecting triangle pairs
|
|
115
|
+
"""
|
|
100
116
|
def is_vertex_manifold(self) -> bool:
|
|
101
117
|
...
|
|
102
118
|
def remove_triangles_by_mask(self, keep_mask: torch.Tensor) -> None:
|
|
Binary file
|
|
@@ -153,6 +153,52 @@ std::tuple<torch::Tensor, torch::Tensor> BVH::query_self()
|
|
|
153
153
|
);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
std::tuple<torch::Tensor, torch::Tensor> BVH::query_ray(
|
|
157
|
+
const torch::Tensor &ray_origins,
|
|
158
|
+
const torch::Tensor &ray_dirs)
|
|
159
|
+
{
|
|
160
|
+
CHECK_INPUT(ray_origins);
|
|
161
|
+
CHECK_INPUT(ray_dirs);
|
|
162
|
+
TORCH_CHECK(ray_origins.scalar_type() == torch::kFloat32, "ray_origins must be float32");
|
|
163
|
+
TORCH_CHECK(ray_dirs.scalar_type() == torch::kFloat32, "ray_dirs must be float32");
|
|
164
|
+
TORCH_CHECK(ray_origins.size(1) == 3, "ray_origins must have shape (M, 3)");
|
|
165
|
+
TORCH_CHECK(ray_dirs.size(1) == 3, "ray_dirs must have shape (M, 3)");
|
|
166
|
+
|
|
167
|
+
const uint32_t num_queries = static_cast<uint32_t>(ray_origins.size(0));
|
|
168
|
+
auto options_int64 = ray_origins.options().dtype(torch::kInt64);
|
|
169
|
+
|
|
170
|
+
if (num_queries == 0) {
|
|
171
|
+
throw std::runtime_error("Cannot query BVH with 0 queries.");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
torch::Tensor out_query_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
|
|
175
|
+
torch::Tensor out_object_ids = torch::empty({BVH_MAX_CAPACITY}, options_int64);
|
|
176
|
+
torch::Tensor hit_counter = torch::zeros({1}, options_int64);
|
|
177
|
+
|
|
178
|
+
bvh::query_ray(
|
|
179
|
+
num_queries,
|
|
180
|
+
this->num_objects,
|
|
181
|
+
reinterpret_cast<const float3 *>(ray_origins.data_ptr<float>()),
|
|
182
|
+
reinterpret_cast<const float3 *>(ray_dirs.data_ptr<float>()),
|
|
183
|
+
reinterpret_cast<const float3 *>(this->aabb_mins.data_ptr<float>()),
|
|
184
|
+
reinterpret_cast<const float3 *>(this->aabb_maxs.data_ptr<float>()),
|
|
185
|
+
reinterpret_cast<const int2 *>(this->bvh_children.data_ptr<int>()),
|
|
186
|
+
reinterpret_cast<const int *>(this->object_ids.data_ptr<int>()),
|
|
187
|
+
reinterpret_cast<int64_t *>(out_query_ids.data_ptr<int64_t>()),
|
|
188
|
+
reinterpret_cast<int64_t *>(out_object_ids.data_ptr<int64_t>()),
|
|
189
|
+
reinterpret_cast<int64_t *>(hit_counter.data_ptr<int64_t>()),
|
|
190
|
+
static_cast<int64_t>(BVH_MAX_CAPACITY)
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
int64_t num_hits = hit_counter.item<int64_t>();
|
|
194
|
+
num_hits = std::min(num_hits, static_cast<int64_t>(BVH_MAX_CAPACITY));
|
|
195
|
+
|
|
196
|
+
return std::make_tuple(
|
|
197
|
+
out_query_ids.slice(0, 0, num_hits),
|
|
198
|
+
out_object_ids.slice(0, 0, num_hits)
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
156
202
|
void bind_ds_bvh(py::module_& m)
|
|
157
203
|
{
|
|
158
204
|
py::class_<BVH>(m, "BVH")
|
|
@@ -167,5 +213,10 @@ void bind_ds_bvh(py::module_& m)
|
|
|
167
213
|
"Query the BVH with bounding boxes or segments. Returns (query_ids, object_ids).")
|
|
168
214
|
|
|
169
215
|
.def("query_self", &BVH::query_self,
|
|
170
|
-
"Query the BVH against itself. Returns unique overlapping (query_ids, object_ids).")
|
|
216
|
+
"Query the BVH against itself. Returns unique overlapping (query_ids, object_ids).")
|
|
217
|
+
|
|
218
|
+
.def("query_ray", &BVH::query_ray,
|
|
219
|
+
py::arg("ray_origins"),
|
|
220
|
+
py::arg("ray_dirs"),
|
|
221
|
+
"Query the BVH with rays. Returns (query_ids, object_ids).");
|
|
171
222
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#include <torch/extension.h>
|
|
2
|
+
#include "../../data_structure/mesh_bvh.h"
|
|
3
|
+
#include <pybind11/pybind11.h>
|
|
4
|
+
|
|
5
|
+
namespace py = pybind11;
|
|
6
|
+
|
|
7
|
+
void bind_ds_mesh_bvh(py::module_& m)
|
|
8
|
+
{
|
|
9
|
+
py::class_<MeshBVH, BVH>(m, "MeshBVH")
|
|
10
|
+
.def(py::init<const torch::Tensor &, const torch::Tensor &>(),
|
|
11
|
+
py::arg("in_aabb_mins"),
|
|
12
|
+
py::arg("in_aabb_maxs"),
|
|
13
|
+
"Construct MeshBVH from Triangle AABBs.")
|
|
14
|
+
.def("get_self_intersection", &MeshBVH::get_self_intersection,
|
|
15
|
+
py::arg("vertices"),
|
|
16
|
+
py::arg("triangles"),
|
|
17
|
+
"Find all self-intersecting triangle pairs")
|
|
18
|
+
.def("is_self_intersection", &MeshBVH::is_self_intersection,
|
|
19
|
+
py::arg("vertices"),
|
|
20
|
+
py::arg("triangles"),
|
|
21
|
+
"Check if there are any self-intersecting triangle pairs")
|
|
22
|
+
.def("get_ray_intersection", [](MeshBVH& self, const torch::Tensor& ray_origins, const torch::Tensor& ray_dirs, const torch::Tensor& vertices, const torch::Tensor& triangles, bool return_distance) -> py::object {
|
|
23
|
+
auto result = self.get_ray_intersection(ray_origins, ray_dirs, vertices, triangles, return_distance);
|
|
24
|
+
if (return_distance) {
|
|
25
|
+
return py::cast(result);
|
|
26
|
+
} else {
|
|
27
|
+
return py::cast(std::make_tuple(std::get<0>(result), std::get<1>(result), std::get<2>(result)));
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
py::arg("ray_origins"),
|
|
31
|
+
py::arg("ray_dirs"),
|
|
32
|
+
py::arg("vertices"),
|
|
33
|
+
py::arg("triangles"),
|
|
34
|
+
py::arg("return_distance") = false,
|
|
35
|
+
"Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])");
|
|
36
|
+
}
|
|
@@ -97,6 +97,15 @@ bool TriangleMesh::is_self_intersection()
|
|
|
97
97
|
return this->bvh.value().is_self_intersection(this->vertices, this->triangles);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor> TriangleMesh::get_ray_intersection(
|
|
101
|
+
const torch::Tensor &ray_origins,
|
|
102
|
+
const torch::Tensor &ray_dirs,
|
|
103
|
+
bool return_distance)
|
|
104
|
+
{
|
|
105
|
+
this->build_bvh();
|
|
106
|
+
return this->bvh.value().get_ray_intersection(ray_origins, ray_dirs, this->vertices, this->triangles, return_distance);
|
|
107
|
+
}
|
|
108
|
+
|
|
100
109
|
torch::Tensor TriangleMesh::get_triangle_areas()
|
|
101
110
|
{
|
|
102
111
|
if (!this->triangle_areas.defined())
|
|
@@ -313,8 +322,22 @@ void bind_ds_triangle_mesh(py::module_ &m)
|
|
|
313
322
|
.def_property_readonly("surface_area", &TriangleMesh::get_surface_area)
|
|
314
323
|
.def_property_readonly("bvh", &TriangleMesh::build_bvh)
|
|
315
324
|
.def("build_bvh", &TriangleMesh::build_bvh)
|
|
316
|
-
.def("get_self_intersection", &TriangleMesh::get_self_intersection
|
|
317
|
-
|
|
325
|
+
.def("get_self_intersection", &TriangleMesh::get_self_intersection,
|
|
326
|
+
"Find all self-intersecting triangle pairs")
|
|
327
|
+
.def("is_self_intersection", &TriangleMesh::is_self_intersection,
|
|
328
|
+
"Check if there are any self-intersecting triangle pairs")
|
|
329
|
+
.def("get_ray_intersection", [](TriangleMesh& self, const torch::Tensor& ray_origins, const torch::Tensor& ray_dirs, bool return_distance) -> py::object {
|
|
330
|
+
auto result = self.get_ray_intersection(ray_origins, ray_dirs, return_distance);
|
|
331
|
+
if (return_distance) {
|
|
332
|
+
return py::cast(result);
|
|
333
|
+
} else {
|
|
334
|
+
return py::cast(std::make_tuple(std::get<0>(result), std::get<1>(result), std::get<2>(result)));
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
py::arg("ray_origins"),
|
|
338
|
+
py::arg("ray_dirs"),
|
|
339
|
+
py::arg("return_distance") = false,
|
|
340
|
+
"Find all ray-triangle intersections. Returns (ray_ids, triangle_ids, intersect_points, [distances])")
|
|
318
341
|
.def_property_readonly("edges", &TriangleMesh::get_edges)
|
|
319
342
|
.def_property_readonly("edge_to_triangle_offsets", &TriangleMesh::get_edge_to_triangle_offsets)
|
|
320
343
|
.def_property_readonly("edge_to_triangle_counts", &TriangleMesh::get_edge_to_triangle_counts)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "bvh.h"
|
|
2
2
|
#include "zcurve.h"
|
|
3
|
+
#include "../primitive/ray.h"
|
|
3
4
|
|
|
4
5
|
#include <thrust/device_vector.h>
|
|
5
6
|
#include <thrust/device_ptr.h>
|
|
@@ -453,4 +454,92 @@ namespace bvh
|
|
|
453
454
|
max_capacity
|
|
454
455
|
);
|
|
455
456
|
}
|
|
457
|
+
|
|
458
|
+
__global__ void query_ray_bvh_kernel(
|
|
459
|
+
const uint32_t num_queries,
|
|
460
|
+
const uint32_t num_objects,
|
|
461
|
+
const float3* __restrict__ ray_origins,
|
|
462
|
+
const float3* __restrict__ ray_dirs,
|
|
463
|
+
const float3* __restrict__ bvh_aabb_mins,
|
|
464
|
+
const float3* __restrict__ bvh_aabb_maxs,
|
|
465
|
+
const int2* __restrict__ bvh_children,
|
|
466
|
+
const int* __restrict__ object_ids,
|
|
467
|
+
int64_t* __restrict__ out_query_ids,
|
|
468
|
+
int64_t* __restrict__ out_object_ids,
|
|
469
|
+
int64_t* __restrict__ hit_counter,
|
|
470
|
+
const int64_t max_capacity)
|
|
471
|
+
{
|
|
472
|
+
uint32_t q_idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
473
|
+
if (q_idx >= num_queries) return;
|
|
474
|
+
|
|
475
|
+
Ray ray(ray_origins[q_idx], ray_dirs[q_idx]);
|
|
476
|
+
|
|
477
|
+
int stack[BVH_STACK_SIZE];
|
|
478
|
+
int stack_ptr = 0;
|
|
479
|
+
stack[0] = 0;
|
|
480
|
+
|
|
481
|
+
while (stack_ptr >= 0)
|
|
482
|
+
{
|
|
483
|
+
int node_idx = stack[stack_ptr--];
|
|
484
|
+
float t_hit;
|
|
485
|
+
|
|
486
|
+
if (ray.is_intersect_aabb(bvh_aabb_mins[node_idx], bvh_aabb_maxs[node_idx], t_hit))
|
|
487
|
+
{
|
|
488
|
+
if (node_idx >= num_objects - 1)
|
|
489
|
+
{
|
|
490
|
+
int leaf_idx = node_idx - (num_objects - 1);
|
|
491
|
+
int original_obj_id = object_ids[leaf_idx];
|
|
492
|
+
|
|
493
|
+
uint64_t write_idx = (uint64_t)atomicAdd((unsigned long long int*)hit_counter, 1ULL);
|
|
494
|
+
|
|
495
|
+
if (write_idx < max_capacity) {
|
|
496
|
+
out_query_ids[write_idx] = q_idx;
|
|
497
|
+
out_object_ids[write_idx] = original_obj_id;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else
|
|
501
|
+
{
|
|
502
|
+
if (stack_ptr + 2 < BVH_STACK_SIZE)
|
|
503
|
+
{
|
|
504
|
+
int2 children = bvh_children[node_idx];
|
|
505
|
+
stack[++stack_ptr] = children.x;
|
|
506
|
+
stack[++stack_ptr] = children.y;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
void query_ray(
|
|
514
|
+
const uint32_t num_queries,
|
|
515
|
+
const uint32_t num_objects,
|
|
516
|
+
const float3* __restrict__ ray_origins,
|
|
517
|
+
const float3* __restrict__ ray_dirs,
|
|
518
|
+
const float3* __restrict__ bvh_aabb_mins,
|
|
519
|
+
const float3* __restrict__ bvh_aabb_maxs,
|
|
520
|
+
const int2* __restrict__ bvh_children,
|
|
521
|
+
const int* __restrict__ object_ids,
|
|
522
|
+
int64_t* __restrict__ out_query_ids,
|
|
523
|
+
int64_t* __restrict__ out_object_ids,
|
|
524
|
+
int64_t* __restrict__ hit_counter,
|
|
525
|
+
const int64_t max_capacity)
|
|
526
|
+
{
|
|
527
|
+
uint32_t threads = NTHREADS;
|
|
528
|
+
uint32_t blocks = (num_queries + threads - 1) / threads;
|
|
529
|
+
|
|
530
|
+
query_ray_bvh_kernel<<<blocks, threads>>>(
|
|
531
|
+
num_queries,
|
|
532
|
+
num_objects,
|
|
533
|
+
ray_origins,
|
|
534
|
+
ray_dirs,
|
|
535
|
+
bvh_aabb_mins,
|
|
536
|
+
bvh_aabb_maxs,
|
|
537
|
+
bvh_children,
|
|
538
|
+
object_ids,
|
|
539
|
+
out_query_ids,
|
|
540
|
+
out_object_ids,
|
|
541
|
+
hit_counter,
|
|
542
|
+
max_capacity
|
|
543
|
+
);
|
|
544
|
+
}
|
|
456
545
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "../maths/maths.h"
|
|
5
5
|
#include "../constants.h"
|
|
6
6
|
#include "../primitive/aabb.h"
|
|
7
|
+
#include "../primitive/ray.h"
|
|
7
8
|
|
|
8
9
|
#include <torch/extension.h>
|
|
9
10
|
#include <cuda_runtime.h>
|
|
@@ -29,6 +30,10 @@ public:
|
|
|
29
30
|
const torch::Tensor &query_aabb_maxs);
|
|
30
31
|
|
|
31
32
|
std::tuple<torch::Tensor, torch::Tensor> query_self();
|
|
33
|
+
|
|
34
|
+
std::tuple<torch::Tensor, torch::Tensor> query_ray(
|
|
35
|
+
const torch::Tensor &ray_origins,
|
|
36
|
+
const torch::Tensor &ray_dirs);
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
namespace bvh
|
|
@@ -69,6 +74,20 @@ namespace bvh
|
|
|
69
74
|
int64_t *__restrict__ out_object_ids,
|
|
70
75
|
int64_t *__restrict__ hit_counter,
|
|
71
76
|
const int64_t max_capacity);
|
|
77
|
+
|
|
78
|
+
__host__ void query_ray(
|
|
79
|
+
const uint32_t num_queries,
|
|
80
|
+
const uint32_t num_objects,
|
|
81
|
+
const float3 *__restrict__ ray_origins,
|
|
82
|
+
const float3 *__restrict__ ray_dirs,
|
|
83
|
+
const float3 *__restrict__ bvh_aabb_mins,
|
|
84
|
+
const float3 *__restrict__ bvh_aabb_maxs,
|
|
85
|
+
const int2 *__restrict__ bvh_children,
|
|
86
|
+
const int *__restrict__ object_ids,
|
|
87
|
+
int64_t *__restrict__ out_query_ids,
|
|
88
|
+
int64_t *__restrict__ out_object_ids,
|
|
89
|
+
int64_t *__restrict__ hit_counter,
|
|
90
|
+
const int64_t max_capacity);
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
#endif // BVH_H
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#include "mesh_bvh.h"
|
|
2
|
+
#include "../primitive/triangles.h"
|
|
3
|
+
#include <thrust/device_vector.h>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
__global__ void filter_self_intersections_kernel(
|
|
7
|
+
const int num_pairs,
|
|
8
|
+
const int64_t* query_ids,
|
|
9
|
+
const int64_t* object_ids,
|
|
10
|
+
const float3* vertices,
|
|
11
|
+
const int3* triangles,
|
|
12
|
+
int64_t* out_query_ids,
|
|
13
|
+
int64_t* out_object_ids,
|
|
14
|
+
int64_t* valid_counter)
|
|
15
|
+
{
|
|
16
|
+
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
17
|
+
if (idx >= num_pairs) return;
|
|
18
|
+
|
|
19
|
+
int64_t idA = query_ids[idx];
|
|
20
|
+
int64_t idB = object_ids[idx];
|
|
21
|
+
|
|
22
|
+
int3 triA = triangles[idA];
|
|
23
|
+
int3 triB = triangles[idB];
|
|
24
|
+
|
|
25
|
+
// Filter shared vertices
|
|
26
|
+
if (triA.x == triB.x || triA.x == triB.y || triA.x == triB.z ||
|
|
27
|
+
triA.y == triB.x || triA.y == triB.y || triA.y == triB.z ||
|
|
28
|
+
triA.z == triB.x || triA.z == triB.y || triA.z == triB.z) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Triangle T1(vertices[triA.x], vertices[triA.y], vertices[triA.z]);
|
|
33
|
+
Triangle T2(vertices[triB.x], vertices[triB.y], vertices[triB.z]);
|
|
34
|
+
|
|
35
|
+
if (triangle::test_intersection(T1, T2)) {
|
|
36
|
+
uint64_t write_idx = (uint64_t)atomicAdd((unsigned long long int*)valid_counter, 1ULL);
|
|
37
|
+
out_query_ids[write_idx] = idA;
|
|
38
|
+
out_object_ids[write_idx] = idB;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
torch::Tensor MeshBVH::get_self_intersection(
|
|
43
|
+
const torch::Tensor &vertices,
|
|
44
|
+
const torch::Tensor &triangles)
|
|
45
|
+
{
|
|
46
|
+
// 1. Broad-phase AABB overlap query
|
|
47
|
+
auto [query_ids, object_ids] = this->query_self();
|
|
48
|
+
|
|
49
|
+
int num_pairs = query_ids.size(0);
|
|
50
|
+
if (num_pairs == 0) {
|
|
51
|
+
return torch::empty({0, 2}, torch::TensorOptions().dtype(torch::kInt64).device(query_ids.device()));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 2. Narrow-phase intersection
|
|
55
|
+
auto options_i64 = torch::TensorOptions().dtype(torch::kInt64).device(query_ids.device());
|
|
56
|
+
torch::Tensor out_query_ids = torch::empty({num_pairs}, options_i64);
|
|
57
|
+
torch::Tensor out_object_ids = torch::empty({num_pairs}, options_i64);
|
|
58
|
+
torch::Tensor valid_counter = torch::zeros({1}, options_i64);
|
|
59
|
+
|
|
60
|
+
int threads = NTHREADS;
|
|
61
|
+
int blocks = (num_pairs + threads - 1) / threads;
|
|
62
|
+
|
|
63
|
+
filter_self_intersections_kernel<<<blocks, threads>>>(
|
|
64
|
+
num_pairs,
|
|
65
|
+
query_ids.data_ptr<int64_t>(),
|
|
66
|
+
object_ids.data_ptr<int64_t>(),
|
|
67
|
+
(const float3*)vertices.data_ptr<float>(),
|
|
68
|
+
(const int3*)triangles.data_ptr<int>(),
|
|
69
|
+
out_query_ids.data_ptr<int64_t>(),
|
|
70
|
+
out_object_ids.data_ptr<int64_t>(),
|
|
71
|
+
valid_counter.data_ptr<int64_t>()
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
int64_t h_valid_counter = valid_counter.item<int64_t>();
|
|
75
|
+
|
|
76
|
+
if (h_valid_counter == 0) {
|
|
77
|
+
return torch::empty({0, 2}, options_i64);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
out_query_ids = out_query_ids.slice(0, 0, h_valid_counter).unsqueeze(1);
|
|
81
|
+
out_object_ids = out_object_ids.slice(0, 0, h_valid_counter).unsqueeze(1);
|
|
82
|
+
|
|
83
|
+
return torch::cat({out_query_ids, out_object_ids}, 1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
bool MeshBVH::is_self_intersection(
|
|
87
|
+
const torch::Tensor &vertices,
|
|
88
|
+
const torch::Tensor &triangles)
|
|
89
|
+
{
|
|
90
|
+
torch::Tensor pairs = this->get_self_intersection(vertices, triangles);
|
|
91
|
+
return pairs.size(0) > 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
__global__ void filter_ray_triangle_intersections_kernel(
|
|
95
|
+
const int num_pairs,
|
|
96
|
+
const int64_t* query_ids,
|
|
97
|
+
const int64_t* object_ids,
|
|
98
|
+
const float3* ray_origins,
|
|
99
|
+
const float3* ray_dirs,
|
|
100
|
+
const float3* vertices,
|
|
101
|
+
const int3* triangles,
|
|
102
|
+
int64_t* out_query_ids,
|
|
103
|
+
int64_t* out_object_ids,
|
|
104
|
+
float3* out_intersect_pts,
|
|
105
|
+
float* out_distances,
|
|
106
|
+
bool return_distance,
|
|
107
|
+
int64_t* valid_counter)
|
|
108
|
+
{
|
|
109
|
+
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
110
|
+
if (idx >= num_pairs) return;
|
|
111
|
+
|
|
112
|
+
int64_t ray_id = query_ids[idx];
|
|
113
|
+
int64_t tri_id = object_ids[idx];
|
|
114
|
+
|
|
115
|
+
Ray ray(ray_origins[ray_id], ray_dirs[ray_id]);
|
|
116
|
+
|
|
117
|
+
int3 tri = triangles[tri_id];
|
|
118
|
+
Triangle T(vertices[tri.x], vertices[tri.y], vertices[tri.z]);
|
|
119
|
+
|
|
120
|
+
float t_hit, u, v;
|
|
121
|
+
if (T.is_intersect_ray(ray, t_hit, u, v)) {
|
|
122
|
+
uint64_t write_idx = (uint64_t)atomicAdd((unsigned long long int*)valid_counter, 1ULL);
|
|
123
|
+
out_query_ids[write_idx] = ray_id;
|
|
124
|
+
out_object_ids[write_idx] = tri_id;
|
|
125
|
+
out_intersect_pts[write_idx] = ray.at(t_hit);
|
|
126
|
+
if (return_distance) {
|
|
127
|
+
out_distances[write_idx] = t_hit;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor> MeshBVH::get_ray_intersection(
|
|
133
|
+
const torch::Tensor &ray_origins,
|
|
134
|
+
const torch::Tensor &ray_dirs,
|
|
135
|
+
const torch::Tensor &vertices,
|
|
136
|
+
const torch::Tensor &triangles,
|
|
137
|
+
bool return_distance)
|
|
138
|
+
{
|
|
139
|
+
// 1. Broad-phase BVH query
|
|
140
|
+
auto [query_ids, object_ids] = this->query_ray(ray_origins, ray_dirs);
|
|
141
|
+
|
|
142
|
+
int num_pairs = query_ids.size(0);
|
|
143
|
+
auto options_i64 = torch::TensorOptions().dtype(torch::kInt64).device(query_ids.device());
|
|
144
|
+
auto options_f32 = torch::TensorOptions().dtype(torch::kFloat32).device(query_ids.device());
|
|
145
|
+
|
|
146
|
+
if (num_pairs == 0) {
|
|
147
|
+
return std::make_tuple(
|
|
148
|
+
torch::empty({0}, options_i64),
|
|
149
|
+
torch::empty({0}, options_i64),
|
|
150
|
+
torch::empty({0, 3}, options_f32),
|
|
151
|
+
torch::empty({0}, options_f32)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 2. Narrow-phase intersection
|
|
156
|
+
torch::Tensor out_query_ids = torch::empty({num_pairs}, options_i64);
|
|
157
|
+
torch::Tensor out_object_ids = torch::empty({num_pairs}, options_i64);
|
|
158
|
+
torch::Tensor out_intersect_pts = torch::empty({num_pairs, 3}, options_f32);
|
|
159
|
+
|
|
160
|
+
torch::Tensor out_distances;
|
|
161
|
+
if (return_distance) {
|
|
162
|
+
out_distances = torch::empty({num_pairs}, options_f32);
|
|
163
|
+
} else {
|
|
164
|
+
out_distances = torch::empty({0}, options_f32);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
torch::Tensor valid_counter = torch::zeros({1}, options_i64);
|
|
168
|
+
|
|
169
|
+
int threads = NTHREADS;
|
|
170
|
+
int blocks = (num_pairs + threads - 1) / threads;
|
|
171
|
+
|
|
172
|
+
filter_ray_triangle_intersections_kernel<<<blocks, threads>>>(
|
|
173
|
+
num_pairs,
|
|
174
|
+
query_ids.data_ptr<int64_t>(),
|
|
175
|
+
object_ids.data_ptr<int64_t>(),
|
|
176
|
+
(const float3*)ray_origins.data_ptr<float>(),
|
|
177
|
+
(const float3*)ray_dirs.data_ptr<float>(),
|
|
178
|
+
(const float3*)vertices.data_ptr<float>(),
|
|
179
|
+
(const int3*)triangles.data_ptr<int>(),
|
|
180
|
+
out_query_ids.data_ptr<int64_t>(),
|
|
181
|
+
out_object_ids.data_ptr<int64_t>(),
|
|
182
|
+
(float3*)out_intersect_pts.data_ptr<float>(),
|
|
183
|
+
return_distance ? out_distances.data_ptr<float>() : nullptr,
|
|
184
|
+
return_distance,
|
|
185
|
+
valid_counter.data_ptr<int64_t>()
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
int64_t h_valid_counter = valid_counter.item<int64_t>();
|
|
189
|
+
|
|
190
|
+
if (h_valid_counter == 0) {
|
|
191
|
+
return std::make_tuple(
|
|
192
|
+
torch::empty({0}, options_i64),
|
|
193
|
+
torch::empty({0}, options_i64),
|
|
194
|
+
torch::empty({0, 3}, options_f32),
|
|
195
|
+
torch::empty({0}, options_f32)
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return std::make_tuple(
|
|
200
|
+
out_query_ids.slice(0, 0, h_valid_counter),
|
|
201
|
+
out_object_ids.slice(0, 0, h_valid_counter),
|
|
202
|
+
out_intersect_pts.slice(0, 0, h_valid_counter),
|
|
203
|
+
return_distance ? out_distances.slice(0, 0, h_valid_counter) : out_distances
|
|
204
|
+
);
|
|
205
|
+
}
|