From a8e4d6297388ee5ec10260754e599f782039f4d3 Mon Sep 17 00:00:00 2001 From: GouMinghao Date: Fri, 15 Aug 2025 23:22:22 +0800 Subject: [PATCH 1/3] NEW: add create_from_sparse_indices for VoxelGrid --- cpp/open3d/geometry/VoxelGrid.h | 12 ++++++++ cpp/open3d/geometry/VoxelGridFactory.cpp | 20 +++++++++++++ cpp/pybind/geometry/voxelgrid.cpp | 9 ++++++ docs/jupyter/geometry/voxelization.ipynb | 36 ++++++++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/cpp/open3d/geometry/VoxelGrid.h b/cpp/open3d/geometry/VoxelGrid.h index 258e975a12d..13ce79e12b5 100644 --- a/cpp/open3d/geometry/VoxelGrid.h +++ b/cpp/open3d/geometry/VoxelGrid.h @@ -189,6 +189,18 @@ class VoxelGrid : public Geometry3D { double height, double depth); + /// Creates a voxel grid given sparse 3d indices. + /// + /// \param indices 3d indices of each VoxelGrid. + /// \param colors Voxel colors for each voxel of the VoxelGrid. + /// \param origin Coordinate center of the VoxelGrid. + /// \param voxel_size Voxel size of of the VoxelGrid construction. + static std::shared_ptr CreateFromSparseIndices( + const std::vector& indices, + const std::vector& colors, + const Eigen::Vector3d origin, + double voxel_size); + /// \enum VoxelPoolingMode /// /// \brief Possible ways of determining voxel color from PointCloud. diff --git a/cpp/open3d/geometry/VoxelGridFactory.cpp b/cpp/open3d/geometry/VoxelGridFactory.cpp index 39fe03668ed..dbd18463b35 100644 --- a/cpp/open3d/geometry/VoxelGridFactory.cpp +++ b/cpp/open3d/geometry/VoxelGridFactory.cpp @@ -41,6 +41,26 @@ std::shared_ptr VoxelGrid::CreateDense(const Eigen::Vector3d &origin, return output; } + +std::shared_ptr VoxelGrid::CreateFromSparseIndices( + const std::vector& indices, + const std::vector& colors, + const Eigen::Vector3d origin, + double voxel_size) { + if (indices.size() != colors.size()) { + utility::LogError("Size of indices and colors are different"); + } + auto output = std::make_shared(); + output->origin_ = origin; + output->voxel_size_ = voxel_size; + for (size_t i = 0; i < indices.size(); ++i) { + Eigen::Vector3i grid_index(indices[i](0), indices[i](1), indices[i](2)); + output->AddVoxel(geometry::Voxel(grid_index, colors[i])); + } + return output; +} + + std::shared_ptr VoxelGrid::CreateFromPointCloudWithinBounds( const PointCloud &input, double voxel_size, diff --git a/cpp/pybind/geometry/voxelgrid.cpp b/cpp/pybind/geometry/voxelgrid.cpp index d0ce7ed7fea..a2b06c743e5 100644 --- a/cpp/pybind/geometry/voxelgrid.cpp +++ b/cpp/pybind/geometry/voxelgrid.cpp @@ -135,6 +135,9 @@ void pybind_voxelgrid_definitions(py::module &m) { "carving", "origin"_a, "color"_a, "voxel_size"_a, "width"_a, "height"_a, "depth"_a) + .def_static("create_from_sparse_indices", &VoxelGrid::CreateFromSparseIndices, + "Creates a voxel grid given sparse 3d indices", + "indices"_a, "colors"_a, "origin"_a, "voxel_size"_a) .def_static( "create_from_point_cloud", &VoxelGrid::CreateFromPointCloud, "Creates a VoxelGrid from a given PointCloud. The " @@ -228,6 +231,12 @@ void pybind_voxelgrid_definitions(py::module &m) { {"width", "Spatial width extend of the VoxelGrid."}, {"height", "Spatial height extend of the VoxelGrid."}, {"depth", "Spatial depth extend of the VoxelGrid."}}); + docstring::ClassMethodDocInject( + m, "VoxelGrid", "create_from_sparse_indices", + {{"indices", "3d indices of each VoxelGrid."}, + {"colors", "Voxel colors for each voxel of the VoxelGrid."}, + {"origin", "Coordinate center of the VoxelGrid."}, + {"voxel_size", "Voxel size of of the VoxelGrid construction."}}); docstring::ClassMethodDocInject( m, "VoxelGrid", "create_from_point_cloud", {{"input", "The input PointCloud"}, diff --git a/docs/jupyter/geometry/voxelization.ipynb b/docs/jupyter/geometry/voxelization.ipynb index e7b98a64f7c..fcabf7d7204 100644 --- a/docs/jupyter/geometry/voxelization.ipynb +++ b/docs/jupyter/geometry/voxelization.ipynb @@ -281,6 +281,42 @@ "print(voxel_grid)\n", "o3d.visualization.draw_geometries([voxel_grid])" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# From sparse indices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The method `create_from_sparse_indices` creates voxels from sparse indices and colors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import open3d as o3d\n", + "import numpy as np\n", + "\n", + "indices = np.array([[0, 0, 0], [1, 1, 1]], dtype=np.int32)\n", + "colors = np.array([[1, 0, 0], [0, 0, 1]], dtype=np.float64)\n", + "\n", + "voxel_grids = o3d.geometry.VoxelGrid.create_from_sparse_indices(\n", + " o3d.utility.Vector3iVector(indices),\n", + " o3d.utility.Vector3dVector(colors),\n", + " np.array([0, 0, 0]),\n", + " 1.0,\n", + ")\n", + "frame = o3d.geometry.TriangleMesh.create_coordinate_frame(0.8)\n", + "o3d.visualization.draw_geometries([frame, voxel_grids])" + ] } ], "metadata": { From 32570fb5f3cd941ed9ab1160f114b9e268cd696f Mon Sep 17 00:00:00 2001 From: GouMinghao Date: Fri, 15 Aug 2025 23:39:48 +0800 Subject: [PATCH 2/3] FIX: fix style error --- cpp/open3d/geometry/VoxelGrid.h | 4 ++-- cpp/open3d/geometry/VoxelGridFactory.cpp | 6 ++---- cpp/pybind/geometry/voxelgrid.cpp | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cpp/open3d/geometry/VoxelGrid.h b/cpp/open3d/geometry/VoxelGrid.h index 13ce79e12b5..19384328a69 100644 --- a/cpp/open3d/geometry/VoxelGrid.h +++ b/cpp/open3d/geometry/VoxelGrid.h @@ -196,8 +196,8 @@ class VoxelGrid : public Geometry3D { /// \param origin Coordinate center of the VoxelGrid. /// \param voxel_size Voxel size of of the VoxelGrid construction. static std::shared_ptr CreateFromSparseIndices( - const std::vector& indices, - const std::vector& colors, + const std::vector &indices, + const std::vector &colors, const Eigen::Vector3d origin, double voxel_size); diff --git a/cpp/open3d/geometry/VoxelGridFactory.cpp b/cpp/open3d/geometry/VoxelGridFactory.cpp index dbd18463b35..8184cc72dbd 100644 --- a/cpp/open3d/geometry/VoxelGridFactory.cpp +++ b/cpp/open3d/geometry/VoxelGridFactory.cpp @@ -41,10 +41,9 @@ std::shared_ptr VoxelGrid::CreateDense(const Eigen::Vector3d &origin, return output; } - std::shared_ptr VoxelGrid::CreateFromSparseIndices( - const std::vector& indices, - const std::vector& colors, + const std::vector &indices, + const std::vector &colors, const Eigen::Vector3d origin, double voxel_size) { if (indices.size() != colors.size()) { @@ -60,7 +59,6 @@ std::shared_ptr VoxelGrid::CreateFromSparseIndices( return output; } - std::shared_ptr VoxelGrid::CreateFromPointCloudWithinBounds( const PointCloud &input, double voxel_size, diff --git a/cpp/pybind/geometry/voxelgrid.cpp b/cpp/pybind/geometry/voxelgrid.cpp index a2b06c743e5..cea34a884c0 100644 --- a/cpp/pybind/geometry/voxelgrid.cpp +++ b/cpp/pybind/geometry/voxelgrid.cpp @@ -135,7 +135,8 @@ void pybind_voxelgrid_definitions(py::module &m) { "carving", "origin"_a, "color"_a, "voxel_size"_a, "width"_a, "height"_a, "depth"_a) - .def_static("create_from_sparse_indices", &VoxelGrid::CreateFromSparseIndices, + .def_static("create_from_sparse_indices", + &VoxelGrid::CreateFromSparseIndices, "Creates a voxel grid given sparse 3d indices", "indices"_a, "colors"_a, "origin"_a, "voxel_size"_a) .def_static( From e23134028e589cf0e49d7e2b61547147605ed76c Mon Sep 17 00:00:00 2001 From: GouMinghao Date: Sat, 16 Aug 2025 08:55:33 +0800 Subject: [PATCH 3/3] ENH: simplify --- cpp/open3d/geometry/VoxelGridFactory.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/open3d/geometry/VoxelGridFactory.cpp b/cpp/open3d/geometry/VoxelGridFactory.cpp index 8184cc72dbd..def73ff0c3c 100644 --- a/cpp/open3d/geometry/VoxelGridFactory.cpp +++ b/cpp/open3d/geometry/VoxelGridFactory.cpp @@ -53,8 +53,7 @@ std::shared_ptr VoxelGrid::CreateFromSparseIndices( output->origin_ = origin; output->voxel_size_ = voxel_size; for (size_t i = 0; i < indices.size(); ++i) { - Eigen::Vector3i grid_index(indices[i](0), indices[i](1), indices[i](2)); - output->AddVoxel(geometry::Voxel(grid_index, colors[i])); + output->AddVoxel(geometry::Voxel(indices[i], colors[i])); } return output; }