Skip to content

Commit 8f818f6

Browse files
Add AxisAlignedBox getters for all relevant geometries
* Mesh is a special case since it forwards the calculations for the caller. If callback is not set, the return is nullptr * This has been done since this library does not depend on gz-common * Geometry types that do not have a volume, return nullptr.
1 parent 7ea246d commit 8f818f6

24 files changed

+427
-0
lines changed

include/sdf/Box.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <gz/math/Box.hh>
2323
#include <gz/math/Vector3.hh>
2424
#include <gz/math/Inertial.hh>
25+
#include <gz/math/AxisAlignedBox.hh>
2526
#include <gz/utils/ImplPtr.hh>
2627
#include <sdf/Error.hh>
2728
#include <sdf/Element.hh>
@@ -76,6 +77,10 @@ namespace sdf
7677
public: std::optional<gz::math::Inertiald>
7778
CalculateInertial(double _density);
7879

80+
/// \brief Get the Axis-aligned box for this Box.
81+
/// \return A gz::math::AxisAlignedBox object.
82+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
83+
7984
/// \brief Create and return an SDF element filled with data from this
8085
/// box.
8186
/// Note that parameter passing functionality is not captured with this

include/sdf/Capsule.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <gz/math/Capsule.hh>
2323
#include <gz/math/Inertial.hh>
24+
#include <gz/math/AxisAlignedBox.hh>
2425
#include <gz/utils/ImplPtr.hh>
2526
#include <sdf/Error.hh>
2627
#include <sdf/Element.hh>
@@ -83,6 +84,10 @@ namespace sdf
8384
public: std::optional<gz::math::Inertiald> CalculateInertial(
8485
double _density);
8586

87+
/// \brief Get the Axis-aligned box for this Capsule.
88+
/// \return A gz::math::AxisAlignedBox object.
89+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
90+
8691
/// \brief Create and return an SDF element filled with data from this
8792
/// capsule.
8893
/// Note that parameter passing functionality is not captured with this

include/sdf/Cone.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <gz/math/Cone.hh>
2525
#include <gz/math/Inertial.hh>
26+
#include <gz/math/AxisAlignedBox.hh>
2627
#include <gz/utils/ImplPtr.hh>
2728
#include <sdf/Error.hh>
2829
#include <sdf/Element.hh>
@@ -85,6 +86,10 @@ namespace sdf
8586
public: std::optional<gz::math::Inertiald>
8687
CalculateInertial(double _density);
8788

89+
/// \brief Get the Axis-aligned box for this Cone.
90+
/// \return A gz::math::AxisAlignedBox object.
91+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
92+
8893
/// \brief Create and return an SDF element filled with data from this
8994
/// cone.
9095
/// Note that parameter passing functionality is not captured with this

include/sdf/Cylinder.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <gz/math/Cylinder.hh>
2323
#include <gz/math/Inertial.hh>
24+
#include <gz/math/AxisAlignedBox.hh>
2425
#include <gz/utils/ImplPtr.hh>
2526
#include <sdf/Error.hh>
2627
#include <sdf/Element.hh>
@@ -83,6 +84,10 @@ namespace sdf
8384
public: std::optional<gz::math::Inertiald>
8485
CalculateInertial(double _density);
8586

87+
/// \brief Get the Axis-aligned box for this Cylinder.
88+
/// \return A gz::math::AxisAlignedBox object.
89+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
90+
8691
/// \brief Create and return an SDF element filled with data from this
8792
/// cylinder.
8893
/// Note that parameter passing functionality is not captured with this

include/sdf/Ellipsoid.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <gz/math/Inertial.hh>
2323
#include <gz/math/Ellipsoid.hh>
24+
#include <gz/math/AxisAlignedBox.hh>
2425
#include <gz/utils/ImplPtr.hh>
2526
#include <sdf/Error.hh>
2627
#include <sdf/Element.hh>
@@ -75,6 +76,10 @@ namespace sdf
7576
public: std::optional<gz::math::Inertiald>
7677
CalculateInertial(double _density);
7778

79+
/// \brief Get the Axis-aligned box for this Ellipsoid.
80+
/// \return A gz::math::AxisAlignedBox object.
81+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
82+
7883
/// \brief Create and return an SDF element filled with data from this
7984
/// ellipsoid.
8085
/// Note that parameter passing functionality is not captured with this

