conquer3d 0.5.2__tar.gz → 0.5.4__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.5.2/conquer3d.egg-info → conquer3d-0.5.4}/PKG-INFO +1 -1
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/_C.so +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/grid.cpp +149 -14
- conquer3d-0.5.4/conquer3d/csrc/binds/ops/volint.cpp +96 -0
- conquer3d-0.5.4/conquer3d/csrc/data_structure/grid.cu +109 -0
- conquer3d-0.5.4/conquer3d/csrc/data_structure/grid.h +22 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f4x4.h +1 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mc.cu +50 -44
- conquer3d-0.5.4/conquer3d/csrc/ops/volint.cu +121 -0
- conquer3d-0.5.4/conquer3d/csrc/ops/volint.h +23 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/pybind.cpp +2 -0
- conquer3d-0.5.4/conquer3d/data/dataset/__init__.py +14 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/dataset/digit3d.py +42 -10
- conquer3d-0.5.4/conquer3d/data/dataset/redwood.py +138 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data_structure/__init__.py +5 -1
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data_structure/grid.py +43 -8
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/__init__.py +3 -1
- conquer3d-0.5.4/conquer3d/ops/volint.py +55 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4/conquer3d.egg-info}/PKG-INFO +1 -1
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d.egg-info/SOURCES.txt +7 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/pyproject.toml +1 -1
- {conquer3d-0.5.2 → conquer3d-0.5.4}/setup.py +5 -0
- conquer3d-0.5.2/conquer3d/data/dataset/__init__.py +0 -5
- {conquer3d-0.5.2 → conquer3d-0.5.4}/LICENSE +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/MANIFEST.in +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/README.md +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/_C.pyi +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/conversion/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/conversion/grid.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/conversion/mesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/conversion/tmesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/creation/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/creation/triangle_creation.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/creation/triangle_creation.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/bvh.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/gs_bvh.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/kdtree.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/mesh_bvh.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/pgs_bvh.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/triangle_mesh.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/data_structure/zcurve.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/ops/chamfer.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/ops/flood_fill.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/ops/mc.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/ops/mtg.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/primitive/gs.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/primitive/pgs.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/primitive/ray.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/binds/primitive/triangle.cpp +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/check.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/constants.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/creation/triangle_creation.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/bvh.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/bvh.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/gs_bvh.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/kdtree.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/kdtree.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/mesh_bvh.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/mesh_bvh.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/pgs_bvh.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/triangle_mesh.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/triangle_mesh.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/zcurve.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/data_structure/zcurve.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f2x2.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f3x1.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f3x3.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f3x4.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/f4x1.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/maths.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/maths/ops.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/chamfer.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/chamfer.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/flood_fill.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/flood_fill.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mc.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mc_data.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mtg.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mtg.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/ops/mtg_data.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/aabb.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/edge.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/gs.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/gs.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/gs_aabb.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/gs_math.cuh +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/pgs.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/pgs.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/pgs_aabb.cu +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/pgs_math.cuh +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/ray.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/csrc/primitive/triangle.h +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/assets/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/assets/common.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/assets/iphigenia.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/collate/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/collate/mesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/collate/sparse_tensor.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/dataset/base_mesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/dataset/mesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/transform/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/transform/base.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/transform/ops.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data/transform/vertex.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data_structure/bmesh.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/data_structure/sort.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/io/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/io/obj.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/io/off.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/delaunay_triangulation.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/diff_marching_cubes.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/diff_marching_tetrahedra_grid.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/distance.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/marching_cubes.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/marching_tetrahedra.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/ops/marching_tetrahedra_grid.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/primitive/__init__.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/primitive/gs.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d/primitive/pgs.py +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d.egg-info/dependency_links.txt +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d.egg-info/not-zip-safe +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d.egg-info/requires.txt +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/conquer3d.egg-info/top_level.txt +0 -0
- {conquer3d-0.5.2 → conquer3d-0.5.4}/setup.cfg +0 -0
|
Binary file
|
|
@@ -6,14 +6,17 @@
|
|
|
6
6
|
#include <vector>
|
|
7
7
|
#include "../../data_structure/mesh_bvh.h"
|
|
8
8
|
#include "../../data_structure/triangle_mesh.h"
|
|
9
|
+
#include "../../data_structure/grid.h"
|
|
10
|
+
#include <cuda_runtime.h>
|
|
9
11
|
|
|
10
12
|
namespace py = pybind11;
|
|
11
13
|
|
|
12
|
-
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor
|
|
14
|
+
std::tuple<torch::Tensor, torch::Tensor, std::optional<torch::Tensor>> create_voxel_grid(
|
|
13
15
|
std::vector<float> grid_min,
|
|
14
16
|
std::vector<float> grid_max,
|
|
15
17
|
std::vector<int64_t> res,
|
|
16
|
-
std::string device_str
|
|
18
|
+
std::string device_str,
|
|
19
|
+
bool return_idx_grids
|
|
17
20
|
) {
|
|
18
21
|
TORCH_CHECK(grid_min.size() == 3, "grid_min must have 3 elements.");
|
|
19
22
|
TORCH_CHECK(grid_max.size() == 3, "grid_max must have 3 elements.");
|
|
@@ -59,13 +62,16 @@ std::tuple<torch::Tensor, torch::Tensor, torch::Tensor> create_voxel_grid(
|
|
|
59
62
|
|
|
60
63
|
auto voxels = torch::stack({v0, v1, v2, v3, v4, v5, v6, v7}, -1).view({-1, 8}).contiguous().to(torch::kInt32);
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
std::optional<torch::Tensor> opt_idx_grids = std::nullopt;
|
|
66
|
+
if (return_idx_grids) {
|
|
67
|
+
auto i_v = torch::arange(rx, options_int);
|
|
68
|
+
auto j_v = torch::arange(ry, options_int);
|
|
69
|
+
auto k_v = torch::arange(rz, options_int);
|
|
70
|
+
auto idx_grids_v = torch::meshgrid({i_v, j_v, k_v}, "ij");
|
|
71
|
+
opt_idx_grids = torch::stack({idx_grids_v[0].flatten(), idx_grids_v[1].flatten(), idx_grids_v[2].flatten()}, -1).contiguous();
|
|
72
|
+
}
|
|
67
73
|
|
|
68
|
-
return std::make_tuple(grid_vertices, voxels,
|
|
74
|
+
return std::make_tuple(grid_vertices, voxels, opt_idx_grids);
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
torch::Tensor compute_grid_normal(torch::Tensor sdf, torch::Tensor grid_vertices, torch::Tensor idx_grids, std::vector<int64_t> res) {
|
|
@@ -141,11 +147,12 @@ torch::Tensor compute_active_voxels(torch::Tensor voxels, torch::Tensor sdf, flo
|
|
|
141
147
|
return active_indices;
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor
|
|
150
|
+
std::tuple<torch::Tensor, torch::Tensor, std::optional<torch::Tensor>> create_voxel_grid_from_tmesh(
|
|
145
151
|
std::vector<float> grid_min,
|
|
146
152
|
std::vector<float> grid_max,
|
|
147
153
|
std::vector<int64_t> res,
|
|
148
|
-
TriangleMesh &tmesh
|
|
154
|
+
TriangleMesh &tmesh,
|
|
155
|
+
bool return_unique_vert_ids = true
|
|
149
156
|
) {
|
|
150
157
|
TORCH_CHECK(grid_min.size() == 3, "grid_min must have 3 elements.");
|
|
151
158
|
TORCH_CHECK(grid_max.size() == 3, "grid_max must have 3 elements.");
|
|
@@ -165,7 +172,131 @@ std::tuple<torch::Tensor, torch::Tensor, torch::Tensor> create_voxel_grid_from_t
|
|
|
165
172
|
return std::make_tuple(
|
|
166
173
|
torch::empty({0, 3}, torch::TensorOptions().dtype(torch::kFloat32).device(vertices.device())),
|
|
167
174
|
torch::empty({0, 8}, torch::TensorOptions().dtype(torch::kInt32).device(vertices.device())),
|
|
168
|
-
torch::empty({0}, torch::TensorOptions().dtype(torch::kInt64).device(vertices.device()))
|
|
175
|
+
return_unique_vert_ids ? std::make_optional(torch::empty({0}, torch::TensorOptions().dtype(torch::kInt64).device(vertices.device()))) : std::nullopt
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
auto vi = active_voxel_ids.div((ry - 1) * (rz - 1), "trunc");
|
|
180
|
+
auto rem = active_voxel_ids.remainder((ry - 1) * (rz - 1));
|
|
181
|
+
auto vj = rem.div(rz - 1, "trunc");
|
|
182
|
+
auto vk = rem.remainder(rz - 1);
|
|
183
|
+
|
|
184
|
+
auto v0 = vi * ry * rz + vj * rz + vk;
|
|
185
|
+
auto v1 = (vi + 1) * ry * rz + vj * rz + vk;
|
|
186
|
+
auto v2 = (vi + 1) * ry * rz + (vj + 1) * rz + vk;
|
|
187
|
+
auto v3 = vi * ry * rz + (vj + 1) * rz + vk;
|
|
188
|
+
auto v4 = vi * ry * rz + vj * rz + (vk + 1);
|
|
189
|
+
auto v5 = (vi + 1) * ry * rz + vj * rz + (vk + 1);
|
|
190
|
+
auto v6 = (vi + 1) * ry * rz + (vj + 1) * rz + (vk + 1);
|
|
191
|
+
auto v7 = vi * ry * rz + (vj + 1) * rz + (vk + 1);
|
|
192
|
+
|
|
193
|
+
auto active_voxels = torch::stack({v0, v1, v2, v3, v4, v5, v6, v7}, -1);
|
|
194
|
+
|
|
195
|
+
torch::Tensor unique_vert_ids, inverse_indices, counts;
|
|
196
|
+
std::tie(unique_vert_ids, inverse_indices, counts) = torch::_unique2(active_voxels.flatten(), true, true, false);
|
|
197
|
+
|
|
198
|
+
auto remapped_voxels = inverse_indices.view({-1, 8}).to(torch::kInt32);
|
|
199
|
+
|
|
200
|
+
auto u_i = unique_vert_ids.div(ry * rz, "trunc");
|
|
201
|
+
auto u_rem = unique_vert_ids.remainder(ry * rz);
|
|
202
|
+
auto u_j = u_rem.div(rz, "trunc");
|
|
203
|
+
auto u_k = u_rem.remainder(rz);
|
|
204
|
+
|
|
205
|
+
float spacing_x = (grid_max[0] - grid_min[0]) / (rx - 1);
|
|
206
|
+
float spacing_y = (grid_max[1] - grid_min[1]) / (ry - 1);
|
|
207
|
+
float spacing_z = (grid_max[2] - grid_min[2]) / (rz - 1);
|
|
208
|
+
|
|
209
|
+
auto x = grid_min[0] + u_i.to(torch::kFloat32) * spacing_x;
|
|
210
|
+
auto y = grid_min[1] + u_j.to(torch::kFloat32) * spacing_y;
|
|
211
|
+
auto z = grid_min[2] + u_k.to(torch::kFloat32) * spacing_z;
|
|
212
|
+
|
|
213
|
+
auto sparse_grid_vertices = torch::stack({x, y, z}, 1).contiguous();
|
|
214
|
+
|
|
215
|
+
return std::make_tuple(sparse_grid_vertices, remapped_voxels, return_unique_vert_ids ? std::make_optional(unique_vert_ids) : std::nullopt);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
torch::Tensor get_active_voxel_ids_from_depth_py(
|
|
219
|
+
torch::Tensor depth_image,
|
|
220
|
+
torch::Tensor c2w_tensor,
|
|
221
|
+
torch::Tensor intrinsics_inv_tensor,
|
|
222
|
+
std::vector<float> grid_min,
|
|
223
|
+
std::vector<float> grid_max,
|
|
224
|
+
std::vector<int64_t> res,
|
|
225
|
+
bool activate_neighbor = false,
|
|
226
|
+
float trunc_margin = 0.0f
|
|
227
|
+
) {
|
|
228
|
+
TORCH_CHECK(depth_image.is_cuda(), "depth_image must be a CUDA tensor");
|
|
229
|
+
TORCH_CHECK(depth_image.dim() == 2, "depth_image must be 2D (H, W)");
|
|
230
|
+
|
|
231
|
+
int image_height = depth_image.size(0);
|
|
232
|
+
int image_width = depth_image.size(1);
|
|
233
|
+
int num_pixels = image_height * image_width;
|
|
234
|
+
|
|
235
|
+
float4x4 c2w;
|
|
236
|
+
auto c2w_cpu = c2w_tensor.to(torch::kFloat32).cpu().contiguous();
|
|
237
|
+
auto c2w_a = c2w_cpu.accessor<float, 2>();
|
|
238
|
+
for(int r=0; r<4; ++r) for(int c=0; c<4; ++c) c2w.m[r][c] = c2w_a[r][c];
|
|
239
|
+
|
|
240
|
+
float3x3 intrinsics_inv;
|
|
241
|
+
auto int_cpu = intrinsics_inv_tensor.to(torch::kFloat32).cpu().contiguous();
|
|
242
|
+
auto int_a = int_cpu.accessor<float, 2>();
|
|
243
|
+
for(int r=0; r<3; ++r) for(int c=0; c<3; ++c) intrinsics_inv.m[r][c] = int_a[r][c];
|
|
244
|
+
|
|
245
|
+
float3 g_min; g_min.x = grid_min[0]; g_min.y = grid_min[1]; g_min.z = grid_min[2];
|
|
246
|
+
float3 g_max; g_max.x = grid_max[0]; g_max.y = grid_max[1]; g_max.z = grid_max[2];
|
|
247
|
+
int3 g_res; g_res.x = res[0]; g_res.y = res[1]; g_res.z = res[2];
|
|
248
|
+
|
|
249
|
+
int max_pad_x = std::ceil(trunc_margin / ((grid_max[0] - grid_min[0]) / (res[0] - 1)));
|
|
250
|
+
int max_pad_y = std::ceil(trunc_margin / ((grid_max[1] - grid_min[1]) / (res[1] - 1)));
|
|
251
|
+
int max_pad_z = std::ceil(trunc_margin / ((grid_max[2] - grid_min[2]) / (res[2] - 1)));
|
|
252
|
+
int max_neighbors = activate_neighbor ? ((2 * max_pad_x + 1) * (2 * max_pad_y + 1) * (2 * max_pad_z + 1)) : 1;
|
|
253
|
+
|
|
254
|
+
int64_t max_voxels = (int64_t)num_pixels * max_neighbors;
|
|
255
|
+
auto options = torch::TensorOptions().device(torch::kCUDA).dtype(torch::kInt64);
|
|
256
|
+
auto out_voxel_ids = torch::empty({max_voxels}, options);
|
|
257
|
+
|
|
258
|
+
auto valid_counter_tensor = torch::zeros({1}, options);
|
|
259
|
+
|
|
260
|
+
grid::get_active_voxel_ids_from_depth(
|
|
261
|
+
num_pixels,
|
|
262
|
+
depth_image.data_ptr<float>(),
|
|
263
|
+
c2w,
|
|
264
|
+
intrinsics_inv,
|
|
265
|
+
image_width,
|
|
266
|
+
image_height,
|
|
267
|
+
g_min,
|
|
268
|
+
g_max,
|
|
269
|
+
g_res,
|
|
270
|
+
out_voxel_ids.data_ptr<int64_t>(),
|
|
271
|
+
reinterpret_cast<unsigned long long*>(valid_counter_tensor.data_ptr<int64_t>()),
|
|
272
|
+
activate_neighbor,
|
|
273
|
+
trunc_margin
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
int64_t valid_count = valid_counter_tensor.item<int64_t>();
|
|
277
|
+
return out_voxel_ids.slice(0, 0, valid_count);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
std::tuple<torch::Tensor, torch::Tensor, std::optional<torch::Tensor>> build_sparse_grid_from_active_voxels(
|
|
281
|
+
torch::Tensor active_voxel_ids,
|
|
282
|
+
std::vector<float> grid_min,
|
|
283
|
+
std::vector<float> grid_max,
|
|
284
|
+
std::vector<int64_t> res,
|
|
285
|
+
bool return_unique_vert_ids = true
|
|
286
|
+
) {
|
|
287
|
+
TORCH_CHECK(grid_min.size() == 3, "grid_min must have 3 elements.");
|
|
288
|
+
TORCH_CHECK(grid_max.size() == 3, "grid_max must have 3 elements.");
|
|
289
|
+
TORCH_CHECK(res.size() == 3, "res must have 3 elements.");
|
|
290
|
+
|
|
291
|
+
int64_t rx = res[0];
|
|
292
|
+
int64_t ry = res[1];
|
|
293
|
+
int64_t rz = res[2];
|
|
294
|
+
|
|
295
|
+
if (active_voxel_ids.size(0) == 0) {
|
|
296
|
+
return std::make_tuple(
|
|
297
|
+
torch::empty({0, 3}, torch::TensorOptions().dtype(torch::kFloat32).device(active_voxel_ids.device())),
|
|
298
|
+
torch::empty({0, 8}, torch::TensorOptions().dtype(torch::kInt32).device(active_voxel_ids.device())),
|
|
299
|
+
return_unique_vert_ids ? std::make_optional(torch::empty({0}, torch::TensorOptions().dtype(torch::kInt64).device(active_voxel_ids.device()))) : std::nullopt
|
|
169
300
|
);
|
|
170
301
|
}
|
|
171
302
|
|
|
@@ -205,16 +336,20 @@ std::tuple<torch::Tensor, torch::Tensor, torch::Tensor> create_voxel_grid_from_t
|
|
|
205
336
|
|
|
206
337
|
auto sparse_grid_vertices = torch::stack({x, y, z}, 1).contiguous();
|
|
207
338
|
|
|
208
|
-
return std::make_tuple(sparse_grid_vertices, remapped_voxels, unique_vert_ids);
|
|
339
|
+
return std::make_tuple(sparse_grid_vertices, remapped_voxels, return_unique_vert_ids ? std::make_optional(unique_vert_ids) : std::nullopt);
|
|
209
340
|
}
|
|
210
341
|
|
|
211
342
|
void bind_ds_grid(py::module_& m) {
|
|
212
343
|
m.def("create_voxel_grid", &create_voxel_grid, "Creates a structured 3D voxel grid.",
|
|
213
|
-
py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("device_str") = "cuda");
|
|
344
|
+
py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("device_str") = "cuda", py::arg("return_idx_grids") = true);
|
|
214
345
|
m.def("create_voxel_grid_from_tmesh", &create_voxel_grid_from_tmesh, "Creates a sparse 3D voxel grid strictly around the surface.",
|
|
215
|
-
py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("tmesh"));
|
|
346
|
+
py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("tmesh"), py::arg("return_unique_vert_ids") = true);
|
|
216
347
|
m.def("compute_grid_normal", &compute_grid_normal, "Computes surface normals for a grid.",
|
|
217
348
|
py::arg("sdf"), py::arg("grid_vertices"), py::arg("idx_grids"), py::arg("res"));
|
|
218
349
|
m.def("compute_active_voxels", &compute_active_voxels, "Computes active voxels intersecting the surface",
|
|
219
350
|
py::arg("voxels"), py::arg("sdf"), py::arg("iso"));
|
|
351
|
+
m.def("get_active_voxel_ids_from_depth", &get_active_voxel_ids_from_depth_py, "Extracts active voxel IDs from a single depth map.",
|
|
352
|
+
py::arg("depth_image"), py::arg("c2w_tensor"), py::arg("intrinsics_inv_tensor"), py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("activate_neighbor") = false, py::arg("trunc_margin") = 0.0f);
|
|
353
|
+
m.def("build_sparse_grid_from_active_voxels", &build_sparse_grid_from_active_voxels, "Builds sparse grid from unique voxel IDs.",
|
|
354
|
+
py::arg("active_voxel_ids"), py::arg("grid_min"), py::arg("grid_max"), py::arg("res"), py::arg("return_unique_vert_ids") = true);
|
|
220
355
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#include <torch/extension.h>
|
|
2
|
+
#include <pybind11/pybind11.h>
|
|
3
|
+
#include "../../ops/volint.h"
|
|
4
|
+
#include "../../maths/maths.h"
|
|
5
|
+
|
|
6
|
+
namespace py = pybind11;
|
|
7
|
+
|
|
8
|
+
void single_view_volume_integral_bind(
|
|
9
|
+
torch::Tensor grid_vertices,
|
|
10
|
+
torch::Tensor sdf,
|
|
11
|
+
torch::Tensor weight,
|
|
12
|
+
std::optional<torch::Tensor> color_opt,
|
|
13
|
+
torch::Tensor depth_image,
|
|
14
|
+
std::optional<torch::Tensor> color_image_opt,
|
|
15
|
+
torch::Tensor extrinsics,
|
|
16
|
+
torch::Tensor intrinsics,
|
|
17
|
+
float trunc_margin,
|
|
18
|
+
int mode
|
|
19
|
+
) {
|
|
20
|
+
TORCH_CHECK(grid_vertices.is_cuda() && grid_vertices.is_contiguous(), "grid_vertices must be CUDA and contiguous");
|
|
21
|
+
TORCH_CHECK(sdf.is_cuda() && sdf.is_contiguous(), "sdf must be CUDA and contiguous");
|
|
22
|
+
TORCH_CHECK(weight.is_cuda() && weight.is_contiguous(), "weight must be CUDA and contiguous");
|
|
23
|
+
TORCH_CHECK(depth_image.is_cuda() && depth_image.is_contiguous(), "depth_image must be CUDA and contiguous");
|
|
24
|
+
|
|
25
|
+
int num_vertices = grid_vertices.size(0);
|
|
26
|
+
int image_height = depth_image.size(0);
|
|
27
|
+
int image_width = depth_image.size(1);
|
|
28
|
+
|
|
29
|
+
const float3* grid_vertices_ptr = reinterpret_cast<const float3*>(grid_vertices.data_ptr<float>());
|
|
30
|
+
float* sdf_ptr = sdf.data_ptr<float>();
|
|
31
|
+
float* weight_ptr = weight.data_ptr<float>();
|
|
32
|
+
const float* depth_image_ptr = depth_image.data_ptr<float>();
|
|
33
|
+
|
|
34
|
+
float3* color_ptr = nullptr;
|
|
35
|
+
if (color_opt.has_value() && color_opt.value().defined() && color_opt.value().numel() > 0) {
|
|
36
|
+
auto color = color_opt.value();
|
|
37
|
+
TORCH_CHECK(color.is_cuda() && color.is_contiguous(), "color must be CUDA and contiguous");
|
|
38
|
+
color_ptr = reinterpret_cast<float3*>(color.data_ptr<float>());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const float3* color_image_ptr = nullptr;
|
|
42
|
+
if (color_image_opt.has_value() && color_image_opt.value().defined() && color_image_opt.value().numel() > 0) {
|
|
43
|
+
auto color_image = color_image_opt.value();
|
|
44
|
+
TORCH_CHECK(color_image.is_cuda() && color_image.is_contiguous(), "color_image must be CUDA and contiguous");
|
|
45
|
+
color_image_ptr = reinterpret_cast<const float3*>(color_image.data_ptr<float>());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
torch::Tensor ex_cpu = extrinsics.cpu().contiguous();
|
|
49
|
+
torch::Tensor in_cpu = intrinsics.cpu().contiguous();
|
|
50
|
+
|
|
51
|
+
const float* ex_data = ex_cpu.data_ptr<float>();
|
|
52
|
+
float4x4 ex = make_float4x4(
|
|
53
|
+
ex_data[0], ex_data[1], ex_data[2], ex_data[3],
|
|
54
|
+
ex_data[4], ex_data[5], ex_data[6], ex_data[7],
|
|
55
|
+
ex_data[8], ex_data[9], ex_data[10], ex_data[11],
|
|
56
|
+
ex_data[12], ex_data[13], ex_data[14], ex_data[15]
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const float* in_data = in_cpu.data_ptr<float>();
|
|
60
|
+
float3x3 in = make_float3x3(
|
|
61
|
+
in_data[0], in_data[1], in_data[2],
|
|
62
|
+
in_data[3], in_data[4], in_data[5],
|
|
63
|
+
in_data[6], in_data[7], in_data[8]
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
single_view_volume_integral(
|
|
67
|
+
num_vertices,
|
|
68
|
+
grid_vertices_ptr,
|
|
69
|
+
sdf_ptr,
|
|
70
|
+
weight_ptr,
|
|
71
|
+
color_ptr,
|
|
72
|
+
depth_image_ptr,
|
|
73
|
+
color_image_ptr,
|
|
74
|
+
image_width,
|
|
75
|
+
image_height,
|
|
76
|
+
ex,
|
|
77
|
+
in,
|
|
78
|
+
trunc_margin,
|
|
79
|
+
mode
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void bind_ops_volint(py::module_& m) {
|
|
84
|
+
m.def("single_view_volume_integral", &single_view_volume_integral_bind,
|
|
85
|
+
py::arg("grid_vertices"),
|
|
86
|
+
py::arg("sdf"),
|
|
87
|
+
py::arg("weight"),
|
|
88
|
+
py::arg("color"),
|
|
89
|
+
py::arg("depth_image"),
|
|
90
|
+
py::arg("color_image"),
|
|
91
|
+
py::arg("extrinsics"),
|
|
92
|
+
py::arg("intrinsics"),
|
|
93
|
+
py::arg("trunc_margin"),
|
|
94
|
+
py::arg("mode") = 1,
|
|
95
|
+
"Single view TSDF volume integration");
|
|
96
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#include "grid.h"
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <math.h>
|
|
4
|
+
|
|
5
|
+
namespace grid {
|
|
6
|
+
|
|
7
|
+
__global__ void get_active_voxel_ids_from_depth_kernel(
|
|
8
|
+
const int num_pixels,
|
|
9
|
+
const float* depth_image,
|
|
10
|
+
const float4x4 c2w,
|
|
11
|
+
const float3x3 intrinsics_inv,
|
|
12
|
+
const int image_width,
|
|
13
|
+
const int image_height,
|
|
14
|
+
const float3 grid_min,
|
|
15
|
+
const float3 grid_max,
|
|
16
|
+
const int3 res,
|
|
17
|
+
int64_t* out_voxel_ids,
|
|
18
|
+
unsigned long long* valid_counter,
|
|
19
|
+
bool activate_neighbor,
|
|
20
|
+
float trunc_margin
|
|
21
|
+
) {
|
|
22
|
+
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
|
23
|
+
if (idx >= num_pixels) return;
|
|
24
|
+
|
|
25
|
+
float d = depth_image[idx];
|
|
26
|
+
if (d <= 0.0f) return; // Ignore invalid depths
|
|
27
|
+
|
|
28
|
+
int ui = idx % image_width;
|
|
29
|
+
int vi = idx / image_width;
|
|
30
|
+
|
|
31
|
+
// 1. Unproject to camera coordinates using inverse intrinsics
|
|
32
|
+
float3 p_cam;
|
|
33
|
+
p_cam.x = d * (intrinsics_inv.m[0][0] * ui + intrinsics_inv.m[0][1] * vi + intrinsics_inv.m[0][2]);
|
|
34
|
+
p_cam.y = d * (intrinsics_inv.m[1][0] * ui + intrinsics_inv.m[1][1] * vi + intrinsics_inv.m[1][2]);
|
|
35
|
+
p_cam.z = d;
|
|
36
|
+
|
|
37
|
+
// 2. Transform to world coordinates using Camera-To-World matrix
|
|
38
|
+
float4 p_cam4 = make_float4(p_cam.x, p_cam.y, p_cam.z, 1.0f);
|
|
39
|
+
float4 p_world4 = c2w * p_cam4;
|
|
40
|
+
|
|
41
|
+
// 3. Compute 3D grid cell indices (0-indexed)
|
|
42
|
+
float spacing_x = (grid_max.x - grid_min.x) / fmaxf(1.0f, (float)(res.x - 1));
|
|
43
|
+
float spacing_y = (grid_max.y - grid_min.y) / fmaxf(1.0f, (float)(res.y - 1));
|
|
44
|
+
float spacing_z = (grid_max.z - grid_min.z) / fmaxf(1.0f, (float)(res.z - 1));
|
|
45
|
+
|
|
46
|
+
int i_min = floorf((p_world4.x - grid_min.x) / spacing_x);
|
|
47
|
+
int i_max = i_min;
|
|
48
|
+
int j_min = floorf((p_world4.y - grid_min.y) / spacing_y);
|
|
49
|
+
int j_max = j_min;
|
|
50
|
+
int k_min = floorf((p_world4.z - grid_min.z) / spacing_z);
|
|
51
|
+
int k_max = k_min;
|
|
52
|
+
|
|
53
|
+
if (activate_neighbor) {
|
|
54
|
+
i_min = floorf((p_world4.x - trunc_margin - grid_min.x) / spacing_x);
|
|
55
|
+
i_max = floorf((p_world4.x + trunc_margin - grid_min.x) / spacing_x);
|
|
56
|
+
j_min = floorf((p_world4.y - trunc_margin - grid_min.y) / spacing_y);
|
|
57
|
+
j_max = floorf((p_world4.y + trunc_margin - grid_min.y) / spacing_y);
|
|
58
|
+
k_min = floorf((p_world4.z - trunc_margin - grid_min.z) / spacing_z);
|
|
59
|
+
k_max = floorf((p_world4.z + trunc_margin - grid_min.z) / spacing_z);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (int i = i_min; i <= i_max; ++i) {
|
|
63
|
+
for (int j = j_min; j <= j_max; ++j) {
|
|
64
|
+
for (int k = k_min; k <= k_max; ++k) {
|
|
65
|
+
if (i >= 0 && i < res.x - 1 && j >= 0 && j < res.y - 1 && k >= 0 && k < res.z - 1) {
|
|
66
|
+
int64_t voxel_id = (int64_t)i * (res.y - 1) * (res.z - 1) + (int64_t)j * (res.z - 1) + (int64_t)k;
|
|
67
|
+
unsigned long long write_idx = atomicAdd(valid_counter, 1ULL);
|
|
68
|
+
out_voxel_ids[write_idx] = voxel_id;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void get_active_voxel_ids_from_depth(
|
|
76
|
+
const int num_pixels,
|
|
77
|
+
const float* depth_image,
|
|
78
|
+
const float4x4 c2w,
|
|
79
|
+
const float3x3 intrinsics_inv,
|
|
80
|
+
const int image_width,
|
|
81
|
+
const int image_height,
|
|
82
|
+
const float3 grid_min,
|
|
83
|
+
const float3 grid_max,
|
|
84
|
+
const int3 res,
|
|
85
|
+
int64_t* out_voxel_ids,
|
|
86
|
+
unsigned long long* valid_counter,
|
|
87
|
+
bool activate_neighbor,
|
|
88
|
+
float trunc_margin
|
|
89
|
+
) {
|
|
90
|
+
int block_size = 256;
|
|
91
|
+
int grid_size = (num_pixels + block_size - 1) / block_size;
|
|
92
|
+
|
|
93
|
+
get_active_voxel_ids_from_depth_kernel<<<grid_size, block_size>>>(
|
|
94
|
+
num_pixels,
|
|
95
|
+
depth_image,
|
|
96
|
+
c2w,
|
|
97
|
+
intrinsics_inv,
|
|
98
|
+
image_width,
|
|
99
|
+
image_height,
|
|
100
|
+
grid_min,
|
|
101
|
+
grid_max,
|
|
102
|
+
res,
|
|
103
|
+
out_voxel_ids,
|
|
104
|
+
valid_counter,
|
|
105
|
+
activate_neighbor,
|
|
106
|
+
trunc_margin
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include <vector>
|
|
3
|
+
#include <torch/extension.h>
|
|
4
|
+
#include "../maths/maths.h"
|
|
5
|
+
|
|
6
|
+
namespace grid {
|
|
7
|
+
void get_active_voxel_ids_from_depth(
|
|
8
|
+
const int num_pixels,
|
|
9
|
+
const float* depth_image,
|
|
10
|
+
const float4x4 c2w,
|
|
11
|
+
const float3x3 intrinsics_inv,
|
|
12
|
+
const int image_width,
|
|
13
|
+
const int image_height,
|
|
14
|
+
const float3 grid_min,
|
|
15
|
+
const float3 grid_max,
|
|
16
|
+
const int3 res,
|
|
17
|
+
int64_t* out_voxel_ids,
|
|
18
|
+
unsigned long long* valid_counter,
|
|
19
|
+
bool activate_neighbor,
|
|
20
|
+
float trunc_margin
|
|
21
|
+
);
|
|
22
|
+
}
|