From 4a40054c53e679a594966c927b5512e2e2159e4a Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Tue, 12 Dec 2023 18:53:10 +0900 Subject: [PATCH] [Type] Refactor Vec (#4296) * WIP * fix vecnoinit/vec, and constexpr init of array * add an other conversion for rgbacolor * correct aliases * fix tests compil * use correct type for getClosest * add compat for picking * polish * change type in image * remove superfluous typenames * no need to clear as it is already zero-init --- ...BarycentricMapperHexahedronSetTopology.inl | 2 +- .../linear/BarycentricMappingRigid.cpp | 2 +- .../fem/elastic/HexahedronFEMForceField.h | 2 +- .../fem/elastic/HexahedronFEMForceField.inl | 2 +- .../spring/JointSpringForceField.inl | 10 +- .../sofa/gui/common/ColourPickingVisitor.cpp | 37 ++++-- .../sofa/gui/common/ColourPickingVisitor.h | 16 ++- Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp | 6 +- .../Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp | 4 +- .../GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h | 2 +- .../Topology/src/sofa/topology/Hexahedron.h | 2 +- .../Topology/test/Hexahedron_test.cpp | 2 +- .../Type/src/sofa/type/BoundingBox.cpp | 16 +-- .../Type/src/sofa/type/RGBAColor.cpp | 5 + Sofa/framework/Type/src/sofa/type/RGBAColor.h | 2 + Sofa/framework/Type/src/sofa/type/Vec.h | 118 ++++++++++++++++-- Sofa/framework/Type/test/Color_test.cpp | 2 +- applications/plugins/image/ImageAlgorithms.h | 20 +-- 18 files changed, 191 insertions(+), 59 deletions(-) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl index 302fc6f7fe1..1887f6e2fd3 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappers/BarycentricMapperHexahedronSetTopology.inl @@ -184,7 +184,7 @@ void BarycentricMapperHexahedronSetTopology::handleTopologyChange(core:: const auto j = *iter; if ( mapData[j].in_index == sofa::InvalidID ) // compute new mapping { - sofa::type::fixed_array coefs; + type::Vec3 coefs; typename In::Coord pos; pos[0] = mapData[j].baryCoords[0]; pos[1] = mapData[j].baryCoords[1]; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp index 35911c33c3c..212bd8a786f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp @@ -86,7 +86,7 @@ void BarycentricMapperHexahedronSetTopology coefs; + sofa::type::Vec3 coefs; defaulttype::Vec3Types::Coord pos; pos[0] = mapData[j].baryCoords[0]; pos[1] = mapData[j].baryCoords[1]; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h index 536c7f45172..14801c77b62 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h @@ -195,7 +195,7 @@ class HexahedronFEMForceField : virtual public core::behavior::ForceFieldgetHexahedra()); } virtual void computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, - const type::fixed_array &nodes, const sofa::Index elementIndice, + const type::Vec<8, Coord> &nodes, const sofa::Index elementIndice, double stiffnessFactor=1.0) const; static Mat33 integrateStiffness( int signx0, int signy0, int signz0, int signx1, int signy1, int signz1, const Real u, const Real v, const Real w, const Mat33& J_1 ); diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl index 63546fe2062..0cf9f338b26 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl @@ -325,7 +325,7 @@ const typename HexahedronFEMForceField::Transformation& HexahedronFEM template -void HexahedronFEMForceField::computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const type::fixed_array &nodes, const sofa::Index elementIndice, double stiffnessFactor) const +void HexahedronFEMForceField::computeElementStiffness( ElementStiffness &K, const MaterialStiffness &M, const type::Vec<8, Coord> &nodes, const sofa::Index elementIndice, double stiffnessFactor) const { const bool verbose = elementIndice==0; // X = n0 (1-x1)(1-x2)(1-x3)/8 + n1 (1+x1)(1-x2)(1-x3)/8 + n2 (1+x1)(1+x2)(1-x3)/8 + n3 (1-x1)(1+x2)(1-x3)/8 + n4 (1-x1)(1-x2)(1+x3)/8 + n5 (1+x1)(1-x2)(1+x3)/8 + n6 (1+x1)(1+x2)(1+x3)/8 + n7 (1-x1)(1+x2)(1+x3)/8 diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl index e864065094a..8eba611bac6 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpringForceField.inl @@ -384,22 +384,22 @@ void JointSpringForceField::draw(const core::visual::VisualParams* vp for (sofa::Index i=0; i::min(); } -void decodeCollisionElement(const sofa::type::Vec4f colour, BodyPicked& body) +void decodeCollisionElement(const RGBAColor& colour, BodyPicked& body) { if( colour[0] > threshold || colour[1] > threshold || colour[2] > threshold ) // make sure we are not picking the background... @@ -70,7 +70,7 @@ void decodeCollisionElement(const sofa::type::Vec4f colour, BodyPicked& body) } -void decodePosition(BodyPicked& body, const sofa::type::Vec4f colour, const TriangleCollisionModel* model, +void decodePosition(BodyPicked& body, const RGBAColor& colour, const TriangleCollisionModel* model, const unsigned int index) { @@ -83,9 +83,11 @@ void decodePosition(BodyPicked& body, const sofa::type::Vec4f colour, const Tria } -void decodePosition(BodyPicked& body, const sofa::type::Vec4f /*colour*/, const SphereCollisionModel *model, +void decodePosition(BodyPicked& body, const RGBAColor& colour, const SphereCollisionModel *model, const unsigned int index) { + SOFA_UNUSED(colour); + const Sphere s(const_cast*>(model),index); body.point = s.center(); } @@ -97,6 +99,23 @@ simulation::Visitor::Result ColourPickingVisitor::processNodeTopDown(simulation: return RESULT_CONTINUE; } +void decodeCollisionElement(const sofa::type::Vec4f& colour, BodyPicked& body) +{ + decodeCollisionElement(sofa::type::RGBAColor::fromVec4(colour), body); +} + +void decodePosition(BodyPicked& body, const sofa::type::Vec4f& colour, const TriangleCollisionModel* model, + const unsigned int index) +{ + decodePosition(body, sofa::type::RGBAColor::fromVec4(colour), model, index); +} + +void decodePosition(BodyPicked& body, const sofa::type::Vec4f& colour, const SphereCollisionModel *model, + const unsigned int index) +{ + decodePosition(body, sofa::type::RGBAColor::fromVec4(colour), model, index); +} + void ColourPickingVisitor::processCollisionModel(simulation::Node* node , core::CollisionModel* o) { using namespace core::objectmodel; @@ -145,9 +164,9 @@ void ColourPickingVisitor::processTriangleModel(simulation::Node * node, sofa::c points.push_back( t.p1() ); points.push_back( t.p2() ); points.push_back( t.p3() ); - colours.push_back( Vec<4,float>(r,g,0,1) ); - colours.push_back( Vec<4,float>(r,g,0,1) ); - colours.push_back( Vec<4,float>(r,g,0,1) ); + colours.emplace_back( r,g,0,1 ); + colours.emplace_back( r,g,0,1 ); + colours.emplace_back( r,g,0,1 ); } break; case ENCODE_RELATIVEPOSITION: @@ -158,9 +177,9 @@ void ColourPickingVisitor::processTriangleModel(simulation::Node * node, sofa::c points.push_back( t.p1() ); points.push_back( t.p2() ); points.push_back( t.p3() ); - colours.push_back( Vec<4,float>(1,0,0,1) ); - colours.push_back( Vec<4,float>(0,1,0,1) ); - colours.push_back( Vec<4,float>(0,0,1,1) ); + colours.emplace_back( 1,0,0,1 ); + colours.emplace_back( 0,1,0,1 ); + colours.emplace_back( 0,0,1,1 ); } break; default: assert(false); diff --git a/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h b/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h index 2ad0d313b79..a49882953f6 100644 --- a/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h +++ b/Sofa/GUI/Common/src/sofa/gui/common/ColourPickingVisitor.h @@ -29,10 +29,20 @@ namespace sofa::gui::common { -void SOFA_GUI_COMMON_API decodeCollisionElement( const sofa::type::Vec4f colour, sofa::gui::component::performer::BodyPicked& body ); -void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, +void SOFA_GUI_COMMON_API decodeCollisionElement( const type::RGBAColor& colour, sofa::gui::component::performer::BodyPicked& body ); +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const type::RGBAColor& colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, const unsigned int index); -void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f colour, const sofa::component::collision::geometry::SphereCollisionModel* model, +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const type::RGBAColor& colour, const sofa::component::collision::geometry::SphereCollisionModel* model, + const unsigned int index); + +// compat +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodeCollisionElement( const sofa::type::Vec4f& colour, sofa::gui::component::performer::BodyPicked& body ); +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f& colour, const sofa::component::collision::geometry::TriangleCollisionModel* model, + const unsigned int index); +SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +void SOFA_GUI_COMMON_API decodePosition( sofa::gui::component::performer::BodyPicked& body, const sofa::type::Vec4f& colour, const sofa::component::collision::geometry::SphereCollisionModel* model, const unsigned int index); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp index c8fc4a28201..3a9c874eea1 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/GLPickHandler.cpp @@ -107,7 +107,7 @@ BodyPicked GLPickHandler::findCollisionUsingColourCoding(const type::Vec3& origi BodyPicked result; result.dist = 0; - sofa::type::Vec4f color; + type::RGBAColor color; const int x = mousePosition.x; const int y = mousePosition.screenHeight - mousePosition.y; TriangleCollisionModel* tmodel; @@ -116,10 +116,10 @@ BodyPicked GLPickHandler::findCollisionUsingColourCoding(const type::Vec3& origi if(renderCallback) { renderCallback->render(ColourPickingVisitor::ENCODE_COLLISIONELEMENT ); - glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems); + glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType, &color[0]); decodeCollisionElement(color,result); renderCallback->render(ColourPickingVisitor::ENCODE_RELATIVEPOSITION ); - glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType,color.elems); + glReadPixels(x,y,1,1,_fboParams.colorFormat,_fboParams.colorType, &color[0]); if( ( tmodel = dynamic_cast*>(result.body) ) != nullptr ) { decodePosition(result,color,tmodel,result.indexCollisionElement); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp index 31bbb94cbe8..8148021a158 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp @@ -61,11 +61,11 @@ QRGBAColorPicker::QRGBAColorPicker(QWidget* parent) : QWidget(parent) connect( _colorButton, SIGNAL( clicked() ), this, SLOT( raiseQColorDialog() ) ); } -Vec4f QRGBAColorPicker::getColor() const +type::RGBAColor QRGBAColorPicker::getColor() const { typedef unsigned char uchar; constexpr uchar max = std::numeric_limits::max(); - Vec4f color; + type::RGBAColor color; float r = _r->text().toFloat(); float g = _g->text().toFloat(); float b = _b->text().toFloat(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h index 8c8fd37bd6f..684bae13677 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h @@ -61,7 +61,7 @@ class QRGBAColorPicker : public QWidget void setColor(const type::RGBAColor& color); void setColor( const Vec4f& color ); - Vec4f getColor() const; + type::RGBAColor getColor() const; protected: QRgb _rgba; diff --git a/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h b/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h index 873f2251461..619ac1ee282 100644 --- a/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h +++ b/Sofa/framework/Topology/src/sofa/topology/Hexahedron.h @@ -32,7 +32,7 @@ namespace sofa::topology template static constexpr sofa::Index getClosestHexahedronIndex(const VectorCoordinates& hexahedronPositions, const sofa::type::vector& hexahedra, - const Coordinates& pos, sofa::type::fixed_array& barycentricCoefficients, SReal& distance) + const Coordinates& pos, type::Vec3& barycentricCoefficients, SReal& distance) { sofa::Index index = sofa::InvalidID; distance = std::numeric_limits::max(); diff --git a/Sofa/framework/Topology/test/Hexahedron_test.cpp b/Sofa/framework/Topology/test/Hexahedron_test.cpp index 240bcfcf75f..080a0858617 100644 --- a/Sofa/framework/Topology/test/Hexahedron_test.cpp +++ b/Sofa/framework/Topology/test/Hexahedron_test.cpp @@ -77,7 +77,7 @@ namespace sofa TEST(TopologyHexahedron_test, getClosestHexahedronIndex) { - sofa::type::fixed_array coeffs{}; + type::Vec3 coeffs{}; SReal distance{}; const sofa::type::Vec3d pos0{0.001, 0., 0.}; diff --git a/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp b/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp index 5baae9df773..08c9121191e 100644 --- a/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp +++ b/Sofa/framework/Type/src/sofa/type/BoundingBox.cpp @@ -114,22 +114,22 @@ BoundingBox::operator bbox_t() const SReal* BoundingBox::minBBoxPtr() { - return bbox.first.elems; + return bbox.first.ptr(); } SReal* BoundingBox::maxBBoxPtr() { - return bbox.second.elems; + return bbox.second.ptr(); } const SReal* BoundingBox::minBBoxPtr() const { - return bbox.first.elems; + return bbox.first.ptr(); } const SReal* BoundingBox::maxBBoxPtr() const { - return bbox.second.elems; + return bbox.second.ptr(); } const sofa::type::Vec3& BoundingBox::minBBox() const @@ -360,22 +360,22 @@ BoundingBox2D::operator bbox_t() const SReal* BoundingBox2D::minBBoxPtr() { - return bbox.first.elems; + return bbox.first.ptr(); } SReal* BoundingBox2D::maxBBoxPtr() { - return bbox.second.elems; + return bbox.second.ptr(); } const SReal* BoundingBox2D::minBBoxPtr() const { - return bbox.first.elems; + return bbox.first.ptr(); } const SReal* BoundingBox2D::maxBBoxPtr() const { - return bbox.second.elems; + return bbox.second.ptr(); } const sofa::type::Vec<2, SReal>& BoundingBox2D::minBBox() const diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index 7e0e88208dd..3d01fc53646 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -91,6 +91,11 @@ RGBAColor::RGBAColor(const type::fixed_array& c) { } +RGBAColor::RGBAColor(const type::Vec4f& c) + : m_components{ c[0], c[1], c[2], c[3] } +{ +} + bool RGBAColor::read(const std::string& str, RGBAColor& color) { std::stringstream s(str); diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index 76a44dc3fb0..637b0c86ddb 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -60,6 +60,8 @@ class SOFA_TYPE_API RGBAColor // compat SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() RGBAColor(const type::fixed_array& c); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + RGBAColor(const type::Vec4f& c); SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() static RGBAColor fromVec4(const type::fixed_array& color); diff --git a/Sofa/framework/Type/src/sofa/type/Vec.h b/Sofa/framework/Type/src/sofa/type/Vec.h index e090a3d5e8f..7c1bd70928e 100644 --- a/Sofa/framework/Type/src/sofa/type/Vec.h +++ b/Sofa/framework/Type/src/sofa/type/Vec.h @@ -30,6 +30,7 @@ #include #include #include +#include #define EQUALITY_THRESHOLD 1e-6 @@ -54,13 +55,25 @@ struct NoInit {}; constexpr NoInit NOINIT; template < sofa::Size N, typename ValueType> -class Vec : public sofa::type::fixed_array +class Vec { - static_assert( N > 0, "" ); public: - typedef sofa::Size Size; + using ArrayType = std::array; + ArrayType elems{}; + + typedef sofa::Size Size; + typedef ValueType value_type; + typedef typename ArrayType::iterator iterator; + typedef typename ArrayType::const_iterator const_iterator; + typedef typename ArrayType::reference reference; + typedef typename ArrayType::const_reference const_reference; + typedef sofa::Size size_type; + typedef std::ptrdiff_t difference_type; + + static constexpr sofa::Size static_size = N; + static constexpr sofa::Size size() { return static_size; } /// Compile-time constant specifying the number of scalars within this vector (equivalent to static_size and size() method) static constexpr Size total_size = N; @@ -68,10 +81,7 @@ class Vec : public sofa::type::fixed_array static constexpr Size spatial_dimensions = N; /// Default constructor: sets all values to 0. - constexpr Vec() - { - this->clear(); - } + constexpr Vec() = default; /// Fast constructor: no initialization explicit constexpr Vec(NoInit) @@ -90,7 +100,7 @@ class Vec : public sofa::type::fixed_array typename = std::enable_if_t< (sizeof...(ArgsT) == N && sizeof...(ArgsT) > 1) > > constexpr Vec(ArgsT&&... r) noexcept - : sofa::type::fixed_array(std::forward(r)...) + : elems{ static_cast(std::forward< ArgsT >(r))... } {} /// Specific constructor for 6-elements vectors, taking two 3-elements vectors @@ -237,6 +247,13 @@ class Vec : public sofa::type::fixed_array this->elems[i] = (ValueType)v(i); } + // assign one value to all elements + constexpr void assign(const ValueType& value) noexcept + { + for (size_type i = 0; i < N; i++) + elems[i] = value; + } + /// Sets every element to 0. constexpr void clear() noexcept { @@ -264,13 +281,13 @@ class Vec : public sofa::type::fixed_array /// Cast into a const array of values. constexpr const ValueType* ptr() const noexcept { - return this->elems; + return this->elems.data(); } /// Cast into an array of values. constexpr ValueType* ptr() noexcept { - return this->elems; + return this->elems.data(); } // LINEAR ALGEBRA @@ -527,7 +544,7 @@ class Vec : public sofa::type::fixed_array /// return true if norm()==1 bool isNormalized( ValueType threshold=std::numeric_limits::epsilon()*(ValueType)10 ) const - { + { return rabs( norm2() - static_cast(1) ) <= threshold; } @@ -569,10 +586,66 @@ class Vec : public sofa::type::fixed_array return false; } + + // operator[] + constexpr reference operator[](size_type i) + { + assert(i < N && "index in Vec must be smaller than size"); + return elems[i]; + } + constexpr const_reference operator[](size_type i) const + { + assert(i < N && "index in Vec must be smaller than size"); + return elems[i]; + } + + // direct access to data + constexpr const ValueType* data() const noexcept + { + return elems.data(); + } + + constexpr iterator begin() noexcept + { + return elems.begin(); + } + constexpr const_iterator begin() const noexcept + { + return elems.begin(); + } + + constexpr iterator end() noexcept + { + return elems.end(); + } + constexpr const_iterator end() const noexcept + { + return elems.end(); + } + + constexpr reference front() + { + return elems[0]; + } + constexpr const_reference front() const + { + return elems[0]; + } + constexpr reference back() + { + return elems[N - 1]; + } + constexpr const_reference back() const + { + return elems[N - 1]; + } + /// @} }; + + /// Same as Vec except the values are not initialized by default template class VecNoInit : public Vec @@ -581,6 +654,15 @@ class VecNoInit : public Vec constexpr VecNoInit() noexcept : Vec(NOINIT) {} + + constexpr VecNoInit(const Vec& v) noexcept + : Vec(v) + {} + + constexpr VecNoInit(Vec&& v) noexcept + : Vec(v) + {} + using Vec::Vec; using Vec::operator=; // make every = from Vec available @@ -648,6 +730,20 @@ constexpr Vec operator*(const float& a, const Vec& V) noexcept return V * a; } +/// Checks if v1 is lexicographically less than v2. Similar to std::lexicographical_compare +template +constexpr bool operator<(const Vec& v1, const Vec& v2) noexcept +{ + for (sofa::Size i = 0; i < N; i++) + { + if (v1[i] < v2[i]) + return true; + if (v2[i] < v1[i]) + return false; + } + return false; +} + } // namespace sofa::type // Specialization of the std comparison function, to use Vec as std::map key diff --git a/Sofa/framework/Type/test/Color_test.cpp b/Sofa/framework/Type/test/Color_test.cpp index c4b062879ba..3e722c8d03a 100644 --- a/Sofa/framework/Type/test/Color_test.cpp +++ b/Sofa/framework/Type/test/Color_test.cpp @@ -142,7 +142,7 @@ void Color_Test::checkCreateFromDouble() void Color_Test::checkConstructors() { - EXPECT_EQ(RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); + EXPECT_EQ( RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); EXPECT_EQ( RGBAColor(sofa::type::Vec<4, float>(1, 2, 3, 4)), RGBAColor(1, 2, 3, 4)); } diff --git a/applications/plugins/image/ImageAlgorithms.h b/applications/plugins/image/ImageAlgorithms.h index 3fed474aae1..b29d85b475d 100644 --- a/applications/plugins/image/ImageAlgorithms.h +++ b/applications/plugins/image/ImageAlgorithms.h @@ -300,7 +300,7 @@ real norm(cimg_library::CImg& distances, sofa::type::fixed_array& /// @brief Replace value at oldCoord with a combinaison of value at newCoord, a offset and a bias if provided template void replace(cimg_library::CImg& voronoi, cimg_library::CImg& distances, sofa::type::fixed_array& oldCoord, sofa::type::fixed_array& newCoord, - sofa::type::fixed_array& offset, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* bias) + sofa::type::fixed_array& offset, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* bias) { real b=1.0; if(bias) @@ -313,7 +313,7 @@ void replace(cimg_library::CImg& voronoi, cimg_library::CImg /// @brief Update value of the pixel of an image after comparing it with its neighbor template -void update(cimg_library::CImg& distances, cimg_library::CImg& voronoi, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& coord, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& offset, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* bias) +void update(cimg_library::CImg& distances, cimg_library::CImg& voronoi, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& coord, sofa::type::fixed_array< sofa::type::fixed_array, 10 >& offset, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* bias) { real l_curr=norm(distances,coord[0]); for(int l=1; l<=9; ++l) @@ -348,7 +348,7 @@ bool hasConverged(cimg_library::CImg& previous, cimg_library::CImg& /// @brief Perform a raster scan from left to right to update distances template -void left(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void left(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int i=d.width()-2; i>=0; --i) { @@ -375,7 +375,7 @@ void left(cimg_library::CImg& v, cimg_library::CImg& d, cons /// @brief Perform a raster scan from right to left to update distances template -void right(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void right(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int i=1; i& v, cimg_library::CImg& d, con /// @brief Perform a raster scan from down to up to update distances template -void down(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void down(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int j=d.height()-2; j>=0; --j) { @@ -429,7 +429,7 @@ void down(cimg_library::CImg& v, cimg_library::CImg& d, cons /// @brief Perform a raster scan from up to down to update distances template -void up(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void up(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int j=1; j& v, cimg_library::CImg& d, const /// @brief Perform a raster scan from backward to forward to update distances template -void backward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void backward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int k=d.depth()-2; k>=0; --k) { @@ -483,7 +483,7 @@ void backward(cimg_library::CImg& v, cimg_library::CImg& d, /// @brief Perform a raster scan from forward to backward to update distances template -void forward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::fixed_array& vx, const cimg_library::CImg* bias) +void forward(cimg_library::CImg& v, cimg_library::CImg& d, const sofa::type::Vec<3, real>& vx, const cimg_library::CImg* bias) { for(int k=1; k& v, cimg_library::CImg& d, c /// @brief Perform 6 raster scan of an image to fully cover it. template -void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg& distances, const sofa::type::fixed_array& voxelSize, const cimg_library::CImg* biasFactor=NULL) +void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg& distances, const sofa::type::Vec<3, real>& voxelSize, const cimg_library::CImg* biasFactor=NULL) { right(voronoi, distances, voxelSize, biasFactor); left(voronoi, distances, voxelSize, biasFactor); @@ -528,7 +528,7 @@ void rasterScan(cimg_library::CImg& voronoi, cimg_library::CImg -void parallelMarching(cimg_library::CImg& distances, cimg_library::CImg& voronoi, const sofa::type::fixed_array& voxelSize, const unsigned int maxIter=std::numeric_limits::max(), const SReal tolerance=10, const cimg_library::CImg* biasFactor=NULL) +void parallelMarching(cimg_library::CImg& distances, cimg_library::CImg& voronoi, const sofa::type::Vec<3, real>& voxelSize, const unsigned int maxIter=std::numeric_limits::max(), const SReal tolerance=10, const cimg_library::CImg* biasFactor=NULL) { if(distances.width()<3 || distances.height()<3 || distances.depth()<3) {