Skip to content

Commit

Permalink
Allow negative scale for MeshShape (#1841)
Browse files Browse the repository at this point in the history
  • Loading branch information
jslee02 authored Sep 3, 2024
1 parent 9feb578 commit e5c8c2c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 31 deletions.
46 changes: 19 additions & 27 deletions dart/dynamics/MeshShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,19 @@ void MeshShape::setMesh(
//==============================================================================
void MeshShape::setScale(const Eigen::Vector3d& scale)
{
assert((scale.array() > 0.0).all());

mScale = scale;
mIsBoundingBoxDirty = true;
mIsVolumeDirty = true;

incrementVersion();
}

//==============================================================================
void MeshShape::setScale(const double scale)
{
setScale(Eigen::Vector3d::Constant(scale));
}

//==============================================================================
const Eigen::Vector3d& MeshShape::getScale() const
{
Expand Down Expand Up @@ -332,33 +336,21 @@ void MeshShape::updateBoundingBox() const
return;
}

double max_X = -std::numeric_limits<double>::infinity();
double max_Y = -std::numeric_limits<double>::infinity();
double max_Z = -std::numeric_limits<double>::infinity();
double min_X = std::numeric_limits<double>::infinity();
double min_Y = std::numeric_limits<double>::infinity();
double min_Z = std::numeric_limits<double>::infinity();

for (unsigned int i = 0; i < mMesh->mNumMeshes; i++) {
for (unsigned int j = 0; j < mMesh->mMeshes[i]->mNumVertices; j++) {
if (mMesh->mMeshes[i]->mVertices[j].x > max_X)
max_X = mMesh->mMeshes[i]->mVertices[j].x;
if (mMesh->mMeshes[i]->mVertices[j].x < min_X)
min_X = mMesh->mMeshes[i]->mVertices[j].x;
if (mMesh->mMeshes[i]->mVertices[j].y > max_Y)
max_Y = mMesh->mMeshes[i]->mVertices[j].y;
if (mMesh->mMeshes[i]->mVertices[j].y < min_Y)
min_Y = mMesh->mMeshes[i]->mVertices[j].y;
if (mMesh->mMeshes[i]->mVertices[j].z > max_Z)
max_Z = mMesh->mMeshes[i]->mVertices[j].z;
if (mMesh->mMeshes[i]->mVertices[j].z < min_Z)
min_Z = mMesh->mMeshes[i]->mVertices[j].z;
Eigen::Vector3d minPoint
= Eigen::Vector3d::Constant(std::numeric_limits<double>::infinity());
Eigen::Vector3d maxPoint = -minPoint;

for (unsigned i = 0u; i < mMesh->mNumMeshes; i++) {
for (unsigned j = 0u; j < mMesh->mMeshes[i]->mNumVertices; j++) {
const auto& vertex = mMesh->mMeshes[i]->mVertices[j];
const Eigen::Vector3d eigenVertex(vertex.x, vertex.y, vertex.z);
minPoint = minPoint.cwiseMin(eigenVertex.cwiseProduct(mScale));
maxPoint = maxPoint.cwiseMax(eigenVertex.cwiseProduct(mScale));
}
}
mBoundingBox.setMin(
Eigen::Vector3d(min_X * mScale[0], min_Y * mScale[1], min_Z * mScale[2]));
mBoundingBox.setMax(
Eigen::Vector3d(max_X * mScale[0], max_Y * mScale[1], max_Z * mScale[2]));

mBoundingBox.setMin(minPoint);
mBoundingBox.setMax(maxPoint);

mIsBoundingBoxDirty = false;
}
Expand Down
16 changes: 16 additions & 0 deletions dart/dynamics/MeshShape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,24 @@ class MeshShape : public Shape

common::ResourceRetrieverPtr getResourceRetriever();

/// Sets the scale of the object using a 3D vector.
///
/// The scale is applied independently along each axis (x, y, z). Negative
/// values will mirror the object along the corresponding axis, potentially
/// flipping normals and causing inside-out geometry.
///
/// Use caution when applying negative scales as it may affect rendering and
/// physics calculations.
void setScale(const Eigen::Vector3d& scale);

/// Sets a uniform scale for the object across all axes.
void setScale(double scale);

/// Returns the current scale of the object as a 3D vector.
///
/// Each component of the vector represents the scale factor along the
/// corresponding axis (x, y, z). Negative values indicate that the object has
/// been mirrored along that axis.
const Eigen::Vector3d& getScale() const;

/// Set how the color of this mesh should be determined
Expand Down
11 changes: 7 additions & 4 deletions python/dartpy/dynamics/Shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,13 @@ void Shape(py::module& m)
})
.def(
"setScale",
+[](dart::dynamics::MeshShape* self, const Eigen::Vector3d& scale) {
self->setScale(scale);
},
::py::arg("scale"))
py::overload_cast<const Eigen::Vector3d&>(
&dart::dynamics::MeshShape::setScale),
py::arg("scale"))
.def(
"setScale",
py::overload_cast<double>(&dart::dynamics::MeshShape::setScale),
py::arg("scale"))
.def(
"getScale",
+[](const dart::dynamics::MeshShape* self) -> const Eigen::Vector3d& {
Expand Down

0 comments on commit e5c8c2c

Please sign in to comment.