Skip to content

Commit

Permalink
Add geometry type CompoundMesh
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi Armstrong authored and Levi-Armstrong committed Sep 16, 2024
1 parent 75cfd93 commit 6a90096
Show file tree
Hide file tree
Showing 20 changed files with 619 additions and 250 deletions.
35 changes: 29 additions & 6 deletions tesseract_collision/bullet/src/bullet_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <BulletCollision/Gimpact/btTriangleShapeEx.h>
#include <boost/thread/mutex.hpp>
#include <memory>
#include <stdexcept>
#include <octomap/octomap.h>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

Expand Down Expand Up @@ -399,6 +400,10 @@ std::shared_ptr<btCollisionShape> createShapePrimitive(const CollisionShapeConst
shape->setMargin(BULLET_MARGIN);
break;
}
case tesseract_geometry::GeometryType::COMPOUND_MESH:
{
throw std::runtime_error("CompundMesh type should not be passed to this function!");
}
// LCOV_EXCL_START
default:
{
Expand Down Expand Up @@ -445,7 +450,8 @@ CollisionObjectWrapper::CollisionObjectWrapper(std::string name,
m_collisionFilterGroup = btBroadphaseProxy::KinematicFilter;
m_collisionFilterMask = btBroadphaseProxy::StaticFilter | btBroadphaseProxy::KinematicFilter;

if (m_shapes.size() == 1 && m_shape_poses[0].matrix().isIdentity())
if (m_shapes.size() == 1 && m_shape_poses[0].matrix().isIdentity() &&
m_shapes[0]->getType() != tesseract_geometry::GeometryType::COMPOUND_MESH)
{
std::shared_ptr<btCollisionShape> shape = createShapePrimitive(m_shapes[0], this, 0);
manage(shape);
Expand All @@ -463,12 +469,29 @@ CollisionObjectWrapper::CollisionObjectWrapper(std::string name,

for (std::size_t j = 0; j < m_shapes.size(); ++j)
{
std::shared_ptr<btCollisionShape> subshape = createShapePrimitive(m_shapes[j], this, static_cast<int>(j));
if (subshape != nullptr)
if (m_shapes[j]->getType() == tesseract_geometry::GeometryType::COMPOUND_MESH)
{
manage(subshape);
btTransform geomTrans = convertEigenToBt(m_shape_poses[j]);
compound->addChildShape(geomTrans, subshape.get());
const auto& meshes = std::static_pointer_cast<const tesseract_geometry::CompoundMesh>(m_shapes[j])->getMeshes();
for (const auto& mesh : meshes)
{
std::shared_ptr<btCollisionShape> subshape = createShapePrimitive(mesh, this, static_cast<int>(j));
if (subshape != nullptr)
{
manage(subshape);
btTransform geomTrans = convertEigenToBt(m_shape_poses[j]);
compound->addChildShape(geomTrans, subshape.get());
}
}
}
else
{
std::shared_ptr<btCollisionShape> subshape = createShapePrimitive(m_shapes[j], this, static_cast<int>(j));
if (subshape != nullptr)
{
manage(subshape);
btTransform geomTrans = convertEigenToBt(m_shape_poses[j]);
compound->addChildShape(geomTrans, subshape.get());
}
}
}
}
Expand Down
44 changes: 35 additions & 9 deletions tesseract_collision/fcl/src/fcl_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <fcl/geometry/shape/capsule-inl.h>
#include <fcl/geometry/octree/octree-inl.h>
#include <memory>
#include <stdexcept>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

#include <tesseract_collision/fcl/fcl_utils.h>
Expand Down Expand Up @@ -190,6 +191,10 @@ CollisionGeometryPtr createShapePrimitive(const CollisionShapeConstPtr& geom)
{
return createShapePrimitive(std::static_pointer_cast<const tesseract_geometry::Octree>(geom));
}
case tesseract_geometry::GeometryType::COMPOUND_MESH:
{
throw std::runtime_error("CompundMesh type should not be passed to this function!");
}
default:
{
CONSOLE_BRIDGE_logError("This geometric shape type (%d) is not supported using fcl yet",
Expand Down Expand Up @@ -349,16 +354,37 @@ CollisionObjectWrapper::CollisionObjectWrapper(std::string name,
collision_objects_raw_.reserve(shapes_.size());
for (std::size_t i = 0; i < shapes_.size(); ++i) // NOLINT
{
CollisionGeometryPtr subshape = createShapePrimitive(shapes_[i]);
if (subshape != nullptr)
if (shapes_[i]->getType() == tesseract_geometry::GeometryType::COMPOUND_MESH)
{
const auto& meshes = std::static_pointer_cast<const tesseract_geometry::CompoundMesh>(shapes_[i])->getMeshes();
for (const auto& mesh : meshes)
{
CollisionGeometryPtr subshape = createShapePrimitive(mesh);
if (subshape != nullptr)
{
collision_geometries_.push_back(subshape);
auto co = std::make_shared<FCLCollisionObjectWrapper>(subshape);
co->setUserData(this);
co->setTransform(shape_poses_[i]);
co->updateAABB();
collision_objects_.push_back(co);
collision_objects_raw_.push_back(co.get());
}
}
}
else
{
collision_geometries_.push_back(subshape);
auto co = std::make_shared<FCLCollisionObjectWrapper>(subshape);
co->setUserData(this);
co->setTransform(shape_poses_[i]);
co->updateAABB();
collision_objects_.push_back(co);
collision_objects_raw_.push_back(co.get());
CollisionGeometryPtr subshape = createShapePrimitive(shapes_[i]);
if (subshape != nullptr)
{
collision_geometries_.push_back(subshape);
auto co = std::make_shared<FCLCollisionObjectWrapper>(subshape);
co->setUserData(this);
co->setTransform(shape_poses_[i]);
co->updateAABB();
collision_objects_.push_back(co);
collision_objects_raw_.push_back(co.get());
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions tesseract_geometry/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ add_library(
src/utils.cpp
src/geometries/box.cpp
src/geometries/capsule.cpp
src/geometries/compound_mesh.cpp
src/geometries/cone.cpp
src/geometries/convex_mesh.cpp
src/geometries/cylinder.cpp
Expand Down
1 change: 1 addition & 0 deletions tesseract_geometry/include/tesseract_geometry/geometries.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <tesseract_geometry/impl/box.h>
#include <tesseract_geometry/impl/capsule.h>
#include <tesseract_geometry/impl/compound_mesh.h>
#include <tesseract_geometry/impl/cone.h>
#include <tesseract_geometry/impl/convex_mesh.h>
#include <tesseract_geometry/impl/cylinder.h>
Expand Down
6 changes: 4 additions & 2 deletions tesseract_geometry/include/tesseract_geometry/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ enum class GeometryType
CONVEX_MESH,
SDF_MESH,
OCTREE,
POLYGON_MESH
POLYGON_MESH,
COMPOUND_MESH
};
static const std::vector<std::string> GeometryTypeStrings = { "UNINITIALIZED", "SPHERE", "CYLINDER", "CAPSULE",
"CONE", "BOX", "PLANE", "MESH",
"CONVEX_MESH", "SDF_MESH", "OCTREE", "POLYGON_MESH" };
"CONVEX_MESH", "SDF_MESH", "OCTREE", "POLYGON_MESH",
"COMPOUND_MESH" };

class Geometry
{
Expand Down
92 changes: 92 additions & 0 deletions tesseract_geometry/include/tesseract_geometry/impl/compound_mesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @file compound_mesh.h
* @brief Tesseract Compound Mesh Geometry
*
* @author Levi Armstrong
* @date September 14, 2024
* @version TODO
* @bug No known bugs
*
* @copyright Copyright (c) 2024, Levi Armstrong
*
* @par License
* Software License Agreement (Apache License)
* @par
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* @par
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TESSERACT_GEOMETRY_COMPOUND_MESH_H
#define TESSERACT_GEOMETRY_COMPOUND_MESH_H

#include <tesseract_common/macros.h>
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <boost/serialization/export.hpp>
#include <memory>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

#include <tesseract_geometry/impl/polygon_mesh.h>

namespace boost::serialization
{
class access;
}

namespace tesseract_geometry
{
/** @brief This is store meshes that are associated with as single resource */
class CompoundMesh : public Geometry
{
public:
using Ptr = std::shared_ptr<CompoundMesh>;
using ConstPtr = std::shared_ptr<const CompoundMesh>;

CompoundMesh() = default;
CompoundMesh(std::vector<std::shared_ptr<PolygonMesh>> meshes);

/**
* @brief Get the meshes
* @return The meshes
*/
const std::vector<std::shared_ptr<PolygonMesh>>& getMeshes() const;

/**
* @brief Get the path to file used to generate the meshs
*
* Note: If empty, assume it was manually generated.
*
* @return Absolute path to the mesh file
*/
std::shared_ptr<const tesseract_common::Resource> getResource() const;

/**
* @brief Get the scale applied to file used to generate the meshs
* @return The scale x, y, z
*/
const Eigen::Vector3d& getScale() const;

Geometry::Ptr clone() const override final;

bool operator==(const CompoundMesh& rhs) const;
bool operator!=(const CompoundMesh& rhs) const;

private:
std::vector<std::shared_ptr<PolygonMesh>> meshes_;

friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version); // NOLINT
};

} // namespace tesseract_geometry

BOOST_CLASS_EXPORT_KEY(tesseract_geometry::CompoundMesh)

#endif // TESSERACT_GEOMETRY_COMPOUND_MESH_H
97 changes: 97 additions & 0 deletions tesseract_geometry/src/geometries/compound_mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* @file compund_mesh.cpp
* @brief Tesseract Compound Mesh Geometry
*
* @author Levi Armstrong
* @date March 16, 2022
* @version TODO
* @bug No known bugs
*
* @par License
* Software License Agreement (Apache License)
* @par
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* @par
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <tesseract_common/macros.h>
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

#include <tesseract_common/utils.h>
#include <tesseract_geometry/impl/compound_mesh.h>

namespace tesseract_geometry
{
CompoundMesh::CompoundMesh(std::vector<std::shared_ptr<PolygonMesh>> meshes)
: Geometry(GeometryType::COMPOUND_MESH), meshes_(std::move(meshes))
{
if (meshes_.size() <= 1)
throw std::runtime_error("Meshes must contain more than one mesh");

#ifndef NDEBUG
for (const auto& mesh : meshes_)
{
assert(meshes_[0]->getResource() == mesh->getResource());
assert(tesseract_common::almostEqualRelativeAndAbs(meshes_[0]->getScale(), mesh->getScale()));
}
#endif
}

const std::vector<std::shared_ptr<PolygonMesh>>& CompoundMesh::getMeshes() const { return meshes_; }

std::shared_ptr<const tesseract_common::Resource> CompoundMesh::getResource() const
{
return meshes_.front()->getResource();
}

const Eigen::Vector3d& CompoundMesh::getScale() const { return meshes_.front()->getScale(); }

Geometry::Ptr CompoundMesh::clone() const
{
std::vector<std::shared_ptr<PolygonMesh>> meshes;
meshes.reserve(meshes_.size());
for (const auto& mesh : meshes_)
meshes.emplace_back(std::dynamic_pointer_cast<PolygonMesh>(mesh->clone()));

return std::make_shared<CompoundMesh>(meshes);
}

bool CompoundMesh::operator==(const CompoundMesh& rhs) const
{
if (meshes_.size() != rhs.meshes_.size())
return false;

bool equal = true;
equal &= Geometry::operator==(rhs);
for (std::size_t i = 0; i < meshes_.size(); ++i)
equal &= (*meshes_.at(i) == *rhs.meshes_.at(i));

return equal;
}
bool CompoundMesh::operator!=(const CompoundMesh& rhs) const { return !operator==(rhs); }

template <class Archive>
void CompoundMesh::serialize(Archive& ar, const unsigned int /*version*/)
{
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Geometry);
ar& BOOST_SERIALIZATION_NVP(meshes_);
}
} // namespace tesseract_geometry

#include <tesseract_common/serialization.h>
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_geometry::CompoundMesh)
TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_geometry::CompoundMesh)
16 changes: 16 additions & 0 deletions tesseract_geometry/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,22 @@ bool isIdentical(const Geometry& geom1, const Geometry& geom2)

break;
}
case GeometryType::COMPOUND_MESH:
{
const auto& s1 = static_cast<const CompoundMesh&>(geom1);
const auto& s2 = static_cast<const CompoundMesh&>(geom2);

if (s1.getMeshes().size() != s2.getMeshes().size())
return false;

for (std::size_t i = 0; i < s1.getMeshes().size(); ++i)
{
if (!isIdentical(*s1.getMeshes()[i], *s2.getMeshes()[i]))
return false;
}

break;
}
default:
{
CONSOLE_BRIDGE_logError("This geometric shape type (%d) is not supported", static_cast<int>(geom1.getType()));
Expand Down
Loading

0 comments on commit 6a90096

Please sign in to comment.