Skip to content

Commit

Permalink
[Type] A concept for isRigidType (sofa-framework#5199)
Browse files Browse the repository at this point in the history
* [Type] A concept for isRigidType

* fix
  • Loading branch information
alxbilger authored Jan 16, 2025
1 parent f28c570 commit 84e79d1
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ UncoupledConstraintCorrection<DataTypes>::UncoupledConstraintCorrection(sofa::co
else
{
// Case: soft body
if constexpr (!sofa::type::isRigidType<DataTypes>())
if constexpr (!sofa::type::isRigidType<DataTypes>)
{
const VecReal &comp = d_compliance.getValue();
if (std::any_of(comp.begin(), comp.end(), [](const Real c) { return c == 0; }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void RestShapeSpringsForceField<DataTypes>::bwdInit()
/// Compile time condition to check if we are working with a Rigid3Types or a type that does not
/// need the Angular Stiffness parameters.
//if constexpr (isRigid())
if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
sofa::helper::ReadAccessor<Data<VecReal>> s = d_stiffness;
sofa::helper::WriteOnlyAccessor<Data<VecReal>> as = d_angularStiffness;
Expand Down Expand Up @@ -369,7 +369,7 @@ void RestShapeSpringsForceField<DataTypes>::addForce(const MechanicalParams* mp
const auto activeDirections = d_activeDirections.getValue();

// rigid case
if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
// translation
if (i >= m_pivots.size())
Expand Down Expand Up @@ -452,7 +452,7 @@ void RestShapeSpringsForceField<DataTypes>::addDForce(const MechanicalParams* mp
const sofa::Index curIndex = m_indices[i];
const auto stiffness = k[static_cast<std::size_t>(i < k.size()) * i];

if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
const auto angularStiffness = k_a[static_cast<std::size_t>(i < k_a.size()) * i];

Expand Down Expand Up @@ -574,7 +574,7 @@ void RestShapeSpringsForceField<DataTypes>::addKToMatrix(const MechanicalParams*
}

// rotation (if applicable)
if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
const auto vr = -kFact * k_a[(index < k_a.size()) * index];
for (sofa::Size i = space_size; i < total_size; i++)
Expand Down Expand Up @@ -611,7 +611,7 @@ void RestShapeSpringsForceField<DataTypes>::buildStiffnessMatrix(core::behavior:
}

// rotation (if applicable)
if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
const auto vr = -k_a[(index < k_a.size()) * index];
for (sofa::Size i = space_size; i < total_size; ++i)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ bool ConstraintAttachBodyPerformer<DataTypes>::startPartial(const BodyPicked& pi
this->m_interactionObject = sofa::core::objectmodel::New<BilateralLagrangianConstraint<DataTypes> >(m_mstate1, m_mstate2);
auto* bconstraint = dynamic_cast< BilateralLagrangianConstraint< DataTypes >* >(this->m_interactionObject.get());

if constexpr (sofa::type::isRigidType<DataTypes>())
if constexpr (sofa::type::isRigidType<DataTypes>)
{
// BilateralLagrangianConstraint::d_keepOrientDiff is protected
auto* keepOrientDiffBaseData = bconstraint->findData("keepOrientationDifference");
Expand Down
7 changes: 7 additions & 0 deletions Sofa/framework/DefaultType/src/sofa/defaulttype/RigidTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <sofa/helper/rmath.h>
#include <sofa/helper/random.h>
#include <cmath>
#include <sofa/type/isRigidType.h>


namespace sofa::defaulttype
Expand Down Expand Up @@ -251,6 +252,9 @@ template<> constexpr const char* Rigid3fTypes::Name() { return "Rigid3f"; }
typedef StdRigidTypes<3,SReal> Rigid3Types; ///< un-defined precision type
typedef StdRigidTypes<3,SReal> RigidTypes; ///< alias (beurk)

static_assert(type::isRigidType<Rigid3dTypes>);
static_assert(type::isRigidType<Rigid3fTypes>);

//=============================================================================
// 2D Rigids
//=============================================================================
Expand Down Expand Up @@ -413,6 +417,9 @@ class StdRigidTypes<2, real>
template<> constexpr const char* Rigid2dTypes::Name() { return "Rigid2d"; }
template<> constexpr const char* Rigid2fTypes::Name() { return "Rigid2f"; }

static_assert(type::isRigidType<Rigid2dTypes>);
static_assert(type::isRigidType<Rigid2fTypes>);

/// \endcond


Expand Down
13 changes: 13 additions & 0 deletions Sofa/framework/DefaultType/src/sofa/defaulttype/VecTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <ostream>
#include <algorithm>
#include <memory>
#include <sofa/type/isRigidType.h>


namespace sofa:: defaulttype
{
Expand Down Expand Up @@ -236,4 +238,15 @@ typedef StdVectorTypes<type::Vec2, type::Vec2, type::Vec2::value_type> Vec2Types
typedef StdVectorTypes<type::Vec1, type::Vec1, type::Vec1::value_type> Vec1Types;


static_assert(!type::isRigidType<Vec6dTypes>);
static_assert(!type::isRigidType<Vec3dTypes>);
static_assert(!type::isRigidType<Vec2dTypes>);
static_assert(!type::isRigidType<Vec1dTypes>);

static_assert(!type::isRigidType<Vec6fTypes>);
static_assert(!type::isRigidType<Vec3fTypes>);
static_assert(!type::isRigidType<Vec2fTypes>);
static_assert(!type::isRigidType<Vec1fTypes>);


} // namespace sofa:: defaulttype
60 changes: 35 additions & 25 deletions Sofa/framework/Type/src/sofa/type/isRigidType.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
//
// Created by hugo on 28/11/23.
//

#ifndef SOFA_ISRIGIDTYPE_H
#define SOFA_ISRIGIDTYPE_H
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture *
* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: [email protected] *
******************************************************************************/
#pragma once

namespace sofa::type
{
// Boiler-plate code to test if a type implements a method
// explanation https://stackoverflow.com/a/30848101

template <typename...>
using void_t = void;

// Primary template handles all types not supporting the operation.
template <typename, template <typename> class, typename = void_t<>>
struct detect : std::false_type {};

// Specialization recognizes/validates only types supporting the archetype.
template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};

// Actual test if DataType::Coord implements getOrientation() (hence is a RigidType)
template <typename T>
using isRigid_t = decltype(std::declval<typename T::Coord>().getOrientation());
/**
* A type T satisfies the isRigidType concept if:
* - T has a nested type named Coord.
* - An object of type T::Coord has a member function getOrientation that can be
* invoked without arguments.
*
* It allows to identify types such as StdRigidTypes and CudaRigidTypes at compile-time.
*/
template<class T>
concept isRigidType = requires
{
std::declval<typename T::Coord>().getOrientation();
};

template <typename T>
using isRigidType = detect<T, isRigid_t>;
}
#endif //SOFA_ISRIGIDTYPE_H

0 comments on commit 84e79d1

Please sign in to comment.