include/sdf/Geometry.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <gz/utils/ImplPtr.hh>
2424
#include <gz/math/Inertial.hh>
25+
#include <gz/math/AxisAlignedBox.hh>
2526
#include <sdf/Error.hh>
2627
#include <sdf/Element.hh>
2728
#include <sdf/config.hh>
@@ -239,6 +240,13 @@ namespace sdf
239240
sdf::Errors &_errors, const ParserConfig &_config,
240241
double _density, sdf::ElementPtr _autoInertiaParams);
241242

243+
/// \brief Calculate and return the AxisAlignedBox for the Geometry
244+
/// @param _meshAabbCalculator The function to calculate the AABB of a mesh
245+
/// @return std::optional with gz::math::AxisAlignedBox object or std::nullopt
246+
/// if the geometry type does not support AABB calculation
247+
public: std::optional<gz::math::AxisAlignedBox> AxisAlignedBox(
248+
Mesh::AxisAlignedBoxCalculator _meshAabbCalculator) const;
249+
242250
/// \brief Get a pointer to the SDF element that was used during
243251
/// load.
244252
/// \return SDF element pointer. The value will be nullptr if Load has

include/sdf/Mesh.hh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <gz/math/Vector3.hh>
2424
#include <gz/math/Inertial.hh>
25+
#include <gz/math/AxisAlignedBox.hh>
2526
#include <gz/utils/ImplPtr.hh>
2627
#include <sdf/CustomInertiaCalcProperties.hh>
2728
#include <sdf/Element.hh>
@@ -94,6 +95,9 @@ namespace sdf
9495
/// Geometry.
9596
class SDFORMAT_VISIBLE Mesh
9697
{
98+
public: using AxisAlignedBoxCalculator =
99+
std::function<gz::math::AxisAlignedBox(const sdf::Mesh &_sdfMesh)>;
100+
97101
/// \brief Constructor
98102
public: Mesh();
99103

@@ -206,6 +210,14 @@ namespace sdf
206210
const sdf::ElementPtr _autoInertiaParams,
207211
const ParserConfig &_config);
208212

213+
/// \brief Get the Axis-aligned box for this Mesh.
214+
/// \param[out] _errors A vector of Errors object. Each object
215+
/// would contain an error code and an error message.
216+
/// \param[in] _config Parser Configuration object.
217+
/// \return A gz::math::AxisAlignedBox object.
218+
public: std::optional<gz::math::AxisAlignedBox>
219+
AxisAlignedBox(AxisAlignedBoxCalculator _meshAabbCalculator) const;
220+
209221
/// \brief Get a pointer to the SDF element that was used during load.
210222
/// \return SDF element pointer. The value will be nullptr if Load has
211223
/// not been called.

include/sdf/Sphere.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <gz/math/Inertial.hh>
2323
#include <gz/math/Sphere.hh>
24+
#include <gz/math/AxisAlignedBox.hh>
2425
#include <gz/utils/ImplPtr.hh>
2526

2627
#include <sdf/Error.hh>
@@ -76,6 +77,10 @@ namespace sdf
7677
public: std::optional<gz::math::Inertiald>
7778
CalculateInertial(double _density);
7879

80+
/// \brief Get the Axis-aligned box for this Sphere.
81+
/// \return A gz::math::AxisAlignedBox object.
82+
public: gz::math::AxisAlignedBox AxisAlignedBox() const;
83+
7984
/// \brief Create and return an SDF element filled with data from this
8085
/// sphere.
8186
/// Note that parameter passing functionality is not captured with this

src/Box.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ std::optional<gz::math::Inertiald> Box::CalculateInertial(double _density)
140140
}
141141
}
142142

