diff --git a/cpp/open3d/geometry/BoundingVolume.h b/cpp/open3d/geometry/BoundingVolume.h index 9050304edac..f82c02dceff 100644 --- a/cpp/open3d/geometry/BoundingVolume.h +++ b/cpp/open3d/geometry/BoundingVolume.h @@ -117,7 +117,8 @@ class OrientedBoundingBox : public Geometry3D { /// bounding box that could be computed for example with O'Rourke's /// algorithm (cf. http://cs.smith.edu/~jorourke/Papers/MinVolBox.pdf, /// https://www.geometrictools.com/Documentation/MinimumVolumeBox.pdf) - /// \param points The input points + /// \param points A list of points with data type of float32 or float64 (N x + /// 3 tensor, where N must be larger than 3). /// \param robust If set to true uses a more robust method which works /// in degenerate cases but introduces noise to the points /// coordinates. @@ -130,7 +131,8 @@ class OrientedBoundingBox : public Geometry3D { /// bounding box: for each triangle in the convex hull, calculate /// the minimal axis aligned box in the frame of that triangle. /// at the end, return the box with the smallest volume - /// \param points The input points + /// \param points A list of points with data type of float32 or float64 (N x + /// 3 tensor, where N must be larger than 3). /// \param robust If set to true uses a more robust method which works /// in degenerate cases but introduces noise to the points /// coordinates. @@ -144,7 +146,8 @@ class OrientedBoundingBox : public Geometry3D { /// The original implementation can be found at the following address: /// https://github.com/juj/MathGeoLib/blob/55053da5e3e55a83043af7324944407b174c3724/src/Geometry/OBB.cpp#L987 /// - /// \param points The input points + /// \param points A list of points with data type of float32 or float64 (N x + /// 3 tensor, where N must be larger than 3). /// \param robust If set to true uses a more robust method which works /// in degenerate cases but introduces noise to the points /// coordinates. diff --git a/cpp/open3d/t/geometry/BoundingVolume.cpp b/cpp/open3d/t/geometry/BoundingVolume.cpp index ad357608442..0b8db5c2f4f 100644 --- a/cpp/open3d/t/geometry/BoundingVolume.cpp +++ b/cpp/open3d/t/geometry/BoundingVolume.cpp @@ -576,6 +576,30 @@ OrientedBoundingBox OrientedBoundingBox::CreateFromPoints( points.GetDtype(), points.GetDevice()); } +OrientedBoundingBox OrientedBoundingBox::CreateFromPointsMinimalApprox( + const core::Tensor &points, bool robust) { + core::AssertTensorShape(points, {utility::nullopt, 3}); + core::AssertTensorDtypes(points, {core::Float32, core::Float64}); + return OrientedBoundingBox::FromLegacy( + open3d::geometry::OrientedBoundingBox:: + CreateFromPointsMinimalApprox( + core::eigen_converter::TensorToEigenVector3dVector( + points), + robust), + points.GetDtype(), points.GetDevice()); +} + +OrientedBoundingBox OrientedBoundingBox::CreateFromPointsMinimal( + const core::Tensor &points, bool robust) { + core::AssertTensorShape(points, {utility::nullopt, 3}); + core::AssertTensorDtypes(points, {core::Float32, core::Float64}); + return OrientedBoundingBox::FromLegacy( + open3d::geometry::OrientedBoundingBox::CreateFromPointsMinimal( + core::eigen_converter::TensorToEigenVector3dVector(points), + robust), + points.GetDtype(), points.GetDevice()); +} + } // namespace geometry } // namespace t } // namespace open3d diff --git a/cpp/open3d/t/geometry/BoundingVolume.h b/cpp/open3d/t/geometry/BoundingVolume.h index 0f3a3afa16b..7d755991b25 100644 --- a/cpp/open3d/t/geometry/BoundingVolume.h +++ b/cpp/open3d/t/geometry/BoundingVolume.h @@ -460,6 +460,36 @@ class OrientedBoundingBox : public Geometry, public DrawableGeometry { static OrientedBoundingBox CreateFromPoints(const core::Tensor &points, bool robust = false); + /// Creates the oriented bounding box with the smallest volume. + /// The algorithm makes use of the fact that at least one edge of + /// the convex hull must be collinear with an edge of the minimum + /// bounding box: for each triangle in the convex hull, calculate + /// the minimal axis aligned box in the frame of that triangle. + /// at the end, return the box with the smallest volume + /// \param points A list of points with data type of float32 or float64 (N x + /// 3 tensor, where N must be larger than 3). + /// \param robust If set to true uses a more robust method which works + /// in degenerate cases but introduces noise to the points + /// coordinates. + + static OrientedBoundingBox CreateFromPointsMinimalApprox( + const core::Tensor &points, bool robust = false); + + /// Creates the oriented bounding box with the smallest volume. + /// This algorithm is inspired by the article "An Exact Algorithm for + /// Finding Minimum Oriented Bounding Boxes" written by Jukka Jylänki. + /// The original implementation can be found at the following address: + /// https://github.com/juj/MathGeoLib/blob/55053da5e3e55a83043af7324944407b174c3724/src/Geometry/OBB.cpp#L987 + /// + /// \param points A list of points with data type of float32 or float64 (N x + /// 3 tensor, where N must be larger than 3). + /// \param robust If set to true uses a more robust method which works + /// in degenerate cases but introduces noise to the points + /// coordinates. + + static OrientedBoundingBox CreateFromPointsMinimal( + const core::Tensor &points, bool robust = false); + protected: core::Device device_ = core::Device("CPU:0"); core::Dtype dtype_ = core::Float32; diff --git a/cpp/pybind/geometry/boundingvolume.cpp b/cpp/pybind/geometry/boundingvolume.cpp index 6436fd9dd6b..128e50a992b 100644 --- a/cpp/pybind/geometry/boundingvolume.cpp +++ b/cpp/pybind/geometry/boundingvolume.cpp @@ -84,7 +84,7 @@ The returned bounding box is an approximation to the minimal bounding box. bounding box is oriented such that the axes are ordered with respect to the principal components. )doc") - .def_static("create_from_points_approx", + .def_static("create_from_points_minimal_approx", &OrientedBoundingBox::CreateFromPointsMinimalApprox, "points"_a, "robust"_a = false, R"doc( diff --git a/cpp/pybind/t/geometry/boundingvolume.cpp b/cpp/pybind/t/geometry/boundingvolume.cpp index ed973e739d5..a2d59fae6e6 100644 --- a/cpp/pybind/t/geometry/boundingvolume.cpp +++ b/cpp/pybind/t/geometry/boundingvolume.cpp @@ -323,6 +323,24 @@ that could be computed for example with O'Rourke's algorithm (cf. http://cs.smith.edu/~jorourke/Papers/MinVolBox.pdf, https://www.geometrictools.com/Documentation/MinimumVolumeBox.pdf) This is a wrapper for a CPU implementation.)", "points"_a, "robust"_a = false); + obb.def_static("create_from_points_minimal_approx", + &OrientedBoundingBox::CreateFromPointsMinimalApprox, + R"(Creates the oriented bounding box with optimized (but not +necessarily smallest) volume. The algorithm makes use of the fact that at least one +edge of the convex hull must be collinear with an edge of the minimum bounding box: +for each triangle in the convex hull, calculate the minimal axis aligned box in the +frame of that triangle. at the end, return the box with optimized (but not +necessarily smallest) volume. This is a wrapper for a CPU implementation.)", + "points"_a, "robust"_a = false); + obb.def_static( + "create_from_points_minimal", + &OrientedBoundingBox::CreateFromPointsMinimal, + R"(Creates the oriented bounding box with the smallest volume. +The algorithm creates the oriented bounding box with the smallest volume. +It is inspired by the article "An Exact Algorithm for Finding Minimum +Oriented Bounding Boxes" written by Jukka Jylänki. +This is a wrapper for a CPU implementation.)", + "points"_a, "robust"_a = false); docstring::ClassMethodDocInject( m, "OrientedBoundingBox", "set_center",