diff --git a/cpp/open3d/geometry/VoxelGrid.h b/cpp/open3d/geometry/VoxelGrid.h index 258e975a12d..19384328a69 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..def73ff0c3c 100644 --- a/cpp/open3d/geometry/VoxelGridFactory.cpp +++ b/cpp/open3d/geometry/VoxelGridFactory.cpp @@ -41,6 +41,23 @@ 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) { + output->AddVoxel(geometry::Voxel(indices[i], 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..cea34a884c0 100644 --- a/cpp/pybind/geometry/voxelgrid.cpp +++ b/cpp/pybind/geometry/voxelgrid.cpp @@ -135,6 +135,10 @@ 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 +232,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": {