143+
/////////////////////////////////////////////////
144+
gz::math::AxisAlignedBox Box::AxisAlignedBox() const
145+
{
146+
auto halfSize = this->Size() / 2;
147+
return gz::math::AxisAlignedBox(-halfSize, halfSize);
148+
}
149+
143150
/////////////////////////////////////////////////
144151
sdf::ElementPtr Box::ToElement() const
145152
{

src/Box_TEST.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,15 @@ TEST(DOMBox, ToElementErrorOutput)
246246
// Check nothing has been printed
247247
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
248248
}
249+
250+
/////////////////////////////////////////////////
251+
TEST(DOMBox, AxisAlignedBox)
252+
{
253+
sdf::Box box;
254+
box.SetSize(gz::math::Vector3d(1, 2, 3));
255+
256+
auto aabb = box.AxisAlignedBox();
257+
EXPECT_EQ(box.Size(), aabb.Size());
258+
EXPECT_EQ(gz::math::Vector3d(-0.5, -1, -1.5), aabb.Min());
259+
EXPECT_EQ(gz::math::Vector3d(0.5, 1, 1.5), aabb.Max());
260+
}

src/Capsule.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ std::optional<gz::math::Inertiald> Capsule::CalculateInertial(double _density)
161161
}
162162
}
163163

164+
/////////////////////////////////////////////////
165+
gz::math::AxisAlignedBox Capsule::AxisAlignedBox() const
166+
{
167+
auto halfSize = gz::math::Vector3d(
168+
this->Radius(), this->Radius(), this->Length() / 2);
169+
return gz::math::AxisAlignedBox(-halfSize, halfSize);
170+
}
171+
164172
/////////////////////////////////////////////////
165173
sdf::ElementPtr Capsule::ToElement() const
166174
{

src/Capsule_TEST.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,16 @@ TEST(DOMCapsule, ToElementErrorOutput)
285285
// Check nothing has been printed
286286
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
287287
}
288+
289+
/////////////////////////////////////////////////
290+
TEST(DOMCapsule, AxisAlignedBox)
291+
{
292+
sdf::Capsule capsule;
293+
capsule.SetRadius(0.5);
294+
capsule.SetLength(2.0);
295+
296+
auto aabb = capsule.AxisAlignedBox();
297+
EXPECT_EQ(gz::math::Vector3d(1.0, 1.0, 2.0), aabb.Size());
298+
EXPECT_EQ(gz::math::Vector3d(-0.5, -0.5, -1.0), aabb.Min());
299+
EXPECT_EQ(gz::math::Vector3d(0.5, 0.5, 1.0), aabb.Max());
300+
}

src/Cone.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ std::optional<gz::math::Inertiald> Cone::CalculateInertial(double _density)
164164
}
165165
}
166166

167+
gz::math::AxisAlignedBox Cone::AxisAlignedBox() const
168+
{
169+
auto halfSize = gz::math::Vector3d(
170+
this->Radius(), this->Radius(), this->Length() / 2);
171+
return gz::math::AxisAlignedBox(-halfSize, halfSize);
172+
}
173+
167174
/////////////////////////////////////////////////
168175
sdf::ElementPtr Cone::ToElement() const
169176
{

src/Cone_TEST.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,16 @@ TEST(DOMCone, ToElementErrorOutput)
286286
// Check nothing has been printed
287287
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
288288
}
289+
290+
/////////////////////////////////////////////////
291+
TEST(DOMCone, AxisAlignedBox)
292+
{
293+
sdf::Cone cone;
294+
cone.SetRadius(0.2);
295+
cone.SetLength(3.0);
296+
297+
auto aabb = cone.AxisAlignedBox();
298+
EXPECT_EQ(gz::math::Vector3d(0.4, 0.4, 3.0), aabb.Size());
299+
EXPECT_EQ(gz::math::Vector3d(-0.2, -0.2, -1.5), aabb.Min());
300+
EXPECT_EQ(gz::math::Vector3d(0.2, 0.2, 1.5), aabb.Max());
301+
}

src/Cylinder.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ std::optional<gz::math::Inertiald> Cylinder::CalculateInertial(double _density)
159159
}
160160
}
161161

162+
/////////////////////////////////////////////////
163+
gz::math::AxisAlignedBox Cylinder::AxisAlignedBox() const
164+
{
165+
auto halfSize = gz::math::Vector3d(
166+
this->Radius(), this->Radius(), this->Length() / 2);
167+
return gz::math::AxisAlignedBox(-halfSize, halfSize);
168+
}
169+
162170
/////////////////////////////////////////////////
163171
sdf::ElementPtr Cylinder::ToElement() const
164172
{

src/Cylinder_TEST.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,16 @@ TEST(DOMCylinder, ToElementErrorOutput)
282282
// Check nothing has been printed
283283
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
284284
}
285+
286+
/////////////////////////////////////////////////
287+
TEST(DOMCylinder, AxisAlignedBox)
288+
{
289+
sdf::Cylinder cylinder;
290+
cylinder.SetRadius(0.25);
291+
cylinder.SetLength(2.5);
292+
293+
auto aabb = cylinder.AxisAlignedBox();
294+
EXPECT_EQ(gz::math::Vector3d(0.5, 0.5, 2.5), aabb.Size());
295+
EXPECT_EQ(gz::math::Vector3d(-0.25, -0.25, -1.25), aabb.Min());
296+
EXPECT_EQ(gz::math::Vector3d(0.25, 0.25, 1.25), aabb.Max());
297+
}

src/Ellipsoid.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ std::optional<gz::math::Inertiald> Ellipsoid::CalculateInertial(double _density)
140140
}
141141
}
142142

143+
/////////////////////////////////////////////////
144+
gz::math::AxisAlignedBox Ellipsoid::AxisAlignedBox() const
145+
{
146+
auto halfSize = this->Radii();
147+
return gz::math::AxisAlignedBox(-halfSize, halfSize);
148+
}
149+
143150
/////////////////////////////////////////////////
144151
sdf::ElementPtr Ellipsoid::ToElement() const
145152
{

src/Ellipsoid_TEST.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,15 @@ TEST(DOMEllipsoid, ToElementErrorOutput)
242242
// Check nothing has been printed
243243
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
244244
}
245+
246+
/////////////////////////////////////////////////
247+
TEST(DOMEllipsoid, AxisAlignedBox)
248+
{
249+
sdf::Ellipsoid ellipsoid;
250+
ellipsoid.SetRadii(gz::math::Vector3d(1.5, 0.5, 0.25));
251+
252+
auto aabb = ellipsoid.AxisAlignedBox();
253+
EXPECT_EQ(gz::math::Vector3d(3.0, 1.0, 0.5), aabb.Size());
254+
EXPECT_EQ(gz::math::Vector3d(-1.5, -0.5, -0.25), aabb.Min());
255+
EXPECT_EQ(gz::math::Vector3d(1.5, 0.5, 0.25), aabb.Max());
256+
}

src/Geometry.cc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,45 @@ std::optional<gz::math::Inertiald> Geometry::CalculateInertial(
385385
return geomInertial;
386386
}
387387

388+
/////////////////////////////////////////////////
389+
std::optional<gz::math::AxisAlignedBox> Geometry::AxisAlignedBox(
390+
Mesh::AxisAlignedBoxCalculator _meshAabbCalculator) const
391+
{
392+
// Initialized the AABB to an empty box (zero volume)
393+
std::optional<gz::math::AxisAlignedBox> aabb;
394+
395+
switch (this->dataPtr->type)
396+
{
397+
case GeometryType::BOX:
398+
aabb = this->dataPtr->box->AxisAlignedBox();
399+
break;
400+
case GeometryType::CAPSULE:
401+
aabb = this->dataPtr->capsule->AxisAlignedBox();
402+
break;
403+
case GeometryType::CONE:
404+
aabb = this->dataPtr->cone->AxisAlignedBox();
405+
break;
406+
case GeometryType::CYLINDER:
407+
aabb = this->dataPtr->cylinder->AxisAlignedBox();
408+
break;
409+
case GeometryType::ELLIPSOID:
410+
aabb = this->dataPtr->ellipsoid->AxisAlignedBox();
411+
break;
412+
case GeometryType::SPHERE:
413+
aabb = this->dataPtr->sphere->AxisAlignedBox();
414+
break;
415+
case GeometryType::MESH:
416+
aabb = this->dataPtr->mesh->AxisAlignedBox(_meshAabbCalculator);
417+
break;
418+
default:
419+
aabb = std::nullopt;
420+
break;
421+
}
422+
423+
return aabb;
424+
}
425+
426+
388427
/////////////////////////////////////////////////
389428
sdf::ElementPtr Geometry::Element() const
390429
{

0 commit comments

Comments
 (0)