From 77d5337dadf63c9acbe6d089ef114d46657bfc71 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 4 Oct 2022 15:17:29 +0200 Subject: [PATCH 01/60] [doc] Add some comments --- src/BeamAdapter/component/engine/WireRestShape.h | 5 +++-- src/BeamAdapter/component/engine/WireRestShape.inl | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 0e2837750..73b40ed24 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -54,8 +54,9 @@ using sofa::core::loader::MeshLoader; /** * \class WireRestShape * \brief Describe the shape functions on multiple segments - * - * Describe the shape functions on multiple segments using curvilinear abscissa + * + * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. */ template class WireRestShape : public core::objectmodel::BaseObject diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index b52af1aff..ba08a09d3 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -295,7 +295,8 @@ void WireRestShape::init() template -void WireRestShape::releaseWirePart(){ +void WireRestShape::releaseWirePart() +{ d_brokenIn2.setValue(true); From f7aed15066b698d2ed62ead22d0785eddbbf60e4 Mon Sep 17 00:00:00 2001 From: epernod Date: Sat, 24 Sep 2022 00:32:46 +0200 Subject: [PATCH 02/60] Add WireSectionMaterial component to store the material property of a wire section and delegate the interpolation param to this class --- CMakeLists.txt | 6 +- .../component/model/WireSectionMaterial.cpp | 90 +++++++++++++++++++ .../component/model/WireSectionMaterial.h | 68 ++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 src/BeamAdapter/component/model/WireSectionMaterial.cpp create mode 100644 src/BeamAdapter/component/model/WireSectionMaterial.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d6e65453..f1e59b498 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,9 @@ set(HEADER_FILES ${BEAMADAPTER_SRC}/component/mapping/AdaptiveBeamMapping.inl ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.h ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.inl - + + ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.h + ${BEAMADAPTER_SRC}/utils/BeamSection.h ${BEAMADAPTER_SRC}/utils/deprecatedcomponent.h ) @@ -80,6 +82,8 @@ set(SOURCE_FILES ${BEAMADAPTER_SRC}/component/mapping/AdaptiveBeamMapping.cpp ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.cpp + + ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.cpp ) if(SofaImplicitField_FOUND) diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp new file mode 100644 index 000000000..39c45f934 --- /dev/null +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -0,0 +1,90 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_PLUGIN_BEAMADAPTER_WIRERESTSHAPE_CPP + +#include +#include +#include + +namespace sofa::beamadapter +{ + +using namespace sofa::defaulttype; + +int WireSectionMaterialClass = core::RegisterObject("Wire Section Material.") +.add< WireSectionMaterial >(); + + +WireSectionMaterial::WireSectionMaterial() + : d_poissonRatio(initData(&d_poissonRatio, (SReal)0.49, "poissonRatio", "Poisson Ratio")) + , d_youngModulus(initData(&d_youngModulus, (SReal)5000, "youngModulus", "Young Modulus")) + , d_radius(initData(&d_radius, (SReal)1.0f, "radius", "radius")) + , d_innerRadius(initData(&d_innerRadius, (SReal)0.0f, "innerRadius", "inner radius if it applies")) + , d_massDensity(initData(&d_massDensity, (SReal)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) +{ + +} + + +void WireSectionMaterial::init() +{ + // Prepare beam sections + double r = this->d_radius.getValue(); + double rInner = this->d_innerRadius.getValue(); + this->beamSection._r = r; + this->beamSection._rInner = rInner; + this->beamSection._Iz = M_PI * (r * r * r * r - rInner * rInner * rInner * rInner) / 4.0; + this->beamSection._Iy = this->beamSection._Iz; + this->beamSection._J = this->beamSection._Iz + this->beamSection._Iy; + this->beamSection._A = M_PI * (r * r - rInner * rInner); + this->beamSection._Asy = 0.0; + this->beamSection._Asz = 0.0; +} + + +/// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position +void WireSectionMaterial::getYoungModulusAtX(SReal& youngModulus, SReal& cPoisson) +{ + youngModulus = this->d_youngModulus.getValue(); + cPoisson = this->d_poissonRatio.getValue(); +} + + +/// This function gives the mass density and the BeamSection data depending on the beam position +void WireSectionMaterial::getInterpolationParam(SReal& _rho, SReal& _A, SReal& _Iy, SReal& _Iz, SReal& _Asy, SReal& _Asz, SReal& _J) +{ + if (d_massDensity.isSet()) + _rho = d_massDensity.getValue(); + + if (d_radius.isSet()) + { + _A = beamSection._A; + _Iy = beamSection._Iy; + _Iz = beamSection._Iz; + _Asy = beamSection._Asy; + _Asz = beamSection._Asz; + _J = beamSection._J; + } +} + + +}// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h new file mode 100644 index 000000000..46adb070d --- /dev/null +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -0,0 +1,68 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::beamadapter +{ + +/** + * \class WireRestShape + * \brief Describe the shape functions on multiple segments + * + * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + */ +class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseObject +{ +public: + SOFA_CLASS(WireSectionMaterial, core::objectmodel::BaseObject); + + /// Default Constructor + WireSectionMaterial(); + + + void init(); + + /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position + void getYoungModulusAtX(SReal& youngModulus, SReal& cPoisson); + + /// This function gives the mass density and the BeamSection data depending on the beam position + void getInterpolationParam(SReal& _rho, SReal& _A, SReal& _Iy, SReal& _Iz, SReal& _Asy, SReal& _Asz, SReal& _J); + + + /// User Data about the Young modulus + Data d_poissonRatio; + Data d_youngModulus; + + /// Radius + Data d_radius; + Data d_innerRadius; + Data d_massDensity; +protected: + BeamSection beamSection; +}; + +} // namespace sofa::beamadapter From bd991f72105f484b3c24b391e31acc310dba755a Mon Sep 17 00:00:00 2001 From: epernod Date: Sat, 24 Sep 2022 00:33:18 +0200 Subject: [PATCH 03/60] Update WireREstShape to use the new WireMaterialSection links --- .../component/engine/WireRestShape.h | 27 ++---- .../component/engine/WireRestShape.inl | 97 +++---------------- 2 files changed, 21 insertions(+), 103 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 73b40ed24..bee155855 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -34,6 +34,8 @@ #include #include +#include + #include #include #include @@ -51,6 +53,8 @@ using sofa::component::topology::container::dynamic::EdgeSetTopologyModifier; using sofa::component::topology::mapping::Edge2QuadTopologicalMapping; using sofa::core::loader::MeshLoader; +using namespace sofa::beamadapter; + /** * \class WireRestShape * \brief Describe the shape functions on multiple segments @@ -142,24 +146,16 @@ class WireRestShape : public core::objectmodel::BaseObject Data< int > d_numEdges; Data > d_numEdgesCollis; - /// User Data about the Young modulus - Data d_poissonRatio; - Data d_youngModulus1; - Data d_youngModulus2; - - /// Radius - Data d_radius1; - Data d_radius2; - Data d_innerRadius1; - Data d_innerRadius2; - - Data d_massDensity1; - Data d_massDensity2; - /// broken in 2 case Data d_brokenIn2; Data d_drawRestShape; + /// Link to be set to the topology container in the component graph. + SingleLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterial1; + + /// Link to be set to the topology container in the component graph. + SingleLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterial2; + private: /// Data required for the File loading type::vector m_localRestPositions; @@ -167,9 +163,6 @@ class WireRestShape : public core::objectmodel::BaseObject type::vector m_curvAbs ; double m_absOfGeometry {0}; - BeamSection beamSection1; - BeamSection beamSection2; - /// Link to be set to the topology container in the component graph. SingleLink, TopologyContainer, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; /// Pointer to the topology container, should be set using @sa l_topology, otherwise will search for one in current Node. diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index ba08a09d3..52af5f824 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -70,17 +70,10 @@ WireRestShape::WireRestShape() : , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) , d_numEdges(initData(&d_numEdges, 10, "numEdges","number of Edges for the visual model")) , d_numEdgesCollis(initData(&d_numEdgesCollis,"numEdgesCollis", "number of Edges for the collision model" )) - , d_poissonRatio(initData(&d_poissonRatio,(Real)0.49,"poissonRatio","Poisson Ratio")) - , d_youngModulus1(initData(&d_youngModulus1,(Real)5000,"youngModulus","Young Modulus")) - , d_youngModulus2(initData(&d_youngModulus2,(Real)3000,"youngModulusExtremity","youngModulus for beams at the extremity\nonly if not straight")) - , d_radius1(initData(&d_radius1,(Real)1.0f,"radius","radius")) - , d_radius2(initData(&d_radius2,(Real)1.0f,"radiusExtremity","radius for beams at the extremity\nonly if not straight")) - , d_innerRadius1(initData(&d_innerRadius1,(Real)0.0f,"innerRadius","inner radius if it applies")) - , d_innerRadius2(initData(&d_innerRadius2,(Real)0.0f,"innerRadiusExtremity","inner radius for beams at the extremity\nonly if not straight")) - , d_massDensity1(initData(&d_massDensity1,(Real)1.0,"massDensity", "Density of the mass (usually in kg/m^3)" )) - , d_massDensity2(initData(&d_massDensity2,(Real)1.0,"massDensityExtremity", "Density of the mass at the extremity\nonly if not straight" )) , d_brokenIn2(initData(&d_brokenIn2, (bool)false, "brokenIn2", "")) , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) + , l_sectionMaterial1(initLink("main_material", "link to the fist Wire Section Material")) + , l_sectionMaterial2(initLink("extremity_material", "link to the second Wire Section Material")) , l_topology(initLink("topology", "link to the topology container")) , l_loader(initLink("loader", "link to the MeshLoader")) , l_edge2QuadMapping(initLink("edge2QuadMapping", "link to the edge2QuadMapping to render this beam")) @@ -267,29 +260,6 @@ void WireRestShape::init() msg_info() <<"WireRestShape end init" ; - // Prepare beam sections - double r = this->d_radius1.getValue(); - double rInner = this->d_innerRadius1.getValue(); - this->beamSection1._r = r; - this->beamSection1._rInner = rInner; - this->beamSection1._Iz = M_PI*(r*r*r*r - rInner*rInner*rInner*rInner)/4.0; - this->beamSection1._Iy = this->beamSection1._Iz ; - this->beamSection1._J = this->beamSection1._Iz + this->beamSection1._Iy; - this->beamSection1._A = M_PI*(r*r - rInner*rInner); - this->beamSection1._Asy = 0.0; - this->beamSection1._Asz = 0.0; - - r = this->d_radius2.getValue(); - rInner = this->d_innerRadius2.getValue(); - this->beamSection2._r = r; - this->beamSection2._rInner = rInner; - this->beamSection2._Iz = M_PI*(r*r*r*r - rInner*rInner*rInner*rInner)/4.0; - this->beamSection2._Iy = this->beamSection2._Iz ; - this->beamSection2._J = this->beamSection2._Iz + this->beamSection2._Iy; - this->beamSection2._A = M_PI*(r*r - rInner*rInner); - this->beamSection2._Asy = 0.0; - this->beamSection2._Asz = 0.0; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } @@ -468,31 +438,11 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co template void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) { - //Initialization - Real _E1, _E2; - youngModulus = 0.0; - cPoisson = 0.0; - - //Get the two possible values of the Young modulus - _E1 = this->d_youngModulus1.getValue(); - _E2 = this->d_youngModulus2.getValue(); - - //Get User data - cPoisson = this->d_poissonRatio.getValue(); - //Depending on the position of the beam, determine the Young modulus - if(x_curv <= this->d_straightLength.getValue()) - { - youngModulus = _E1; - } + if (x_curv > this->d_straightLength.getValue() && l_sectionMaterial2.get()) // extremity of the wire + return l_sectionMaterial2.get()->getYoungModulusAtX(youngModulus, cPoisson); else - { - if(_E2 == 0.0) - youngModulus = _E1; - else - youngModulus = _E2; - } - return; + return l_sectionMaterial1.get()->getYoungModulusAtX(youngModulus, cPoisson); } @@ -501,43 +451,18 @@ void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_ { if(x_curv <= this->d_straightLength.getValue()) { - if(d_massDensity1.isSet()) - _rho = d_massDensity1.getValue(); - - if(d_radius1.isSet()) - { - _A =beamSection1._A; - _Iy =beamSection1._Iy; - _Iz =beamSection1._Iz; - _Asy =beamSection1._Asy; - _Asz =beamSection1._Asz; - _J =beamSection1._J; - } + return l_sectionMaterial1.get()->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); } else { - if(d_massDensity2.isSet()) - _rho = d_massDensity2.getValue(); - else if(d_massDensity1.isSet()) - _rho = d_massDensity1.getValue(); - - if(d_radius2.isSet()) + auto mat = l_sectionMaterial2.get(); + if (mat) { - _A =beamSection2._A; - _Iy =beamSection2._Iy; - _Iz =beamSection2._Iz; - _Asy =beamSection2._Asy; - _Asz =beamSection2._Asz; - _J =beamSection2._J; + return mat->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); } - else if(d_radius1.isSet()) + else { - _A =beamSection1._A; - _Iy =beamSection1._Iy; - _Iz =beamSection1._Iz; - _Asy =beamSection1._Asy; - _Asz =beamSection1._Asz; - _J =beamSection1._J; + return l_sectionMaterial1.get()->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); } } } From 2ca0d787626e279de101410998d3f97ff6cfa92d Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 26 Sep 2022 09:15:47 +0200 Subject: [PATCH 04/60] Add check on BeamMAterial section --- src/BeamAdapter/component/engine/WireRestShape.inl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 52af5f824..9cfc68e3b 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -154,6 +154,13 @@ void WireRestShape::init() } } + if (!l_sectionMaterial1.get()) + { + msg_error() << "No WireSectionMaterial set. At least one material should be set and link using main_material"; + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + return; + } + ////////////////////////////////////////////// ////////// get and fill local topology /////// ////////////////////////////////////////////// From 91bd6bfc3d663f3c056ec4196d486625318460be Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Sep 2022 17:26:18 +0200 Subject: [PATCH 05/60] [WireRestShape] Remove use of Edge2QuatTopologyMapping, no need to propagate topology change. It will be done automatically through topology changes pipeline --- .../component/engine/WireRestShape.h | 3 --- .../component/engine/WireRestShape.inl | 24 +------------------ 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index bee155855..c6e52fc77 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -177,9 +177,6 @@ class WireRestShape : public core::objectmodel::BaseObject /// Link to a Edge2QuadTopologicalMapping, usually used for beam surface rendering to be set to propagate topological changes SingleLink, Edge2QuadTopologicalMapping, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_edge2QuadMapping; - /// Pointer to a Edge2QuadTopologicalMapping usually used for beam surface rendering. To be set using @sa l_edge2QuadMapping - Edge2QuadTopologicalMapping* edge2QuadMap{ nullptr }; - }; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 9cfc68e3b..24a73d2f0 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -211,16 +211,6 @@ void WireRestShape::init() for (int i=0; iaddEdge(i,i+1); - /// Get possible edge2Quad Mapping if one set. - // TODO epernod 2022-08-05: check if the pointer to the mapping is still useful. Only used in releaseWirePart which should be now automatically handle by Topological changes mechanism. - edge2QuadMap = l_edge2QuadMapping.get(); - - const TagSet& tags = this->getTags(); - if (!tags.empty()) - { - msg_warning() << "Using tags to find edge2QuadMapping has been depreciate. Please use 'edge2QuadMapping' link to set the path to the correct topological mapping."; - } - //////////////////////////////////////////////////////// ////////// keyPoint list and Density Assignement /////// @@ -295,19 +285,7 @@ void WireRestShape::releaseWirePart() edgeMod->removeEdges(edge_remove,false); // remove the single edge and do not remove any point... msg_info() << "WireRestShape _topology name="<<_topology->getName()<<" - numEdges ="<<_topology->getNbEdges() ; - - // propagate the topological change to the topological mapping // - if(edge2QuadMap!=nullptr) - { - edge2QuadMap->updateTopologicalMappingTopDown(); - sofa::component::topology::container::dynamic::QuadSetTopologyModifier *quadMod; - edge2QuadMap->getContext()->get(quadMod); - quadMod->notifyEndingEvent(); - } - - - _topology->resetTopologyChangeList(); - + return; } } From 483e4e76ad7c4c85802405c12f5b052b645dc980 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 2 Oct 2022 01:35:37 +0200 Subject: [PATCH 06/60] [src] Move numEdges and numEdgesCollision into WireSectionMaterial --- .../component/engine/WireRestShape.h | 5 +- .../component/engine/WireRestShape.inl | 119 +++++++++++------- .../component/model/WireSectionMaterial.cpp | 15 +++ .../component/model/WireSectionMaterial.h | 8 ++ 4 files changed, 97 insertions(+), 50 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index c6e52fc77..baea5be52 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -89,7 +89,8 @@ class WireRestShape : public core::objectmodel::BaseObject /////////////////////////// Inherited from BaseObject ////////////////////////////////////////// void parse(core::objectmodel::BaseObjectDescription* arg) override; void init() override ; - + void initTopology(); + void draw(const core::visual::VisualParams * vparams) override ; @@ -143,8 +144,6 @@ class WireRestShape : public core::objectmodel::BaseObject Data d_spireHeight; Data > d_density; Data > d_keyPoints; - Data< int > d_numEdges; - Data > d_numEdgesCollis; /// broken in 2 case Data d_brokenIn2; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 24a73d2f0..b2c201a4b 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -68,8 +68,6 @@ WireRestShape::WireRestShape() : , d_spireHeight(initData(&d_spireHeight, (Real)0.01, "spireHeight", "height between each spire")) , d_density(initData(&d_density, "densityOfBeams", "density of beams between key points")) , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) - , d_numEdges(initData(&d_numEdges, 10, "numEdges","number of Edges for the visual model")) - , d_numEdgesCollis(initData(&d_numEdgesCollis,"numEdgesCollis", "number of Edges for the collision model" )) , d_brokenIn2(initData(&d_brokenIn2, (bool)false, "brokenIn2", "")) , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) , l_sectionMaterial1(initLink("main_material", "link to the fist Wire Section Material")) @@ -191,26 +189,7 @@ void WireRestShape::init() msg_warning() << "No EdgeSetTopologyModifier found in the same node as the topology container: " << _topology->getName() << ". This wire won't support topological changes."; } - - /// fill topology : - _topology->clear(); - _topology->cleanup(); - int nbrEdges = d_numEdges.getValue(); - if (nbrEdges <= 0) - { - msg_warning() << "Number of edges has been set to an invalid value: " << nbrEdges << ". Value should be a positive integer. Setting to default value: 10"; - nbrEdges = 10; - } - Real dx = this->d_length.getValue() / nbrEdges; - - /// add points - for ( int i=0; iaddPoint( i*dx, 0, 0); - - /// add segments - for (int i=0; iaddEdge(i,i+1); - + initTopology(); //////////////////////////////////////////////////////// ////////// keyPoint list and Density Assignement /////// @@ -247,20 +226,54 @@ void WireRestShape::init() } } - if(!d_numEdgesCollis.getValue().size()) - { - auto densityCol = sofa::helper::getWriteOnlyAccessor(d_numEdgesCollis); - densityCol.resize(keyPointList.size()-1); - for (unsigned int i=0; id_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } +template +void WireRestShape::initTopology() +{ + /// fill topology : + _topology->clear(); + _topology->cleanup(); + + const Real& fullLength = this->d_length.getValue(); + const Real& straightLength = this->d_straightLength.getValue(); + + // Add topology of the first material + WireSectionMaterial* mat1 = l_sectionMaterial1.get(); + int nbrEdges1 = mat1->getNbVisualEdges(); + Real dx1 = straightLength / nbrEdges1; + + /// add points from main material + for (int i = 0; i < nbrEdges1 + 1; i++) + _topology->addPoint(i * dx1, 0, 0); + + /// add segments from main material + for (int i = 0; i < nbrEdges1; i++) + _topology->addEdge(i, i + 1); + + + // Add topology of the second material + if (WireSectionMaterial* mat2 = l_sectionMaterial2.get()) + { + Real lengthExtremity = fullLength - straightLength; + int nbrEdges2 = mat2->getNbVisualEdges(); + Real dx2 = lengthExtremity / nbrEdges2; + + /// add points from main material + for (int i = 0; i < nbrEdges2 + 1; i++) + _topology->addPoint(straightLength + i * dx2, 0, 0); + + /// add segments from main material + for (int i = nbrEdges1 + 1; i < nbrEdges1 + nbrEdges2 + 2; i++) + _topology->addEdge(i, i + 1); + } +} + + template void WireRestShape::releaseWirePart() { @@ -335,25 +348,36 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv x_used=0.0; // verify that size of numEdgesCollis = size of keyPoints-1 - if( d_numEdgesCollis.getValue().size() != d_keyPoints.getValue().size()-1) + //if( d_numEdgesCollis.getValue().size() != d_keyPoints.getValue().size()-1) + //{ + // msg_error() << "Problem size of numEdgesCollis ()" << d_numEdgesCollis.getValue().size() + // << " != size of keyPoints-1 " << d_keyPoints.getValue().size()-1 ; + // numLines = (unsigned int)d_numEdgesCollis.getValue()[0]; + // dx=d_length.getValue()/numLines; + // return; + //} + + if (x_used < d_straightLength.getValue()) { - msg_error() << "Problem size of numEdgesCollis ()" << d_numEdgesCollis.getValue().size() << " != size of keyPoints-1 " << d_keyPoints.getValue().size()-1 ; - numLines = (unsigned int)d_numEdgesCollis.getValue()[0]; - dx=d_length.getValue()/numLines; - return; + numLines = l_sectionMaterial1.get()->getNbCollisionEdges(); + dx = d_straightLength.getValue() / numLines; } - - - for (unsigned int i=1; id_keyPoints.getValue().size(); i++) + else if (x_used < d_length.getValue()) { - if( x_used < this->d_keyPoints.getValue()[i] ) - { - numLines = (unsigned int)d_numEdgesCollis.getValue()[i-1]; - dx=(this->d_keyPoints.getValue()[i] - this->d_keyPoints.getValue()[i-1])/numLines; - return; - } + numLines = l_sectionMaterial2.get()->getNbCollisionEdges(); + dx = d_length.getValue() / numLines; } + //for (unsigned int i=1; id_keyPoints.getValue().size(); i++) + //{ + // if( x_used < this->d_keyPoints.getValue()[i] ) + // { + // numLines = (unsigned int)d_numEdgesCollis.getValue()[i - 1]; + // dx = (this->d_keyPoints.getValue()[i] - this->d_keyPoints.getValue()[i - 1]) / numLines; + // return; + // } + //} + dx=d_length.getValue()/20; msg_error() << " problem is getCollisionSampling : x_curv "<::Real WireRestShape::getLength() template void WireRestShape::getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) { - numLines = 0; - for (unsigned i=0; igetNbCollisionEdges(); + + if (auto mat2 = l_sectionMaterial2.get()) { - numLines += (unsigned int)d_numEdgesCollis.getValue()[i]; + numLines += mat2->getNbCollisionEdges(); } dx=d_length.getValue()/numLines; } diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp index 39c45f934..5ac5d67b6 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -40,6 +40,8 @@ WireSectionMaterial::WireSectionMaterial() , d_radius(initData(&d_radius, (SReal)1.0f, "radius", "radius")) , d_innerRadius(initData(&d_innerRadius, (SReal)0.0f, "innerRadius", "inner radius if it applies")) , d_massDensity(initData(&d_massDensity, (SReal)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) + , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) + , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) { } @@ -58,6 +60,19 @@ void WireSectionMaterial::init() this->beamSection._A = M_PI * (r * r - rInner * rInner); this->beamSection._Asy = 0.0; this->beamSection._Asz = 0.0; + + if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + { + msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + d_nbEdgesVisu.setValue(10); + } + + + if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + { + msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + d_nbEdgesVisu.setValue(10); + } } diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h index 46adb070d..d0e16f4cc 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -52,6 +52,11 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO /// This function gives the mass density and the BeamSection data depending on the beam position void getInterpolationParam(SReal& _rho, SReal& _A, SReal& _Iy, SReal& _Iz, SReal& _Asy, SReal& _Asz, SReal& _J); + [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } + + [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } + + /// User Data about the Young modulus Data d_poissonRatio; @@ -61,6 +66,9 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO Data d_radius; Data d_innerRadius; Data d_massDensity; + + Data< int > d_nbEdgesVisu; + Data< int > d_nbEdgesCollis; protected: BeamSection beamSection; }; From 5be2cfd617fa4178f0aa6c30b97c791eede8f165 Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 3 Oct 2022 15:53:37 +0200 Subject: [PATCH 07/60] [WireRestShape] Remove use of Edge2QuatTopologyMapping, no need to propagate topology change. It will be done automatically through topology changes pipeline --- src/BeamAdapter/component/engine/WireRestShape.h | 3 --- src/BeamAdapter/component/engine/WireRestShape.inl | 1 - 2 files changed, 4 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index baea5be52..9b9c35e86 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -173,9 +173,6 @@ class WireRestShape : public core::objectmodel::BaseObject SingleLink, MeshLoader, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_loader; /// Pointer to the MeshLoader, should be set using @sa l_loader, otherwise will search for one in current Node. MeshLoader* loader{ nullptr }; - - /// Link to a Edge2QuadTopologicalMapping, usually used for beam surface rendering to be set to propagate topological changes - SingleLink, Edge2QuadTopologicalMapping, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_edge2QuadMapping; }; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index b2c201a4b..28eec3ac9 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -74,7 +74,6 @@ WireRestShape::WireRestShape() : , l_sectionMaterial2(initLink("extremity_material", "link to the second Wire Section Material")) , l_topology(initLink("topology", "link to the topology container")) , l_loader(initLink("loader", "link to the MeshLoader")) - , l_edge2QuadMapping(initLink("edge2QuadMapping", "link to the edge2QuadMapping to render this beam")) { d_spireDiameter.setGroup("Procedural"); d_spireHeight.setGroup("Procedural"); From 7448b43ca02707e47ba7b164b541f41329c8ab80 Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 3 Oct 2022 15:56:17 +0200 Subject: [PATCH 08/60] Fix numEdges creation fron materials --- .../component/engine/WireRestShape.inl | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 28eec3ac9..66f5f7b7e 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -247,12 +247,16 @@ void WireRestShape::initTopology() Real dx1 = straightLength / nbrEdges1; /// add points from main material - for (int i = 0; i < nbrEdges1 + 1; i++) + for (int i = 0; i < nbrEdges1 + 1; i++) { _topology->addPoint(i * dx1, 0, 0); + //std::cout << "1. addPoint: " << i << " -> " << i * dx1 << std::endl; + } /// add segments from main material - for (int i = 0; i < nbrEdges1; i++) + for (int i = 0; i < nbrEdges1; i++) { _topology->addEdge(i, i + 1); + //std::cout << "1. addEdge: " << i << " - " << i + 1 << std::endl; + } // Add topology of the second material @@ -263,12 +267,16 @@ void WireRestShape::initTopology() Real dx2 = lengthExtremity / nbrEdges2; /// add points from main material - for (int i = 0; i < nbrEdges2 + 1; i++) + for (int i = 1; i < nbrEdges2 + 1; i++) { _topology->addPoint(straightLength + i * dx2, 0, 0); + //std::cout << "2. addPoint: " << i + nbrEdges1 << " -> " << straightLength + i * dx2 << std::endl; + } /// add segments from main material - for (int i = nbrEdges1 + 1; i < nbrEdges1 + nbrEdges2 + 2; i++) - _topology->addEdge(i, i + 1); + for (int i = nbrEdges1; i < nbrEdges1 + nbrEdges2; i++) { + _topology->addEdge(i, i + 1); + //std::cout << "2. addEdge: " << i << " - " << i + 1 << std::endl; + } } } @@ -356,16 +364,21 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv // return; //} - if (x_used < d_straightLength.getValue()) + if (x_used <= d_straightLength.getValue()) { numLines = l_sectionMaterial1.get()->getNbCollisionEdges(); dx = d_straightLength.getValue() / numLines; } - else if (x_used < d_length.getValue()) + else if (x_used <= d_length.getValue()) { numLines = l_sectionMaterial2.get()->getNbCollisionEdges(); dx = d_length.getValue() / numLines; } + else + { + dx = d_length.getValue() / 20; + msg_error() << " problem is getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); + } //for (unsigned int i=1; id_keyPoints.getValue().size(); i++) //{ @@ -377,8 +390,6 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv // } //} - dx=d_length.getValue()/20; - msg_error() << " problem is getCollisionSampling : x_curv "< Date: Tue, 4 Oct 2022 11:30:25 +0200 Subject: [PATCH 09/60] [src] Update WireRestShape to use a vector of Links instead of hardcoded material1 and material2 --- .../component/engine/WireRestShape.h | 16 +- .../component/engine/WireRestShape.inl | 237 +++++++++--------- 2 files changed, 127 insertions(+), 126 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 9b9c35e86..75246a4c8 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -89,7 +89,6 @@ class WireRestShape : public core::objectmodel::BaseObject /////////////////////////// Inherited from BaseObject ////////////////////////////////////////// void parse(core::objectmodel::BaseObjectDescription* arg) override; void init() override ; - void initTopology(); void draw(const core::visual::VisualParams * vparams) override ; @@ -133,6 +132,12 @@ class WireRestShape : public core::objectmodel::BaseObject void rotateFrameForAlignX(const Quat &input, Vec3 &x, Quat &output); +protected: + /// Internal method to init Lengths vector @sa d_keyPoints if not set using @sa d_length and @sa d_straightLength. Returns false if init can't be performed. + bool initLengths(); + /// Internal method to init Edge Topology @sa _topology using the list of materials @sa l_sectionMaterials. Returns false if init can't be performed. + bool initTopology(); + public: /// Analitical creation of wire shape... @@ -148,12 +153,9 @@ class WireRestShape : public core::objectmodel::BaseObject /// broken in 2 case Data d_brokenIn2; Data d_drawRestShape; - - /// Link to be set to the topology container in the component graph. - SingleLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterial1; - - /// Link to be set to the topology container in the component graph. - SingleLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterial2; + + /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. + MultiLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; private: /// Data required for the File loading diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 66f5f7b7e..fd8188a15 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -70,8 +70,7 @@ WireRestShape::WireRestShape() : , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) , d_brokenIn2(initData(&d_brokenIn2, (bool)false, "brokenIn2", "")) , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) - , l_sectionMaterial1(initLink("main_material", "link to the fist Wire Section Material")) - , l_sectionMaterial2(initLink("extremity_material", "link to the second Wire Section Material")) + , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) , l_topology(initLink("topology", "link to the topology container")) , l_loader(initLink("loader", "link to the MeshLoader")) { @@ -151,9 +150,20 @@ void WireRestShape::init() } } - if (!l_sectionMaterial1.get()) + if (l_sectionMaterials.empty()) + { + msg_error() << "No WireSectionMaterial set. At least one material should be set and link using wireMaterials."; + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + return; + } + + + //////////////////////////////////////////////////////// + ////////// keyPoint list and Density Assignement /////// + //////////////////////////////////////////////////////// + + if (!initLengths()) { - msg_error() << "No WireSectionMaterial set. At least one material should be set and link using main_material"; this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); return; } @@ -179,105 +189,101 @@ void WireRestShape::init() return; } - // Get pointer to the topology Modifier (for topological changes) _topology->getContext()->get(edgeMod); - if (edgeMod == nullptr) { msg_warning() << "No EdgeSetTopologyModifier found in the same node as the topology container: " << _topology->getName() << ". This wire won't support topological changes."; } - initTopology(); + initTopology(); - //////////////////////////////////////////////////////// - ////////// keyPoint list and Density Assignement /////// - //////////////////////////////////////////////////////// + + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); + msg_info() << "WireRestShape end init"; +} + + +template +bool WireRestShape::initLengths() +{ auto keyPointList = sofa::helper::getWriteOnlyAccessor(d_keyPoints); - if(!keyPointList.size()) + auto densityList = sofa::helper::getWriteOnlyAccessor(d_density); + + // In case use used length and straightLenght instead of keyPointList, create keyPointList + if (keyPointList.empty()) { keyPointList.push_back(0.0); - if(d_straightLength.getValue()>= 0.001*this->d_length.getValue() && d_straightLength.getValue() <= 0.999*d_length.getValue()) + if (d_straightLength.getValue() >= 0.001 * this->d_length.getValue() && d_straightLength.getValue() <= 0.999 * d_length.getValue()) keyPointList.push_back(d_straightLength.getValue()); keyPointList.push_back(d_length.getValue()); } - if( d_density.getValue().size() != keyPointList.size()-1) + // checking sizes between keypointList and number of input material + if (l_sectionMaterials.size() != keyPointList.size() - 1) { - auto densityList = sofa::helper::getWriteOnlyAccessor(d_density); + msg_error() << "Wrong number of inputs. Component can't be init. Number of input materials: " << l_sectionMaterials.size() << ", should be equal to keyPointList.size()-1. keyPointList.size() is equal to: " << keyPointList.size(); + return false; + } - if(densityList.size() > keyPointList.size()-1 ) - densityList.resize(keyPointList.size()-1); - else - { - densityList.clear(); + if (densityList.size() != keyPointList.size() - 1) + { + msg_warning() << "Wrong number of densityOfBeams. Given: " << densityList.size() << ", should be equal to keyPointList.size()-1: '" << keyPointList.size() + << "'. densityOfBeams will be recomputed using Wire material number of collision edges."; + densityList.clear(); - if(d_straightLength.getValue()>= 0.001*this->d_length.getValue() ) - { - int numNodes = (int) floor(5.0*d_straightLength.getValue() / d_length.getValue() ); - densityList.push_back(numNodes); - } - if( d_straightLength.getValue() <= 0.999*d_length.getValue()) - { - int numNodes = (int) floor(20.0*(1.0 - d_straightLength.getValue() / d_length.getValue()) ); - densityList.push_back(numNodes); - } + for (unsigned int i = 0; i < keyPointList.size() - 1; ++i) + { + auto mat = l_sectionMaterials.get(i); + int nbrCollEdges = mat->getNbCollisionEdges(); + densityList.push_back(nbrCollEdges); } } - msg_info() <<"WireRestShape end init" ; - - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); + return true; } template -void WireRestShape::initTopology() +bool WireRestShape::initTopology() { /// fill topology : _topology->clear(); _topology->cleanup(); - const Real& fullLength = this->d_length.getValue(); - const Real& straightLength = this->d_straightLength.getValue(); - - // Add topology of the first material - WireSectionMaterial* mat1 = l_sectionMaterial1.get(); - int nbrEdges1 = mat1->getNbVisualEdges(); - Real dx1 = straightLength / nbrEdges1; - - /// add points from main material - for (int i = 0; i < nbrEdges1 + 1; i++) { - _topology->addPoint(i * dx1, 0, 0); - //std::cout << "1. addPoint: " << i << " -> " << i * dx1 << std::endl; - } - - /// add segments from main material - for (int i = 0; i < nbrEdges1; i++) { - _topology->addEdge(i, i + 1); - //std::cout << "1. addEdge: " << i << " - " << i + 1 << std::endl; - } - - - // Add topology of the second material - if (WireSectionMaterial* mat2 = l_sectionMaterial2.get()) + const type::vector& keyPts = d_keyPoints.getValue(); + if (l_sectionMaterials.size() != keyPts.size() - 1) { - Real lengthExtremity = fullLength - straightLength; - int nbrEdges2 = mat2->getNbVisualEdges(); - Real dx2 = lengthExtremity / nbrEdges2; - - /// add points from main material - for (int i = 1; i < nbrEdges2 + 1; i++) { - _topology->addPoint(straightLength + i * dx2, 0, 0); - //std::cout << "2. addPoint: " << i + nbrEdges1 << " -> " << straightLength + i * dx2 << std::endl; + msg_error() << "Wrong number of inputs. Component can't be init. Number of input materials: " << l_sectionMaterials.size() << ", should be equal to keyPointList.size()-1. keyPointList.size() is equal to: " << keyPts.size(); + return false; + } + + Real prev_length = 0.0; + int prev_edges = 0; + int startPtId = 0; + for (auto i = 0; i < l_sectionMaterials.size(); ++i) + { + // Add topology of the material + int nbrVisuEdges = l_sectionMaterials.get(i)->getNbVisualEdges(); + Real length = fabs(keyPts[i + 1] - keyPts[i]); + Real dx = length / nbrVisuEdges; + + // add points from the material + for (int i = startPtId; i < nbrVisuEdges + 1; i++) { + _topology->addPoint(prev_length + i * dx, 0, 0); } - /// add segments from main material - for (int i = nbrEdges1; i < nbrEdges1 + nbrEdges2; i++) { + // add segments from the material + for (int i = prev_edges; i < prev_edges + nbrVisuEdges; i++) { _topology->addEdge(i, i + 1); - //std::cout << "2. addEdge: " << i << " - " << i + 1 << std::endl; } + + prev_length = length; + prev_edges = nbrVisuEdges; + startPtId = 1; // Assume the last point of mat[n] == first point of mat[n+1] } + + return true; } @@ -354,42 +360,34 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv if(x_used<0.0) x_used=0.0; - // verify that size of numEdgesCollis = size of keyPoints-1 - //if( d_numEdgesCollis.getValue().size() != d_keyPoints.getValue().size()-1) - //{ - // msg_error() << "Problem size of numEdgesCollis ()" << d_numEdgesCollis.getValue().size() - // << " != size of keyPoints-1 " << d_keyPoints.getValue().size()-1 ; - // numLines = (unsigned int)d_numEdgesCollis.getValue()[0]; - // dx=d_length.getValue()/numLines; - // return; - //} - - if (x_used <= d_straightLength.getValue()) - { - numLines = l_sectionMaterial1.get()->getNbCollisionEdges(); - dx = d_straightLength.getValue() / numLines; - } - else if (x_used <= d_length.getValue()) + const type::vector& keyPts = d_keyPoints.getValue(); + + // verify that size of number of materials == size of keyPoints-1 + if (l_sectionMaterials.size() != keyPts.size() - 1) { - numLines = l_sectionMaterial2.get()->getNbCollisionEdges(); + msg_error() << "Problem size of number of materials: " << l_sectionMaterials.size() + << " != size of keyPoints-1 " << keyPts.size()-1 + << ". Returning default values."; + numLines = 20; dx = d_length.getValue() / numLines; + return; } - else + + // Check in which section x_used belongs to and get access to this section material + for (auto i = 1; i< keyPts.size(); ++i) { - dx = d_length.getValue() / 20; - msg_error() << " problem is getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); + if (x_used <= keyPts[i]) + { + numLines = l_sectionMaterials.get(i-1)->getNbCollisionEdges(); + dx = d_straightLength.getValue() / numLines; + return; + } } - //for (unsigned int i=1; id_keyPoints.getValue().size(); i++) - //{ - // if( x_used < this->d_keyPoints.getValue()[i] ) - // { - // numLines = (unsigned int)d_numEdgesCollis.getValue()[i - 1]; - // dx = (this->d_keyPoints.getValue()[i] - this->d_keyPoints.getValue()[i - 1]) / numLines; - // return; - // } - //} - + // If x_used is out of bounds. Warn user and returns default value. + numLines = 20; + dx = d_length.getValue() / numLines; + msg_error() << " problem is getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); } @@ -457,35 +455,37 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co template void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) { - //Depending on the position of the beam, determine the Young modulus - if (x_curv > this->d_straightLength.getValue() && l_sectionMaterial2.get()) // extremity of the wire - return l_sectionMaterial2.get()->getYoungModulusAtX(youngModulus, cPoisson); - else - return l_sectionMaterial1.get()->getYoungModulusAtX(youngModulus, cPoisson); + const type::vector& keyPts = d_keyPoints.getValue(); + // Depending on the position of the beam, determine the corresponding section material and returning its Young modulus + for (auto i = 1; i < keyPts.size(); ++i) + { + if (x_curv <= keyPts[i]) + { + return l_sectionMaterials.get(i - 1)->getYoungModulusAtX(youngModulus, cPoisson); + } + } + + msg_error() << " problem in getYoungModulusAtX : x_curv " << x_curv << " is not between keyPoints" << keyPts; } template void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) { - if(x_curv <= this->d_straightLength.getValue()) + const type::vector& keyPts = d_keyPoints.getValue(); + // Check in which section x_used belongs to and get access to this section material + for (auto i = 1; i < keyPts.size(); ++i) { - return l_sectionMaterial1.get()->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); - } - else - { - auto mat = l_sectionMaterial2.get(); - if (mat) + if (x_curv <= keyPts[i]) { - return mat->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); - } - else - { - return l_sectionMaterial1.get()->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); + return l_sectionMaterials.get(i - 1)->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); } } + + msg_error() << " problem in getInterpolationParam : x_curv " << x_curv << " is not between keyPoints" << keyPts; } + template bool WireRestShape::checkTopology() { @@ -707,13 +707,12 @@ typename WireRestShape::Real WireRestShape::getLength() template void WireRestShape::getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) { - numLines = l_sectionMaterial1.get()->getNbCollisionEdges(); - - if (auto mat2 = l_sectionMaterial2.get()) + numLines = 0; + for (auto i = 0; i < l_sectionMaterials.size(); ++i) { - numLines += mat2->getNbCollisionEdges(); + numLines += l_sectionMaterials.get(i)->getNbCollisionEdges(); } - dx=d_length.getValue()/numLines; + dx = d_length.getValue() / numLines; } template From c442d02b7614a95bc6d3060e76611cc62ffcc208 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 4 Oct 2022 15:24:37 +0200 Subject: [PATCH 10/60] backup changes in scenes --- examples/SingleBeamDeployment.scn | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/SingleBeamDeployment.scn b/examples/SingleBeamDeployment.scn index ca9739617..87e118747 100644 --- a/examples/SingleBeamDeployment.scn +++ b/examples/SingleBeamDeployment.scn @@ -15,11 +15,12 @@ - + + + From 52e0213d5815204dcaa8d19041b6da85a3c800cd Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 4 Oct 2022 15:53:57 +0200 Subject: [PATCH 11/60] Add float/double methods. --- .../component/model/WireSectionMaterial.cpp | 34 ++++++++++++++++--- .../component/model/WireSectionMaterial.h | 6 ++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp index 5ac5d67b6..2bc5cde0a 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -77,15 +77,40 @@ void WireSectionMaterial::init() /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position -void WireSectionMaterial::getYoungModulusAtX(SReal& youngModulus, SReal& cPoisson) +void WireSectionMaterial::getYoungModulusAtX(float& youngModulus, float& cPoisson) { - youngModulus = this->d_youngModulus.getValue(); - cPoisson = this->d_poissonRatio.getValue(); + youngModulus = float(this->d_youngModulus.getValue()); + cPoisson = float(this->d_poissonRatio.getValue()); +} + + +/// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position +void WireSectionMaterial::getYoungModulusAtX(double& youngModulus, double& cPoisson) +{ + youngModulus = double(this->d_youngModulus.getValue()); + cPoisson = double(this->d_poissonRatio.getValue()); } /// This function gives the mass density and the BeamSection data depending on the beam position -void WireSectionMaterial::getInterpolationParam(SReal& _rho, SReal& _A, SReal& _Iy, SReal& _Iz, SReal& _Asy, SReal& _Asz, SReal& _J) +void WireSectionMaterial::getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) +{ + if (d_massDensity.isSet()) + _rho = float(d_massDensity.getValue()); + + if (d_radius.isSet()) + { + _A = float(beamSection._A); + _Iy = float(beamSection._Iy); + _Iz = float(beamSection._Iz); + _Asy = float(beamSection._Asy); + _Asz = float(beamSection._Asz); + _J = float(beamSection._J); + } +} + + +void WireSectionMaterial::getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) { if (d_massDensity.isSet()) _rho = d_massDensity.getValue(); @@ -102,4 +127,5 @@ void WireSectionMaterial::getInterpolationParam(SReal& _rho, SReal& _A, SReal& _ } + }// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h index d0e16f4cc..2e3d2ffa8 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -47,10 +47,12 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO void init(); /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position - void getYoungModulusAtX(SReal& youngModulus, SReal& cPoisson); + void getYoungModulusAtX(float& youngModulus, float& cPoisson); + void getYoungModulusAtX(double& youngModulus, double& cPoisson); /// This function gives the mass density and the BeamSection data depending on the beam position - void getInterpolationParam(SReal& _rho, SReal& _A, SReal& _Iy, SReal& _Iz, SReal& _Asy, SReal& _Asz, SReal& _J); + void getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J); + void getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J); [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } From 75c0343efeb1158a71c82adbc06c6d4c321ce9c2 Mon Sep 17 00:00:00 2001 From: erik pernod Date: Thu, 13 Oct 2022 11:12:03 +0200 Subject: [PATCH 12/60] Update src/BeamAdapter/component/model/WireSectionMaterial.cpp Co-authored-by: Frederick Roy --- src/BeamAdapter/component/model/WireSectionMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp index 2bc5cde0a..c76a7d2a4 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -71,7 +71,7 @@ void WireSectionMaterial::init() if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) { msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; - d_nbEdgesVisu.setValue(10); + d_nbEdgesCollis.setValue(10); } } From 7bf0249f2560afb37a910ab16e5f011f1a6bc02c Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 6 Oct 2022 00:25:07 +0200 Subject: [PATCH 13/60] [WireRestShape] Fix Collision edges sampling --- src/BeamAdapter/component/engine/WireRestShape.inl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index ca037ce63..9e271f61e 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -377,7 +377,9 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv if (x_used <= keyPts[i]) { numLines = l_sectionMaterials.get(i-1)->getNbCollisionEdges(); - dx = d_straightLength.getValue() / numLines; + + Real length = fabs(keyPts[i] - keyPts[i-1]); + dx = length / numLines; return; } } From 17ef028f8bd02230aa058e7ed49b6b780bec19dd Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 11 Oct 2022 14:05:48 +0200 Subject: [PATCH 14/60] [WRShape] Add epsilon on get youngModulus and interpolation --- src/BeamAdapter/component/engine/WireRestShape.inl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 9e271f61e..c4793c3bd 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -40,7 +40,7 @@ #include #include -#define EPSILON 0.0000000001 +#define EPSILON 0.0001 #define VERIF 1 namespace sofa::component::engine @@ -455,11 +455,13 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co template void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) { + const Real x_used = x_curv - Real(EPSILON); const type::vector& keyPts = d_keyPoints.getValue(); + // Depending on the position of the beam, determine the corresponding section material and returning its Young modulus for (auto i = 1; i < keyPts.size(); ++i) { - if (x_curv <= keyPts[i]) + if (x_used <= keyPts[i]) { return l_sectionMaterials.get(i - 1)->getYoungModulusAtX(youngModulus, cPoisson); } @@ -472,11 +474,13 @@ void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youn template void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) { + const Real x_used = x_curv - Real(EPSILON); const type::vector& keyPts = d_keyPoints.getValue(); + // Check in which section x_used belongs to and get access to this section material for (auto i = 1; i < keyPts.size(); ++i) { - if (x_curv <= keyPts[i]) + if (x_used <= keyPts[i]) { return l_sectionMaterials.get(i - 1)->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); } From 7c4ec9f1e1f31621ae9242f9298ab162cb5806ad Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 11 Oct 2022 14:43:08 +0200 Subject: [PATCH 15/60] Turn severals methods into const --- src/BeamAdapter/component/engine/WireRestShape.h | 4 ++-- src/BeamAdapter/component/engine/WireRestShape.inl | 4 ++-- .../component/model/WireSectionMaterial.cpp | 8 ++++---- src/BeamAdapter/component/model/WireSectionMaterial.h | 11 ++++++----- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 75246a4c8..e612de0a8 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -102,10 +102,10 @@ class WireRestShape : public core::objectmodel::BaseObject void getRestTransformOnX(Transform &global_H_local, const Real &x); /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position - void getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson); + void getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) const; /// This function gives the mass density and the BeamSection data depending on the beam position - void getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J); + void getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) const; /** * This function provides a type::vector with the curviliar abscissa of the noticeable point(s) diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index c4793c3bd..88bf928d7 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -453,7 +453,7 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co template -void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) +void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youngModulus, Real& cPoisson) const { const Real x_used = x_curv - Real(EPSILON); const type::vector& keyPts = d_keyPoints.getValue(); @@ -472,7 +472,7 @@ void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youn template -void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) +void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) const { const Real x_used = x_curv - Real(EPSILON); const type::vector& keyPts = d_keyPoints.getValue(); diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp index c76a7d2a4..a86252ce2 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -77,7 +77,7 @@ void WireSectionMaterial::init() /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position -void WireSectionMaterial::getYoungModulusAtX(float& youngModulus, float& cPoisson) +void WireSectionMaterial::getYoungModulusAtX(float& youngModulus, float& cPoisson) const { youngModulus = float(this->d_youngModulus.getValue()); cPoisson = float(this->d_poissonRatio.getValue()); @@ -85,7 +85,7 @@ void WireSectionMaterial::getYoungModulusAtX(float& youngModulus, float& cPoisso /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position -void WireSectionMaterial::getYoungModulusAtX(double& youngModulus, double& cPoisson) +void WireSectionMaterial::getYoungModulusAtX(double& youngModulus, double& cPoisson) const { youngModulus = double(this->d_youngModulus.getValue()); cPoisson = double(this->d_poissonRatio.getValue()); @@ -93,7 +93,7 @@ void WireSectionMaterial::getYoungModulusAtX(double& youngModulus, double& cPois /// This function gives the mass density and the BeamSection data depending on the beam position -void WireSectionMaterial::getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) +void WireSectionMaterial::getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) const { if (d_massDensity.isSet()) _rho = float(d_massDensity.getValue()); @@ -110,7 +110,7 @@ void WireSectionMaterial::getInterpolationParam(float& _rho, float& _A, float& _ } -void WireSectionMaterial::getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) +void WireSectionMaterial::getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) const { if (d_massDensity.isSet()) _rho = d_massDensity.getValue(); diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h index 2e3d2ffa8..98050c03c 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -47,12 +47,12 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO void init(); /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position - void getYoungModulusAtX(float& youngModulus, float& cPoisson); - void getYoungModulusAtX(double& youngModulus, double& cPoisson); + void getYoungModulusAtX(float& youngModulus, float& cPoisson) const; + void getYoungModulusAtX(double& youngModulus, double& cPoisson) const; /// This function gives the mass density and the BeamSection data depending on the beam position - void getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J); - void getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J); + void getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) const; + void getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) const; [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } @@ -71,7 +71,8 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO Data< int > d_nbEdgesVisu; Data< int > d_nbEdgesCollis; -protected: + +private: BeamSection beamSection; }; From 7a55ef4f07ed4b8173c77d679b8280a74c842633 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 22:01:12 +0200 Subject: [PATCH 16/60] [WireSection] Update WireSectionMaterial to be templated --- CMakeLists.txt | 13 ++- .../component/engine/WireRestShape.h | 2 +- .../component/model/WireSectionMaterial.cpp | 104 +----------------- .../component/model/WireSectionMaterial.h | 30 +++-- .../component/model/WireSectionMaterial.inl | 99 +++++++++++++++++ .../gpu/cuda/CudaInstantiations.cpp | 16 +++ 6 files changed, 147 insertions(+), 117 deletions(-) create mode 100644 src/BeamAdapter/component/model/WireSectionMaterial.inl diff --git a/CMakeLists.txt b/CMakeLists.txt index f99685742..41747175d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,13 +57,14 @@ set(HEADER_FILES ${BEAMADAPTER_SRC}/component/mapping/BeamLengthMapping.inl ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.h ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.inl - - ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.h - + + ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.h + ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.inl + ${BEAMADAPTER_SRC}/utils/BeamSection.h ${BEAMADAPTER_SRC}/utils/BeamActions.h ${BEAMADAPTER_SRC}/utils/deprecatedcomponent.h - ) +) set(SOURCE_FILES ${BEAMADAPTER_SRC}/initBeamAdapter.cpp @@ -89,8 +90,8 @@ set(SOURCE_FILES ${BEAMADAPTER_SRC}/component/mapping/BeamLengthMapping.cpp ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.cpp - ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.cpp - ) + ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.cpp +) if(SofaImplicitField_FOUND) set(HEADER_FILES ${HEADER_FILES} diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 6db51b6eb..9818e3c64 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -156,7 +156,7 @@ class WireRestShape : public core::objectmodel::BaseObject Data d_drawRestShape; /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. - MultiLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; + MultiLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; private: /// Data required for the File loading diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/WireSectionMaterial.cpp index a86252ce2..1de24395d 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/WireSectionMaterial.cpp @@ -19,113 +19,21 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_PLUGIN_BEAMADAPTER_WIRERESTSHAPE_CPP +#define SOFA_PLUGIN_BEAMADAPTER_WIRESECTIONMATERIAL_CPP -#include +#include #include #include +#include namespace sofa::beamadapter { using namespace sofa::defaulttype; -int WireSectionMaterialClass = core::RegisterObject("Wire Section Material.") -.add< WireSectionMaterial >(); - - -WireSectionMaterial::WireSectionMaterial() - : d_poissonRatio(initData(&d_poissonRatio, (SReal)0.49, "poissonRatio", "Poisson Ratio")) - , d_youngModulus(initData(&d_youngModulus, (SReal)5000, "youngModulus", "Young Modulus")) - , d_radius(initData(&d_radius, (SReal)1.0f, "radius", "radius")) - , d_innerRadius(initData(&d_innerRadius, (SReal)0.0f, "innerRadius", "inner radius if it applies")) - , d_massDensity(initData(&d_massDensity, (SReal)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) - , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) - , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) -{ - -} - - -void WireSectionMaterial::init() -{ - // Prepare beam sections - double r = this->d_radius.getValue(); - double rInner = this->d_innerRadius.getValue(); - this->beamSection._r = r; - this->beamSection._rInner = rInner; - this->beamSection._Iz = M_PI * (r * r * r * r - rInner * rInner * rInner * rInner) / 4.0; - this->beamSection._Iy = this->beamSection._Iz; - this->beamSection._J = this->beamSection._Iz + this->beamSection._Iy; - this->beamSection._A = M_PI * (r * r - rInner * rInner); - this->beamSection._Asy = 0.0; - this->beamSection._Asz = 0.0; - - if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) - { - msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; - d_nbEdgesVisu.setValue(10); - } - - - if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) - { - msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; - d_nbEdgesCollis.setValue(10); - } -} - - -/// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position -void WireSectionMaterial::getYoungModulusAtX(float& youngModulus, float& cPoisson) const -{ - youngModulus = float(this->d_youngModulus.getValue()); - cPoisson = float(this->d_poissonRatio.getValue()); -} - - -/// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position -void WireSectionMaterial::getYoungModulusAtX(double& youngModulus, double& cPoisson) const -{ - youngModulus = double(this->d_youngModulus.getValue()); - cPoisson = double(this->d_poissonRatio.getValue()); -} - - -/// This function gives the mass density and the BeamSection data depending on the beam position -void WireSectionMaterial::getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) const -{ - if (d_massDensity.isSet()) - _rho = float(d_massDensity.getValue()); - - if (d_radius.isSet()) - { - _A = float(beamSection._A); - _Iy = float(beamSection._Iy); - _Iz = float(beamSection._Iz); - _Asy = float(beamSection._Asy); - _Asz = float(beamSection._Asz); - _J = float(beamSection._J); - } -} - - -void WireSectionMaterial::getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) const -{ - if (d_massDensity.isSet()) - _rho = d_massDensity.getValue(); - - if (d_radius.isSet()) - { - _A = beamSection._A; - _Iy = beamSection._Iy; - _Iz = beamSection._Iz; - _Asy = beamSection._Asy; - _Asz = beamSection._Asz; - _J = beamSection._J; - } -} - +const int WireSectionMaterialClass = core::RegisterObject("Wire Section Material.") +.add< WireSectionMaterial >(true); +template class SOFA_BEAMADAPTER_API WireSectionMaterial; }// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h index 98050c03c..4b37cd52d 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace sofa::beamadapter @@ -35,24 +36,25 @@ namespace sofa::beamadapter * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. */ -class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseObject +template +class WireSectionMaterial : public core::objectmodel::BaseObject { public: SOFA_CLASS(WireSectionMaterial, core::objectmodel::BaseObject); + using Coord = typename DataTypes::Coord; + using Real = typename Coord::value_type; + /// Default Constructor WireSectionMaterial(); - - void init(); + void init() override; /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position - void getYoungModulusAtX(float& youngModulus, float& cPoisson) const; - void getYoungModulusAtX(double& youngModulus, double& cPoisson) const; + void getYoungModulusAtX(Real& youngModulus, Real& cPoisson) const; /// This function gives the mass density and the BeamSection data depending on the beam position - void getInterpolationParam(float& _rho, float& _A, float& _Iy, float& _Iz, float& _Asy, float& _Asz, float& _J) const; - void getInterpolationParam(double& _rho, double& _A, double& _Iy, double& _Iz, double& _Asy, double& _Asz, double& _J) const; + void getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const; [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } @@ -61,13 +63,13 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO /// User Data about the Young modulus - Data d_poissonRatio; - Data d_youngModulus; + Data d_poissonRatio; + Data d_youngModulus; /// Radius - Data d_radius; - Data d_innerRadius; - Data d_massDensity; + Data d_radius; + Data d_innerRadius; + Data d_massDensity; Data< int > d_nbEdgesVisu; Data< int > d_nbEdgesCollis; @@ -76,4 +78,8 @@ class SOFA_BEAMADAPTER_API WireSectionMaterial : public core::objectmodel::BaseO BeamSection beamSection; }; +#if !defined(SOFA_PLUGIN_BEAMADAPTER_WIRESECTIONMATERIAL_CPP) +extern template class SOFA_BEAMADAPTER_API WireSectionMaterial; +#endif + } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.inl b/src/BeamAdapter/component/model/WireSectionMaterial.inl new file mode 100644 index 000000000..6bbf4dd2e --- /dev/null +++ b/src/BeamAdapter/component/model/WireSectionMaterial.inl @@ -0,0 +1,99 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::beamadapter +{ + +template +WireSectionMaterial::WireSectionMaterial() + : d_poissonRatio(initData(&d_poissonRatio, (Real)0.49, "poissonRatio", "Poisson Ratio")) + , d_youngModulus(initData(&d_youngModulus, (Real)5000, "youngModulus", "Young Modulus")) + , d_radius(initData(&d_radius, (Real)1.0, "radius", "radius")) + , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) + , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) + , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) + , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) +{ + +} + + +template +void WireSectionMaterial::init() +{ + // Prepare beam sections + double r = this->d_radius.getValue(); + double rInner = this->d_innerRadius.getValue(); + this->beamSection._r = r; + this->beamSection._rInner = rInner; + this->beamSection._Iz = M_PI * (r * r * r * r - rInner * rInner * rInner * rInner) / 4.0; + this->beamSection._Iy = this->beamSection._Iz; + this->beamSection._J = this->beamSection._Iz + this->beamSection._Iy; + this->beamSection._A = M_PI * (r * r - rInner * rInner); + this->beamSection._Asy = 0.0; + this->beamSection._Asz = 0.0; + + if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + { + msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + d_nbEdgesVisu.setValue(10); + } + + + if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + { + msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + d_nbEdgesCollis.setValue(10); + } +} + + +template +void WireSectionMaterial::getYoungModulusAtX(Real& youngModulus, Real& cPoisson) const +{ + youngModulus = this->d_youngModulus.getValue(); + cPoisson = this->d_poissonRatio.getValue(); +} + + +template +void WireSectionMaterial::getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const +{ + if (d_massDensity.isSet()) + _rho = d_massDensity.getValue(); + + if (d_radius.isSet()) + { + _A = beamSection._A; + _Iy = beamSection._Iy; + _Iz = beamSection._Iz; + _Asy = beamSection._Asy; + _Asz = beamSection._Asz; + _J = beamSection._J; + } +} + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp index 5441f7f7d..0cf19c52e 100644 --- a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp +++ b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -86,6 +87,14 @@ namespace sofa::component::mapping #endif } // namespace sofa::component::mapping +namespace sofa::beamadapter +{ + template class SOFA_BEAMADAPTER_API WireSectionMaterial; +#ifdef SOFA_GPU_CUDA_DOUBLE + template class SOFA_BEAMADAPTER_API WireSectionMaterial; +#endif +} // namespace sofa::beamadapter + namespace sofa::gpu::cuda { @@ -139,6 +148,13 @@ int CudaMultiAdaptiveBeamMappingClass = core::RegisterObject("Set the positions #endif ; +int CudaWireSectionMaterialClass = core::RegisterObject("Wire Section Material using CUDA.") +.add< sofa::beamadapter::WireSectionMaterial >() +#ifdef SOFA_GPU_CUDA_DOUBLE +.add< sofa::beamadapter::WireSectionMaterialg >() +#endif +; + } // namespace sofa::gpu::cuda From c9617f99bd7e15042ddd6d7636160a62e1e23003 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 22:02:06 +0200 Subject: [PATCH 17/60] Temporarly comment code related to loading mesh not anymore working to fix compilation --- .../component/engine/WireRestShape.cpp | 2 +- .../component/engine/WireRestShape.h | 2 +- .../component/engine/WireRestShape.inl | 108 +++++++++--------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.cpp b/src/BeamAdapter/component/engine/WireRestShape.cpp index dacba394e..34572378a 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.cpp +++ b/src/BeamAdapter/component/engine/WireRestShape.cpp @@ -52,7 +52,7 @@ using namespace sofa::defaulttype; /// //////////////////////////////////////////////////////////////////////////////////////////////////// -static int WireRestShapeClass = core::RegisterObject("Describe the shape functions on multiple segments using curvilinear abscissa") +const int WireRestShapeClass = core::RegisterObject("Describe the shape functions on multiple segments using curvilinear abscissa") .add< WireRestShape >(true) ; diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 9818e3c64..b937f614a 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -121,7 +121,7 @@ class WireRestShape : public core::objectmodel::BaseObject void initFromLoader(); bool checkTopology(); - [[nodiscard]] bool fillTopology(); + //[[nodiscard]] bool fillTopology(); Real getLength() ; void getCollisionSampling(Real &dx, const Real &x_curv) ; void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) ; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index f1652c557..d179874d2 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -189,15 +189,15 @@ void WireRestShape::init() return; } - else - { - if (!fillTopology()) - { - msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } - } + //else + //{ + // if (!fillTopology()) + // { + // msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; + // this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + // return; + // } + //} // Get pointer to the topology Modifier (for topological changes) _topology->getContext()->get(edgeMod); if (edgeMod == nullptr) @@ -537,45 +537,45 @@ bool WireRestShape::checkTopology() } -template -bool WireRestShape::fillTopology() -{ - if (!_topology) - { - msg_error() << "Topology is null"; - return false; - } - - const auto length = this->d_length.getValue(); - if (length <= Real(0.0)) - { - msg_error() << "Length is 0 (or negative), check if d_length has been given or computed."; - return false; - } - - int nbrEdges = d_numEdges.getValue(); - if (nbrEdges <= 0) - { - msg_warning() << "Number of edges has been set to an invalid value: " << nbrEdges << ". Value should be a positive integer. Setting to default value: 10"; - nbrEdges = 10; - } - - /// fill topology : - _topology->clear(); - _topology->cleanup(); - - Real dx = this->d_length.getValue() / nbrEdges; - - /// add points - for (int i = 0; i < d_numEdges.getValue() + 1; i++) - _topology->addPoint(i * dx, 0, 0); - - /// add segments - for (int i = 0; i < d_numEdges.getValue(); i++) - _topology->addEdge(i, i + 1); - - return true; -} +//template +//bool WireRestShape::fillTopology() +//{ +// if (!_topology) +// { +// msg_error() << "Topology is null"; +// return false; +// } +// +// const auto length = this->d_length.getValue(); +// if (length <= Real(0.0)) +// { +// msg_error() << "Length is 0 (or negative), check if d_length has been given or computed."; +// return false; +// } +// +// int nbrEdges = d_numEdges.getValue(); +// if (nbrEdges <= 0) +// { +// msg_warning() << "Number of edges has been set to an invalid value: " << nbrEdges << ". Value should be a positive integer. Setting to default value: 10"; +// nbrEdges = 10; +// } +// +// /// fill topology : +// _topology->clear(); +// _topology->cleanup(); +// +// Real dx = this->d_length.getValue() / nbrEdges; +// +// /// add points +// for (int i = 0; i < d_numEdges.getValue() + 1; i++) +// _topology->addPoint(i * dx, 0, 0); +// +// /// add segments +// for (int i = 0; i < d_numEdges.getValue(); i++) +// _topology->addEdge(i, i + 1); +// +// return true; +//} @@ -718,12 +718,12 @@ void WireRestShape::initRestConfig() msg_info() <<"Length of the loaded shape = "<< m_absOfGeometry << ", total length with straight length = " << newLength ; - if (!fillTopology()) - { - msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } + //if (!fillTopology()) + //{ + // msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; + // this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + // return; + //} } From 9d81cf30ead07bd1e9dfdaa5c74955dc349d6333 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 23:36:34 +0200 Subject: [PATCH 18/60] Remove use of Edge2QuadTopologicalMapping --- src/BeamAdapter/component/engine/WireRestShape.h | 2 -- src/BeamAdapter/component/engine/WireRestShape.inl | 1 - 2 files changed, 3 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index b937f614a..5392922fc 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -39,7 +39,6 @@ #include #include #include -#include #include namespace sofa::component::engine @@ -50,7 +49,6 @@ namespace _wirerestshape_ using sofa::core::topology::TopologyContainer; using sofa::component::topology::container::dynamic::EdgeSetTopologyModifier; -using sofa::component::topology::mapping::Edge2QuadTopologicalMapping; using sofa::core::loader::MeshLoader; using namespace sofa::beamadapter; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index d179874d2..e11ec3800 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -35,7 +35,6 @@ #include #include -#include #include #include From dcc9816e963b54eae550f24b42da305239cf0e95 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 23:36:57 +0200 Subject: [PATCH 19/60] Fix compilation --- src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp index 0cf19c52e..f9a3fcea2 100644 --- a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp +++ b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp @@ -149,11 +149,11 @@ int CudaMultiAdaptiveBeamMappingClass = core::RegisterObject("Set the positions ; int CudaWireSectionMaterialClass = core::RegisterObject("Wire Section Material using CUDA.") -.add< sofa::beamadapter::WireSectionMaterial >() + .add< sofa::beamadapter::WireSectionMaterial >() #ifdef SOFA_GPU_CUDA_DOUBLE -.add< sofa::beamadapter::WireSectionMaterialg >() + .add< sofa::beamadapter::WireSectionMaterial >() #endif -; + ; } // namespace sofa::gpu::cuda From d982a78b06a8ada8fdaf55374b5343a2f72f9c0e Mon Sep 17 00:00:00 2001 From: epernod Date: Wed, 28 Jun 2023 09:04:31 +0200 Subject: [PATCH 20/60] backup work on moving loader to material --- .../component/engine/WireRestShape.h | 7 +- .../component/model/WireSectionMaterial.h | 16 ++- .../component/model/WireSectionMaterial.inl | 133 +++++++++++++++++- 3 files changed, 142 insertions(+), 14 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 5392922fc..ae62817d0 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -161,7 +161,7 @@ class WireRestShape : public core::objectmodel::BaseObject type::vector m_localRestPositions; type::vector m_localRestTransforms; type::vector m_curvAbs ; - double m_absOfGeometry {0}; + double m_absOfGeometry {0}; /// Link to be set to the topology container in the component graph. SingleLink, TopologyContainer, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; @@ -169,11 +169,6 @@ class WireRestShape : public core::objectmodel::BaseObject TopologyContainer* _topology{ nullptr }; /// Pointer to the topology modifier. Will be set at init by searching one in @sa _topology context. EdgeSetTopologyModifier* edgeMod{ nullptr }; - - /// Link to be set to the topology container in the component graph. - SingleLink, MeshLoader, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_loader; - /// Pointer to the MeshLoader, should be set using @sa l_loader, otherwise will search for one in current Node. - MeshLoader* loader{ nullptr }; }; diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/WireSectionMaterial.h index 4b37cd52d..a63abfc69 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/WireSectionMaterial.h @@ -25,10 +25,13 @@ #include #include #include +#include namespace sofa::beamadapter { +using sofa::core::loader::MeshLoader; + /** * \class WireRestShape * \brief Describe the shape functions on multiple segments @@ -60,8 +63,10 @@ class WireSectionMaterial : public core::objectmodel::BaseObject [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } +protected: + void initFromLoader(); - +public: /// User Data about the Young modulus Data d_poissonRatio; Data d_youngModulus; @@ -71,11 +76,20 @@ class WireSectionMaterial : public core::objectmodel::BaseObject Data d_innerRadius; Data d_massDensity; + Data d_length; + Data d_density; + Data< int > d_nbEdgesVisu; Data< int > d_nbEdgesCollis; + /// Link to be set to the topology container in the component graph. + SingleLink, MeshLoader, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_loader; + private: BeamSection beamSection; + + /// Pointer to the MeshLoader, should be set using @sa l_loader, otherwise will search for one in current Node. + MeshLoader* loader{ nullptr }; }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_WIRESECTIONMATERIAL_CPP) diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.inl b/src/BeamAdapter/component/model/WireSectionMaterial.inl index 6bbf4dd2e..981344118 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.inl +++ b/src/BeamAdapter/component/model/WireSectionMaterial.inl @@ -34,8 +34,11 @@ WireSectionMaterial::WireSectionMaterial() , d_radius(initData(&d_radius, (Real)1.0, "radius", "radius")) , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) + , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) + , d_density(initData(&d_density, 10, "densityOfBeams", "density of beams between key points")) , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) + , l_loader(initLink("loader", "link to the MeshLoader")) { } @@ -44,6 +47,8 @@ WireSectionMaterial::WireSectionMaterial() template void WireSectionMaterial::init() { + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Loading); + // Prepare beam sections double r = this->d_radius.getValue(); double rInner = this->d_innerRadius.getValue(); @@ -56,18 +61,29 @@ void WireSectionMaterial::init() this->beamSection._Asy = 0.0; this->beamSection._Asz = 0.0; - if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + if (!l_loader.empty()) { - msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; - d_nbEdgesVisu.setValue(10); + // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. + loader = l_loader.get(); + initFromLoader(); } + else + { + if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + { + msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + d_nbEdgesVisu.setValue(10); + } - if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) - { - msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; - d_nbEdgesCollis.setValue(10); + if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + { + msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + d_nbEdgesCollis.setValue(10); + } } + + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } @@ -96,4 +112,107 @@ void WireSectionMaterial::getInterpolationParam(Real& _rho, Real& _A, } } + +template +void WireSectionMaterial::initFromLoader() +{ + if (!checkTopology()) + { + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + return; + } + + // this is... dirty but d_straightLength itself is not relevant for loader-created wire + // but the code uses it actively and expects it to not be zero. + if (d_straightLength.getValue() <= 0.0) + { + msg_warning() << "straightLength cannot be 0 (or negative...). Setting a minimum value."; + d_straightLength.setValue(0.0001); + } + + type::vector vertices; + sofa::core::topology::BaseMeshTopology::SeqEdges edges; + + //get the topology position + auto topoVertices = sofa::helper::getReadAccessor(loader->d_positions); + + //copy the topology edges in a local vector + auto topoEdges = sofa::helper::getReadAccessor(loader->d_edges); + edges = topoEdges.ref(); + + /** renumber the vertices **/ + type::vector verticesConnexion; //gives the number of edges connected to a vertex + for (unsigned int i = 0; i < topoVertices.size(); i++) + verticesConnexion.push_back(2); + + for (const auto& ed : edges) + { + verticesConnexion[ed[0]]--; + verticesConnexion[ed[1]]--; + } + + msg_info() << "Successfully compute the vertex connexion"; + + // check for the first corner of the edge + unsigned int firstIndex = 0; + bool found = false; + while ((firstIndex < verticesConnexion.size()) && !found) + { + if (verticesConnexion[firstIndex] == 1) + found = true; + else + firstIndex++; + } + + if (firstIndex == verticesConnexion.size()) + { + msg_error() << "The first vertex of the beam structure is not found, probably because of a closed structure"; + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + return; + } + + vertices.push_back(topoVertices[firstIndex]); + + while (edges.size() > 0) + { + auto it = edges.begin(); + auto end = edges.end(); + + bool notFound = true; + while (notFound && (it != end)) + { + const auto& ed = (*it); + auto toDel = it; + it++; + if (ed[0] == firstIndex) + { + vertices.push_back(topoVertices[ed[1]]); + firstIndex = ed[1]; + edges.erase(toDel); + notFound = false; + + } + else if (ed[1] == firstIndex) + { + vertices.push_back(topoVertices[ed[0]]); + firstIndex = ed[0]; + edges.erase(toDel); + notFound = false; + } + } + } + + msg_info() << "Successfully computed the topology"; + + m_localRestPositions = vertices; + + for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) + m_localRestPositions[i] *= d_nonProceduralScale.getValue(); + + initRestConfig(); + // TODO epernod 2022-08-05: Init from loader seems quite buggy, need to check if this is still needed and working + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); +} + + } // namespace sofa::beamadapter From 44463a535ad2c959246a768bed2e305aea5a8f4e Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 29 Jun 2023 12:08:15 +0200 Subject: [PATCH 21/60] backup work on new RodSection classes architecture --- CMakeLists.txt | 15 +- .../component/engine/WireRestShape.h | 13 +- .../component/engine/WireRestShape.inl | 204 ++---------------- ...aterial.cpp => BaseRodSectionMaterial.cpp} | 12 +- ...ionMaterial.h => BaseRodSectionMaterial.h} | 23 +- .../model/BaseRodSectionMaterial.inl | 118 ++++++++++ .../component/model/RodMeshSection.cpp | 39 ++++ .../component/model/RodMeshSection.h | 74 +++++++ ...SectionMaterial.inl => RodMeshSection.inl} | 138 +++++------- .../component/model/RodSpireSection.cpp | 39 ++++ .../component/model/RodSpireSection.h | 58 +++++ .../component/model/RodSpireSection.inl | 45 ++++ .../component/model/RodStraightSection.cpp | 39 ++++ .../component/model/RodStraightSection.h | 60 ++++++ .../component/model/RodStraightSection.inl | 46 ++++ .../gpu/cuda/CudaInstantiations.cpp | 30 ++- 16 files changed, 645 insertions(+), 308 deletions(-) rename src/BeamAdapter/component/model/{WireSectionMaterial.cpp => BaseRodSectionMaterial.cpp} (84%) rename src/BeamAdapter/component/model/{WireSectionMaterial.h => BaseRodSectionMaterial.h} (83%) create mode 100644 src/BeamAdapter/component/model/BaseRodSectionMaterial.inl create mode 100644 src/BeamAdapter/component/model/RodMeshSection.cpp create mode 100644 src/BeamAdapter/component/model/RodMeshSection.h rename src/BeamAdapter/component/model/{WireSectionMaterial.inl => RodMeshSection.inl} (54%) create mode 100644 src/BeamAdapter/component/model/RodSpireSection.cpp create mode 100644 src/BeamAdapter/component/model/RodSpireSection.h create mode 100644 src/BeamAdapter/component/model/RodSpireSection.inl create mode 100644 src/BeamAdapter/component/model/RodStraightSection.cpp create mode 100644 src/BeamAdapter/component/model/RodStraightSection.h create mode 100644 src/BeamAdapter/component/model/RodStraightSection.inl diff --git a/CMakeLists.txt b/CMakeLists.txt index 41747175d..c7705ef9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,8 +58,14 @@ set(HEADER_FILES ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.h ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.inl - ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.h - ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.inl + ${BEAMADAPTER_SRC}/component/model/BaseRodSectionMaterial.h + ${BEAMADAPTER_SRC}/component/model/BaseRodSectionMaterial.inl + ${BEAMADAPTER_SRC}/component/model/RodMeshSection.h + ${BEAMADAPTER_SRC}/component/model/RodMeshSection.inl + ${BEAMADAPTER_SRC}/component/model/RodSpireSection.h + ${BEAMADAPTER_SRC}/component/model/RodSpireSection.inl + ${BEAMADAPTER_SRC}/component/model/RodStraightSection.h + ${BEAMADAPTER_SRC}/component/model/RodStraightSection.inl ${BEAMADAPTER_SRC}/utils/BeamSection.h ${BEAMADAPTER_SRC}/utils/BeamActions.h @@ -90,7 +96,10 @@ set(SOURCE_FILES ${BEAMADAPTER_SRC}/component/mapping/BeamLengthMapping.cpp ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.cpp - ${BEAMADAPTER_SRC}/component/model/WireSectionMaterial.cpp + ${BEAMADAPTER_SRC}/component/model/BaseRodSectionMaterial.cpp + ${BEAMADAPTER_SRC}/component/model/RodMeshSection.cpp + ${BEAMADAPTER_SRC}/component/model/RodSpireSection.cpp + ${BEAMADAPTER_SRC}/component/model/RodStraightSection.cpp ) if(SofaImplicitField_FOUND) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index ae62817d0..9710c3a44 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include @@ -73,7 +73,7 @@ class WireRestShape : public core::objectmodel::BaseObject using Quat = sofa::type::Quat; using BeamSection = sofa::beamadapter::BeamSection; - + /** * @brief Default Constructor. */ @@ -116,12 +116,11 @@ class WireRestShape : public core::objectmodel::BaseObject void initRestConfig(); void getRestPosNonProcedural(Real& abs, Coord &p); void computeOrientation(const Vec3& AB, const Quat& Q, Quat &result); - void initFromLoader(); - bool checkTopology(); + //[[nodiscard]] bool fillTopology(); Real getLength() ; - void getCollisionSampling(Real &dx, const Real &x_curv) ; + void getCollisionSampling(Real &dx, const Real &x_curv); void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) ; //TODO(dmarchal 2017-05-17) Please specify who and when it will be done either a time after wich @@ -131,6 +130,8 @@ class WireRestShape : public core::objectmodel::BaseObject void rotateFrameForAlignX(const Quat &input, Vec3 &x, Quat &output); + void getRodSectionMaterial(const Real& x_curv); + protected: /// Internal method to init Lengths vector @sa d_keyPoints if not set using @sa d_length and @sa d_straightLength. Returns false if init can't be performed. bool initLengths(); @@ -154,7 +155,7 @@ class WireRestShape : public core::objectmodel::BaseObject Data d_drawRestShape; /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. - MultiLink, WireSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; + MultiLink, BaseRodSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; private: /// Data required for the File loading diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index e11ec3800..42e4d2117 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -71,7 +71,6 @@ WireRestShape::WireRestShape() : , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) , l_topology(initLink("topology", "link to the topology container")) - , l_loader(initLink("loader", "link to the MeshLoader")) { d_spireDiameter.setGroup("Procedural"); d_spireHeight.setGroup("Procedural"); @@ -150,29 +149,10 @@ void WireRestShape::init() return; } - if (!d_isAProceduralShape.getValue()) - { - // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. - loader = l_loader.get(); - - if (!loader) - this->getContext()->get(loader); - - if (!loader) { - msg_error() << "Cannot find a mesh loader. Please insert a MeshObjLoader in the same node or use l_loader to specify the path in the scene graph."; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } - else - { - msg_info() << "Found a mesh with " << loader->d_edges.getValue().size() << " edges"; - initFromLoader(); - } - } if (l_sectionMaterials.empty()) { - msg_error() << "No WireSectionMaterial set. At least one material should be set and link using wireMaterials."; + msg_error() << "No BaseRodSectionMaterial set. At least one material should be set and link using wireMaterials."; this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); return; } @@ -188,15 +168,6 @@ void WireRestShape::init() return; } - //else - //{ - // if (!fillTopology()) - // { - // msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; - // this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - // return; - // } - //} // Get pointer to the topology Modifier (for topological changes) _topology->getContext()->get(edgeMod); if (edgeMod == nullptr) @@ -483,59 +454,32 @@ void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youn template void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) const { - const Real x_used = x_curv - Real(EPSILON); - const type::vector& keyPts = d_keyPoints.getValue(); - - // Check in which section x_used belongs to and get access to this section material - for (auto i = 1; i < keyPts.size(); ++i) - { - if (x_used <= keyPts[i]) - { - return l_sectionMaterials.get(i - 1)->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); - } - } - - msg_error() << " problem in getInterpolationParam : x_curv " << x_curv << " is not between keyPoints" << keyPts; + BaseRodSectionMaterial* wireSection = nullptr; + //getRodSectionMaterial(x_curv); + if (wireSection) + wireSection->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); + else + msg_error() << " problem in getInterpolationParam : x_curv " << x_curv << " is not between keyPoints"; } - template -bool WireRestShape::checkTopology() +void WireRestShape::getRodSectionMaterial(const Real& x_curv) { - if (!loader->d_edges.getValue().size()) - { - msg_error() << "There is no edges in the topology loaded by " << loader->getName() ; - return false; - } - - if (loader->d_triangles.getValue().size()) - { - msg_error() << "There are triangles in the topology loaded by " << loader->getName() ; - return false; - } - - if (loader->d_quads.getValue().size()) - { - msg_error() << "There are quads in the topology loaded by " << loader->getName() ; - return false; - } - - if (loader->d_polygons.getValue().size()) - { - msg_error() << "There are polygons in the topology loaded by " << loader->getName() ; - return false; - } - - //TODO(dmarchal 2017-05-17) when writing a TODO please specify: - // who will do that - // when it will be done - /// \todo check if the topology is like a wire + //const Real x_used = x_curv - Real(EPSILON); + //const type::vector& keyPts = d_keyPoints.getValue(); + //// Check in which section x_used belongs to and get access to this section material + //for (auto i = 1; i < keyPts.size(); ++i) + //{ + // if (x_used <= keyPts[i]) + // { + // return l_sectionMaterials.get(i - 1); + // } + //} - return true; + //return nullptr; } - //template //bool WireRestShape::fillTopology() //{ @@ -577,109 +521,6 @@ bool WireRestShape::checkTopology() //} - -template -void WireRestShape::initFromLoader() -{ - if (!checkTopology()) - { - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } - - // this is... dirty but d_straightLength itself is not relevant for loader-created wire - // but the code uses it actively and expects it to not be zero. - if (d_straightLength.getValue() <= 0.0) - { - msg_warning() << "straightLength cannot be 0 (or negative...). Setting a minimum value."; - d_straightLength.setValue(0.0001); - } - - type::vector vertices; - sofa::core::topology::BaseMeshTopology::SeqEdges edges; - - //get the topology position - auto topoVertices = sofa::helper::getReadAccessor(loader->d_positions); - - //copy the topology edges in a local vector - auto topoEdges = sofa::helper::getReadAccessor(loader->d_edges); - edges = topoEdges.ref(); - - /** renumber the vertices **/ - type::vector verticesConnexion; //gives the number of edges connected to a vertex - for(unsigned int i =0; i < topoVertices.size(); i++) - verticesConnexion.push_back(2); - - for(const auto& ed : edges) - { - verticesConnexion[ed[0]]--; - verticesConnexion[ed[1]]--; - } - - msg_info() << "Successfully compute the vertex connexion" ; - - // check for the first corner of the edge - unsigned int firstIndex = 0; - bool found = false; - while((firstIndex < verticesConnexion.size()) && !found) - { - if(verticesConnexion[firstIndex] == 1) - found = true; - else - firstIndex++; - } - - if(firstIndex == verticesConnexion.size()) - { - msg_error() << "The first vertex of the beam structure is not found, probably because of a closed structure" ; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } - - vertices.push_back(topoVertices[firstIndex]); - - while(edges.size() > 0) - { - auto it = edges.begin(); - auto end = edges.end(); - - bool notFound = true; - while (notFound && (it != end)) - { - const auto& ed = (*it); - auto toDel = it; - it++; - if(ed[0] == firstIndex) - { - vertices.push_back(topoVertices[ed[1]]); - firstIndex = ed[1]; - edges.erase(toDel); - notFound = false; - - } - else if(ed[1] == firstIndex) - { - vertices.push_back(topoVertices[ed[0]]); - firstIndex = ed[0]; - edges.erase(toDel); - notFound = false; - } - } - } - - msg_info() << "Successfully computed the topology" ; - - m_localRestPositions = vertices; - - for(unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) - m_localRestPositions[i] *= d_nonProceduralScale.getValue(); - - initRestConfig(); - // TODO epernod 2022-08-05: Init from loader seems quite buggy, need to check if this is still needed and working - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); -} - - template void WireRestShape::initRestConfig() { @@ -716,13 +557,6 @@ void WireRestShape::initRestConfig() d_length.setValue(newLength); msg_info() <<"Length of the loaded shape = "<< m_absOfGeometry << ", total length with straight length = " << newLength ; - - //if (!fillTopology()) - //{ - // msg_error() << "Error while trying to fill the associated topology, setting the state to Invalid"; - // this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - // return; - //} } diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.cpp b/src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp similarity index 84% rename from src/BeamAdapter/component/model/WireSectionMaterial.cpp rename to src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp index 1de24395d..450681d63 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.cpp +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp @@ -19,9 +19,9 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFA_PLUGIN_BEAMADAPTER_WIRESECTIONMATERIAL_CPP +#define SOFA_PLUGIN_BEAMADAPTER_BASERODSECTIONMATERIAL_CPP -#include +#include #include #include #include @@ -31,9 +31,9 @@ namespace sofa::beamadapter using namespace sofa::defaulttype; -const int WireSectionMaterialClass = core::RegisterObject("Wire Section Material.") -.add< WireSectionMaterial >(true); - -template class SOFA_BEAMADAPTER_API WireSectionMaterial; +//const int BaseRodSectionMaterialClass = core::RegisterObject("Wire Section Material.") +//.add< BaseRodSectionMaterial >(true); +// +//template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; }// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.h b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h similarity index 83% rename from src/BeamAdapter/component/model/WireSectionMaterial.h rename to src/BeamAdapter/component/model/BaseRodSectionMaterial.h index a63abfc69..44a9a043f 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.h +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace sofa::beamadapter @@ -40,16 +41,17 @@ using sofa::core::loader::MeshLoader; * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. */ template -class WireSectionMaterial : public core::objectmodel::BaseObject +class BaseRodSectionMaterial : public core::objectmodel::BaseObject { public: - SOFA_CLASS(WireSectionMaterial, core::objectmodel::BaseObject); + SOFA_CLASS(SOFA_TEMPLATE(BaseRodSectionMaterial, DataTypes), core::objectmodel::BaseObject); using Coord = typename DataTypes::Coord; using Real = typename Coord::value_type; + using Vec3 = sofa::type::Vec<3, Real>; /// Default Constructor - WireSectionMaterial(); + BaseRodSectionMaterial(); void init() override; @@ -64,7 +66,7 @@ class WireSectionMaterial : public core::objectmodel::BaseObject [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } protected: - void initFromLoader(); + virtual void initSection() {} public: /// User Data about the Young modulus @@ -76,24 +78,17 @@ class WireSectionMaterial : public core::objectmodel::BaseObject Data d_innerRadius; Data d_massDensity; + Data d_spireDiameter; + Data d_spireHeight; + Data d_length; Data d_density; Data< int > d_nbEdgesVisu; Data< int > d_nbEdgesCollis; - /// Link to be set to the topology container in the component graph. - SingleLink, MeshLoader, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_loader; - private: BeamSection beamSection; - - /// Pointer to the MeshLoader, should be set using @sa l_loader, otherwise will search for one in current Node. - MeshLoader* loader{ nullptr }; }; -#if !defined(SOFA_PLUGIN_BEAMADAPTER_WIRESECTIONMATERIAL_CPP) -extern template class SOFA_BEAMADAPTER_API WireSectionMaterial; -#endif - } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl new file mode 100644 index 000000000..4f1c8d607 --- /dev/null +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl @@ -0,0 +1,118 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::beamadapter +{ + +template +BaseRodSectionMaterial::BaseRodSectionMaterial() + : d_poissonRatio(initData(&d_poissonRatio, (Real)0.49, "poissonRatio", "Poisson Ratio")) + , d_youngModulus(initData(&d_youngModulus, (Real)5000, "youngModulus", "Young Modulus")) + , d_radius(initData(&d_radius, (Real)1.0, "radius", "radius")) + , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) + , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) + , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) + , d_density(initData(&d_density, 10, "densityOfBeams", "density of beams between key points")) + , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) + , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) +{ + +} + + +template +void BaseRodSectionMaterial::init() +{ + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Loading); + + // Prepare beam sections + double r = this->d_radius.getValue(); + double rInner = this->d_innerRadius.getValue(); + this->beamSection._r = r; + this->beamSection._rInner = rInner; + this->beamSection._Iz = M_PI * (r * r * r * r - rInner * rInner * rInner * rInner) / 4.0; + this->beamSection._Iy = this->beamSection._Iz; + this->beamSection._J = this->beamSection._Iz + this->beamSection._Iy; + this->beamSection._A = M_PI * (r * r - rInner * rInner); + this->beamSection._Asy = 0.0; + this->beamSection._Asz = 0.0; + + initSection(); + + //if (!l_loader.empty()) + //{ + // // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. + // loader = l_loader.get(); + // initFromLoader(); + //} + //else + //{ + // if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + // { + // msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + // d_nbEdgesVisu.setValue(10); + // } + + + // if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + // { + // msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + // d_nbEdgesCollis.setValue(10); + // } + //} + + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); +} + + +template +void BaseRodSectionMaterial::getYoungModulusAtX(Real& youngModulus, Real& cPoisson) const +{ + youngModulus = this->d_youngModulus.getValue(); + cPoisson = this->d_poissonRatio.getValue(); +} + + +template +void BaseRodSectionMaterial::getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const +{ + if (d_massDensity.isSet()) + _rho = d_massDensity.getValue(); + + if (d_radius.isSet()) + { + _A = beamSection._A; + _Iy = beamSection._Iy; + _Iz = beamSection._Iz; + _Asy = beamSection._Asy; + _Asz = beamSection._Asz; + _J = beamSection._J; + } +} + + + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodMeshSection.cpp b/src/BeamAdapter/component/model/RodMeshSection.cpp new file mode 100644 index 000000000..58b506884 --- /dev/null +++ b/src/BeamAdapter/component/model/RodMeshSection.cpp @@ -0,0 +1,39 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_PLUGIN_BEAMADAPTER_RODMESHSECTION_CPP + +#include +#include +#include +#include + +namespace sofa::beamadapter +{ + +using namespace sofa::defaulttype; + +const int RodMeshSectionClass = core::RegisterObject("Class defining a Rod Section using a MeshLoader and material parameters.") + .add< RodMeshSection >(true); + +template class SOFA_BEAMADAPTER_API RodMeshSection; + +}// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodMeshSection.h b/src/BeamAdapter/component/model/RodMeshSection.h new file mode 100644 index 000000000..07e686dff --- /dev/null +++ b/src/BeamAdapter/component/model/RodMeshSection.h @@ -0,0 +1,74 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::beamadapter +{ + +using sofa::core::loader::MeshLoader; + +/** + * \class WireRestShape + * \brief Describe the shape functions on multiple segments + * + * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + */ +template +class RodMeshSection : public sofa::beamadapter::BaseRodSectionMaterial +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(RodMeshSection, DataTypes), SOFA_TEMPLATE(BaseRodSectionMaterial, DataTypes)); + + using Coord = typename DataTypes::Coord; + using Real = typename Coord::value_type; + using Vec3 = sofa::type::Vec<3, Real>; + + /// Default Constructor + RodMeshSection(); + +protected: + void initSection() override; + void initFromLoader(); + bool checkLoaderTopology(); + +public: + /// Link to be set to the topology container in the component graph. + SingleLink, MeshLoader, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_loader; + +private: + /// Pointer to the MeshLoader, should be set using @sa l_loader, otherwise will search for one in current Node. + MeshLoader* loader{ nullptr }; + + /// Data required for the File loading + type::vector m_localRestPositions; +}; + +#if !defined(SOFA_PLUGIN_BEAMADAPTER_RODMESHSECTION_CPP) +extern template class SOFA_BEAMADAPTER_API RodMeshSection; +#endif + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/WireSectionMaterial.inl b/src/BeamAdapter/component/model/RodMeshSection.inl similarity index 54% rename from src/BeamAdapter/component/model/WireSectionMaterial.inl rename to src/BeamAdapter/component/model/RodMeshSection.inl index 981344118..5d67bd15c 100644 --- a/src/BeamAdapter/component/model/WireSectionMaterial.inl +++ b/src/BeamAdapter/component/model/RodMeshSection.inl @@ -21,23 +21,16 @@ ******************************************************************************/ #pragma once -#include +#include +#include #include namespace sofa::beamadapter { template -WireSectionMaterial::WireSectionMaterial() - : d_poissonRatio(initData(&d_poissonRatio, (Real)0.49, "poissonRatio", "Poisson Ratio")) - , d_youngModulus(initData(&d_youngModulus, (Real)5000, "youngModulus", "Young Modulus")) - , d_radius(initData(&d_radius, (Real)1.0, "radius", "radius")) - , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) - , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) - , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) - , d_density(initData(&d_density, 10, "densityOfBeams", "density of beams between key points")) - , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) - , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) +RodMeshSection::RodMeshSection() + : BaseRodSectionMaterial() , l_loader(initLink("loader", "link to the MeshLoader")) { @@ -45,91 +38,21 @@ WireSectionMaterial::WireSectionMaterial() template -void WireSectionMaterial::init() +void RodMeshSection::initSection() { - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Loading); - - // Prepare beam sections - double r = this->d_radius.getValue(); - double rInner = this->d_innerRadius.getValue(); - this->beamSection._r = r; - this->beamSection._rInner = rInner; - this->beamSection._Iz = M_PI * (r * r * r * r - rInner * rInner * rInner * rInner) / 4.0; - this->beamSection._Iy = this->beamSection._Iz; - this->beamSection._J = this->beamSection._Iz + this->beamSection._Iy; - this->beamSection._A = M_PI * (r * r - rInner * rInner); - this->beamSection._Asy = 0.0; - this->beamSection._Asz = 0.0; - - if (!l_loader.empty()) - { - // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. - loader = l_loader.get(); - initFromLoader(); - } - else - { - if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) - { - msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; - d_nbEdgesVisu.setValue(10); - } - - - if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) - { - msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; - d_nbEdgesCollis.setValue(10); - } - } - - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); -} - - -template -void WireSectionMaterial::getYoungModulusAtX(Real& youngModulus, Real& cPoisson) const -{ - youngModulus = this->d_youngModulus.getValue(); - cPoisson = this->d_poissonRatio.getValue(); -} - - -template -void WireSectionMaterial::getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const -{ - if (d_massDensity.isSet()) - _rho = d_massDensity.getValue(); - - if (d_radius.isSet()) - { - _A = beamSection._A; - _Iy = beamSection._Iy; - _Iz = beamSection._Iz; - _Asy = beamSection._Asy; - _Asz = beamSection._Asz; - _J = beamSection._J; - } + } template -void WireSectionMaterial::initFromLoader() +void RodMeshSection::initFromLoader() { - if (!checkTopology()) + if (!checkLoaderTopology()) { this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); return; } - // this is... dirty but d_straightLength itself is not relevant for loader-created wire - // but the code uses it actively and expects it to not be zero. - if (d_straightLength.getValue() <= 0.0) - { - msg_warning() << "straightLength cannot be 0 (or negative...). Setting a minimum value."; - d_straightLength.setValue(0.0001); - } - type::vector vertices; sofa::core::topology::BaseMeshTopology::SeqEdges edges; @@ -206,13 +129,52 @@ void WireSectionMaterial::initFromLoader() m_localRestPositions = vertices; - for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) - m_localRestPositions[i] *= d_nonProceduralScale.getValue(); + //for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) + // m_localRestPositions[i] *= d_nonProceduralScale.getValue(); - initRestConfig(); + //TODO on the WireRestShape + //initRestConfig(); // TODO epernod 2022-08-05: Init from loader seems quite buggy, need to check if this is still needed and working this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } +template +bool RodMeshSection::checkLoaderTopology() +{ + if (!loader->d_edges.getValue().size()) + { + msg_error() << "There is no edges in the topology loaded by " << loader->getName(); + return false; + } + + if (loader->d_triangles.getValue().size()) + { + msg_error() << "There are triangles in the topology loaded by " << loader->getName(); + return false; + } + + if (loader->d_quads.getValue().size()) + { + msg_error() << "There are quads in the topology loaded by " << loader->getName(); + return false; + } + + if (loader->d_polygons.getValue().size()) + { + msg_error() << "There are polygons in the topology loaded by " << loader->getName(); + return false; + } + + //TODO(dmarchal 2017-05-17) when writing a TODO please specify: + // who will do that + // when it will be done + /// \todo check if the topology is like a wire + + + return true; +} + + + } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodSpireSection.cpp b/src/BeamAdapter/component/model/RodSpireSection.cpp new file mode 100644 index 000000000..04b64d83a --- /dev/null +++ b/src/BeamAdapter/component/model/RodSpireSection.cpp @@ -0,0 +1,39 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_PLUGIN_BEAMADAPTER_RODSPIRESECTION_CPP + +#include +#include +#include +#include + +namespace sofa::beamadapter +{ + +using namespace sofa::defaulttype; + +const int RodSpireSectionClass = core::RegisterObject("Class defining a rod spire section, defining material and geometry parameters.") + .add< RodSpireSection >(true); + +template class SOFA_BEAMADAPTER_API RodSpireSection; + +}// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodSpireSection.h b/src/BeamAdapter/component/model/RodSpireSection.h new file mode 100644 index 000000000..fec2f10d5 --- /dev/null +++ b/src/BeamAdapter/component/model/RodSpireSection.h @@ -0,0 +1,58 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::beamadapter +{ + +using sofa::core::loader::MeshLoader; + +/** + * \class WireRestShape + * \brief Describe the shape functions on multiple segments + * + * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + */ +template +class RodSpireSection : public sofa::beamadapter::BaseRodSectionMaterial +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(RodSpireSection, DataTypes), SOFA_TEMPLATE(BaseRodSectionMaterial, DataTypes)); + + /// Default Constructor + RodSpireSection(); + +protected: + void initSection() override; + +private: +}; + +#if !defined(SOFA_PLUGIN_BEAMADAPTER_RODSPIRESECTION_CPP) +extern template class SOFA_BEAMADAPTER_API RodSpireSection; +#endif + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodSpireSection.inl b/src/BeamAdapter/component/model/RodSpireSection.inl new file mode 100644 index 000000000..0f46a1970 --- /dev/null +++ b/src/BeamAdapter/component/model/RodSpireSection.inl @@ -0,0 +1,45 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::beamadapter +{ + +template +RodSpireSection::RodSpireSection() + : BaseRodSectionMaterial() +{ + +} + + +template +void RodSpireSection::initSection() +{ + +} + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodStraightSection.cpp b/src/BeamAdapter/component/model/RodStraightSection.cpp new file mode 100644 index 000000000..777466bf0 --- /dev/null +++ b/src/BeamAdapter/component/model/RodStraightSection.cpp @@ -0,0 +1,39 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_PLUGIN_BEAMADAPTER_RODSTRAIGHTSECTION_CPP + +#include +#include +#include +#include + +namespace sofa::beamadapter +{ + +using namespace sofa::defaulttype; + +const int RodStraightSectionClass = core::RegisterObject("Class defining a rod straight section Material, defining material and geometry parameters.") + .add< RodStraightSection >(true); + +template class SOFA_BEAMADAPTER_API RodStraightSection; + +}// namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodStraightSection.h b/src/BeamAdapter/component/model/RodStraightSection.h new file mode 100644 index 000000000..0abecc4f6 --- /dev/null +++ b/src/BeamAdapter/component/model/RodStraightSection.h @@ -0,0 +1,60 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::beamadapter +{ + +using sofa::core::loader::MeshLoader; + +/** + * \class WireRestShape + * \brief Describe the shape functions on multiple segments + * + * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + */ +template +class RodStraightSection : public sofa::beamadapter::BaseRodSectionMaterial +{ +public: + SOFA_CLASS(SOFA_TEMPLATE(RodStraightSection, DataTypes), SOFA_TEMPLATE(BaseRodSectionMaterial, DataTypes)); + + using Coord = typename DataTypes::Coord; + using Real = typename Coord::value_type; + using Vec3 = sofa::type::Vec<3, Real>; + + /// Default Constructor + RodStraightSection(); + +protected: + void initSection() override; +}; + +#if !defined(SOFA_PLUGIN_BEAMADAPTER_RODSTRAIGHTSECTION_CPP) +extern template class SOFA_BEAMADAPTER_API RodStraightSection; +#endif + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodStraightSection.inl b/src/BeamAdapter/component/model/RodStraightSection.inl new file mode 100644 index 000000000..45bd623bb --- /dev/null +++ b/src/BeamAdapter/component/model/RodStraightSection.inl @@ -0,0 +1,46 @@ +/****************************************************************************** +* BeamAdapter plugin * +* (c) 2006 Inria, University of Lille, CNRS * +* * +* 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 . * +******************************************************************************* +* Authors: see Authors.md * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::beamadapter +{ + +template +RodStraightSection::RodStraightSection() + : BaseRodSectionMaterial() +{ + +} + + +template +void RodStraightSection::initSection() +{ + +} + + +} // namespace sofa::beamadapter diff --git a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp index f9a3fcea2..fb5d3a1c8 100644 --- a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp +++ b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp @@ -28,7 +28,9 @@ #include #include #include -#include +#include +#include +#include #include #include @@ -89,9 +91,9 @@ namespace sofa::component::mapping namespace sofa::beamadapter { - template class SOFA_BEAMADAPTER_API WireSectionMaterial; + template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; #ifdef SOFA_GPU_CUDA_DOUBLE - template class SOFA_BEAMADAPTER_API WireSectionMaterial; + template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; #endif } // namespace sofa::beamadapter @@ -148,13 +150,29 @@ int CudaMultiAdaptiveBeamMappingClass = core::RegisterObject("Set the positions #endif ; -int CudaWireSectionMaterialClass = core::RegisterObject("Wire Section Material using CUDA.") - .add< sofa::beamadapter::WireSectionMaterial >() +const int CudaRodMeshSectionClass = core::RegisterObject("Class defining a Rod Section using a MeshLoader and material parameters using CUDA.") + .add< sofa::beamadapter::RodMeshSection >() #ifdef SOFA_GPU_CUDA_DOUBLE - .add< sofa::beamadapter::WireSectionMaterial >() + .add< sofa::beamadapter::RodMeshSection >() #endif ; +const int CudaRodSpireSectionClass = core::RegisterObject("Class defining a rod spire section, defining material and geometry parameters using CUDA.") + .add< sofa::beamadapter::RodSpireSection >() +#ifdef SOFA_GPU_CUDA_DOUBLE + .add< sofa::beamadapter::RodSpireSection >() +#endif +; + +const int CudaRodStraightSectionClass = core::RegisterObject("Class defining a rod straight section Material, defining material and geometry parameters using CUDA.") + .add< sofa::beamadapter::RodStraightSection >() +#ifdef SOFA_GPU_CUDA_DOUBLE + .add< sofa::beamadapter::RodStraightSection >() +#endif +; + + + } // namespace sofa::gpu::cuda From 3d1cc2cd2ac65c3bb1e646298af2e9fd8e471fd5 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 29 Jun 2023 16:28:37 +0200 Subject: [PATCH 22/60] Add RodSpire and RodStraight sections implementation --- .../component/model/BaseRodSectionMaterial.h | 16 +++++++--- .../model/BaseRodSectionMaterial.inl | 1 - .../component/model/RodSpireSection.h | 6 ++++ .../component/model/RodSpireSection.inl | 32 +++++++++++++++++++ .../component/model/RodStraightSection.h | 15 +++------ .../component/model/RodStraightSection.inl | 7 ++++ 6 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.h b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h index 44a9a043f..d66682afe 100644 --- a/src/BeamAdapter/component/model/BaseRodSectionMaterial.h +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h @@ -48,7 +48,9 @@ class BaseRodSectionMaterial : public core::objectmodel::BaseObject using Coord = typename DataTypes::Coord; using Real = typename Coord::value_type; + using Transform = typename sofa::defaulttype::SolidTypes::Transform; using Vec3 = sofa::type::Vec<3, Real>; + using Quat = sofa::type::Quat; /// Default Constructor BaseRodSectionMaterial(); @@ -61,9 +63,19 @@ class BaseRodSectionMaterial : public core::objectmodel::BaseObject /// This function gives the mass density and the BeamSection data depending on the beam position void getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const; + /// This function is called by the force field to evaluate the rest position of each beam + virtual void getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) + { + SOFA_UNUSED(global_H_local); + SOFA_UNUSED(x_used); + SOFA_UNUSED(x_start); + } + [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } + + [[nodiscard]] Real getLength() const { return d_length.getValue(); } protected: virtual void initSection() {} @@ -78,11 +90,7 @@ class BaseRodSectionMaterial : public core::objectmodel::BaseObject Data d_innerRadius; Data d_massDensity; - Data d_spireDiameter; - Data d_spireHeight; - Data d_length; - Data d_density; Data< int > d_nbEdgesVisu; Data< int > d_nbEdgesCollis; diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl index 4f1c8d607..0464da6e3 100644 --- a/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl @@ -35,7 +35,6 @@ BaseRodSectionMaterial::BaseRodSectionMaterial() , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) - , d_density(initData(&d_density, 10, "densityOfBeams", "density of beams between key points")) , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) { diff --git a/src/BeamAdapter/component/model/RodSpireSection.h b/src/BeamAdapter/component/model/RodSpireSection.h index fec2f10d5..ca1000cf2 100644 --- a/src/BeamAdapter/component/model/RodSpireSection.h +++ b/src/BeamAdapter/component/model/RodSpireSection.h @@ -45,9 +45,15 @@ class RodSpireSection : public sofa::beamadapter::BaseRodSectionMaterial d_spireDiameter; + Data d_spireHeight; + private: }; diff --git a/src/BeamAdapter/component/model/RodSpireSection.inl b/src/BeamAdapter/component/model/RodSpireSection.inl index 0f46a1970..b155a1498 100644 --- a/src/BeamAdapter/component/model/RodSpireSection.inl +++ b/src/BeamAdapter/component/model/RodSpireSection.inl @@ -31,6 +31,8 @@ namespace sofa::beamadapter template RodSpireSection::RodSpireSection() : BaseRodSectionMaterial() + , d_spireDiameter(initData(&d_spireDiameter, (Real)0.1, "spireDiameter", "diameter of the spire")) + , d_spireHeight(initData(&d_spireHeight, (Real)0.01, "spireHeight", "height between each spire")) { } @@ -42,4 +44,34 @@ void RodSpireSection::initSection() } + +template +void RodSpireSection::getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) +{ + Real projetedLength = d_spireDiameter.getValue() * M_PI; + Real lengthSpire = sqrt(d_spireHeight.getValue() * d_spireHeight.getValue() + projetedLength * projetedLength); + // angle in the z direction + Real phi = atan(d_spireHeight.getValue() / projetedLength); + + Quat Qphi; + Qphi.axisToQuat(Vec3(0, 0, 1), phi); + + // spire angle (if theta=2*PI, there is a complete spire between startx and x) + Real lengthCurve = x_used - x_start; + Real numSpire = lengthCurve / lengthSpire; + Real theta = 2 * M_PI * numSpire; + + // computation of the Quat + Quat Qtheta; + Qtheta.axisToQuat(Vec3(0, 1, 0), theta); + Quat newSpireQuat = Qtheta * Qphi; + + // computation of the position + Real radius = d_spireDiameter.getValue() / 2.0; + Vec3 PosEndCurve(radius * sin(theta), numSpire * d_spireHeight.getValue(), radius * (cos(theta) - 1)); + Vec3 SpirePos = PosEndCurve + Vec3(x_start, 0, 0); + + global_H_local.set(SpirePos, newSpireQuat); +} + } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodStraightSection.h b/src/BeamAdapter/component/model/RodStraightSection.h index 0abecc4f6..afc49e478 100644 --- a/src/BeamAdapter/component/model/RodStraightSection.h +++ b/src/BeamAdapter/component/model/RodStraightSection.h @@ -27,14 +27,11 @@ namespace sofa::beamadapter { -using sofa::core::loader::MeshLoader; - /** - * \class WireRestShape - * \brief Describe the shape functions on multiple segments + * \class RodStraightSection + * \brief Describe a rod straight section * - * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) - * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + * */ template class RodStraightSection : public sofa::beamadapter::BaseRodSectionMaterial @@ -42,13 +39,11 @@ class RodStraightSection : public sofa::beamadapter::BaseRodSectionMaterial; - /// Default Constructor RodStraightSection(); + void getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) override; + protected: void initSection() override; }; diff --git a/src/BeamAdapter/component/model/RodStraightSection.inl b/src/BeamAdapter/component/model/RodStraightSection.inl index 45bd623bb..dc47d41e6 100644 --- a/src/BeamAdapter/component/model/RodStraightSection.inl +++ b/src/BeamAdapter/component/model/RodStraightSection.inl @@ -43,4 +43,11 @@ void RodStraightSection::initSection() } +template +void RodStraightSection::getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) +{ + global_H_local.set(Vec3(x_start + x_used, 0.0, 0.0), Quat()); +} + + } // namespace sofa::beamadapter From 5f48f9ef301ba9d23d0edf55c9b95e0efd5dd24f Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 29 Jun 2023 16:34:17 +0200 Subject: [PATCH 23/60] [WireRestShape] Remove optiond releaseWire or brokenIn2 --- .../component/engine/WireRestShape.h | 13 ++-- .../component/engine/WireRestShape.inl | 59 +------------------ 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 9710c3a44..da2ea7931 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -94,7 +94,10 @@ class WireRestShape : public core::objectmodel::BaseObject /////////////////////////// Methods of WireRestShape ////////////////////////////////////////// /// For coils: a part of the coil instrument can be brokenIn2 (by default the point of release is the end of the straight length) - Real getReleaseCurvAbs() const {return d_straightLength.getValue();} + Real getReleaseCurvAbs() const { + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + return 0.0; + } /// This function is called by the force field to evaluate the rest position of each beam void getRestTransformOnX(Transform &global_H_local, const Real &x); @@ -123,10 +126,9 @@ class WireRestShape : public core::objectmodel::BaseObject void getCollisionSampling(Real &dx, const Real &x_curv); void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) ; - //TODO(dmarchal 2017-05-17) Please specify who and when it will be done either a time after wich - //we can remove the todo. - // todo => topological change ! - void releaseWirePart(); + void releaseWirePart() { + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + } void rotateFrameForAlignX(const Quat &input, Vec3 &x, Quat &output); @@ -151,7 +153,6 @@ class WireRestShape : public core::objectmodel::BaseObject Data > d_keyPoints; /// broken in 2 case - Data d_brokenIn2; Data d_drawRestShape; /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 42e4d2117..d6184ff37 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -67,7 +67,6 @@ WireRestShape::WireRestShape() : , d_spireHeight(initData(&d_spireHeight, (Real)0.01, "spireHeight", "height between each spire")) , d_density(initData(&d_density, "densityOfBeams", "density of beams between key points")) , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) - , d_brokenIn2(initData(&d_brokenIn2, (bool)false, "brokenIn2", "")) , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) , l_topology(initLink("topology", "link to the topology container")) @@ -265,66 +264,12 @@ bool WireRestShape::initTopology() } -template -void WireRestShape::releaseWirePart() -{ - - d_brokenIn2.setValue(true); - - if ( edgeMod == nullptr ) - { - msg_error() << "no edgeSetModifier in the node -> cannot do the topological change"; - return; - } - ///////// remove the edge that is cut ////// - for ( sofa::Size i=0; i<_topology->getNbPoints(); i++) - { - if( _topology->getPX(i) > this->getReleaseCurvAbs() + EPSILON ) - { - type::vector edge_remove; - edge_remove.push_back( i-1 ); - - msg_info() << "releaseWirePart() -> remove edge number "<< i ; - - edgeMod->removeEdges(edge_remove,false); // remove the single edge and do not remove any point... - - msg_info() << "WireRestShape _topology name="<<_topology->getName()<<" - numEdges ="<<_topology->getNbEdges() ; - - return; - } - } - - dmsg_info() <<" Wire Part is brokenIn2... should implement a topo change !" ; -} - - template void WireRestShape::getSamplingParameters(type::vector& xP_noticeable, type::vector& nbP_density) const { - - xP_noticeable.clear(); - nbP_density.clear(); - - if (d_brokenIn2.getValue()) - { - for (unsigned int i=0; i getReleaseCurvAbs() ) - break; - xP_noticeable.push_back(x); - nbP_density.push_back(d_density.getValue()[i]); - } - xP_noticeable.push_back( getReleaseCurvAbs()); - - dmsg_info() <<"getSamplingParameters brokenIn2 detected - return xP_noticeable ="<d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); + return; + } + else + { + msg_info() << "Found a mesh with " << loader->d_edges.getValue().size() << " edges"; + initFromLoader(); + } +} + + +template +void RodMeshSection::getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) +{ + Real x_local = x_used - x_start; + x_local = x_local /(d_length.getValue()) * m_absOfGeometry; + + Coord p; + this->getRestPosNonProcedural(x_local, p); + + Vec3 PosEndCurve = p.getCenter(); + Quat ExtremityQuat = p.getOrientation(); + Vec3 ExtremityPos = PosEndCurve + Vec3(x_start, 0, 0); + + global_H_local.set(ExtremityPos, ExtremityQuat); } @@ -129,12 +163,8 @@ void RodMeshSection::initFromLoader() m_localRestPositions = vertices; - //for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) - // m_localRestPositions[i] *= d_nonProceduralScale.getValue(); + initRestConfig(); - //TODO on the WireRestShape - //initRestConfig(); - // TODO epernod 2022-08-05: Init from loader seems quite buggy, need to check if this is still needed and working this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } @@ -166,15 +196,113 @@ bool RodMeshSection::checkLoaderTopology() return false; } - //TODO(dmarchal 2017-05-17) when writing a TODO please specify: - // who will do that - // when it will be done - /// \todo check if the topology is like a wire + return true; +} - return true; +template +void RodMeshSection::rotateFrameForAlignX(const Quat& input, Vec3& x, Quat& output) +{ + x.normalize(); + Vec3 x0 = input.inverseRotate(x); + + Real cTheta = x0[0]; + Real theta; + if (cTheta > (1 - EPSILON)) + { + output = input; + } + else + { + theta = acos(cTheta); + // axis of rotation + Vec3 dw(0, -x0[2], x0[1]); + dw.normalize(); + + // computation of the rotation + Quat inputRoutput; + inputRoutput.axisToQuat(dw, theta); + + output = input * inputRoutput; + } +} + + +template +void RodMeshSection::initRestConfig() +{ + m_curvAbs.clear(); + double tot = 0; + m_curvAbs.push_back(0); + Quat input, output; + input.identity(); + m_localRestTransforms.resize(m_localRestPositions.size()); + m_localRestTransforms[0].setOrigin(Vec3(0, 0, 0)); + m_localRestTransforms[0].setOrientation(input); + + for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) + { + Vec3 vec = m_localRestPositions[i + 1] - m_localRestPositions[i]; + double norm = vec.norm(); + tot += norm; + + this->rotateFrameForAlignX(input, vec, output); + + input = output; + + m_localRestTransforms[i + 1].setOrientation(output); + + Vec3 localPos = m_localRestPositions[i + 1] - m_localRestPositions[0]; + + m_localRestTransforms[i + 1].setOrigin(localPos); + + m_curvAbs.push_back(tot); + } + m_absOfGeometry = tot; + + d_length.setValue(m_absOfGeometry); + + msg_info() << "Length of the loaded shape = " << m_absOfGeometry; } +template +void RodMeshSection::getRestPosNonProcedural(Real& abs, Coord& p) +{ + /*** find the range which includes the "requested" abs ***/ + double startingAbs = 0; unsigned int index = 0; + + while ((startingAbs < abs) && (index < m_localRestPositions.size())) + { + index++; + startingAbs = m_curvAbs[index]; + } + + /*** OOB ***/ + if (abs > startingAbs) + { + msg_error() << "abs = " << abs << " et startingAbs = " << startingAbs << msgendl + << "Out of bound position request"; + return; + } + else /*** Expected case ***/ + { + Real alpha, one_minus_alpha; + Vec3 result; + + alpha = (abs - m_curvAbs[index - 1]) / (m_curvAbs[index] - m_curvAbs[index - 1]); + one_minus_alpha = 1 - alpha; + result = m_localRestTransforms[index - 1].getOrigin() * one_minus_alpha + m_localRestTransforms[index].getOrigin() * alpha; + Quat slerp; + slerp.slerp(m_localRestTransforms[index - 1].getOrientation(), m_localRestTransforms[index].getOrientation(), alpha, true); + + slerp.normalize(); + + p.getCenter() = result; + + p.getOrientation() = slerp; + } +} + } // namespace sofa::beamadapter From eefc535078fb04b14523226702469b30fc0d8a73 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 29 Jun 2023 17:40:00 +0200 Subject: [PATCH 25/60] Update WireRestShape to only use RodSectionMaterials --- .../component/engine/SteerableCatheter.h | 7 +- .../component/engine/WireRestShape.h | 26 +- .../component/engine/WireRestShape.inl | 355 +++--------------- 3 files changed, 57 insertions(+), 331 deletions(-) diff --git a/src/BeamAdapter/component/engine/SteerableCatheter.h b/src/BeamAdapter/component/engine/SteerableCatheter.h index 17ceebb98..27819a66a 100644 --- a/src/BeamAdapter/component/engine/SteerableCatheter.h +++ b/src/BeamAdapter/component/engine/SteerableCatheter.h @@ -104,9 +104,10 @@ class SteerableCatheter : public WireRestShape /// Bring inherited attributes and function in the current lookup context. /// otherwise any access to the base::attribute would require /// the "this->" approach. - using Inherit1::d_spireDiameter; - using Inherit1::d_length; - using Inherit1::d_straightLength; + Data d_length; + Data d_straightLength; + Data d_spireDiameter; + Data d_spireHeight; /////////////////////////////////////////////////////////////////////////// }; diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index da2ea7931..3ebd5ee67 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -85,11 +85,8 @@ class WireRestShape : public core::objectmodel::BaseObject virtual ~WireRestShape() = default; /////////////////////////// Inherited from BaseObject ////////////////////////////////////////// - void parse(core::objectmodel::BaseObjectDescription* arg) override; void init() override ; - void draw(const core::visual::VisualParams * vparams) override ; - /////////////////////////// Methods of WireRestShape ////////////////////////////////////////// @@ -116,8 +113,6 @@ class WireRestShape : public core::objectmodel::BaseObject /// Functions enabling to load and use a geometry given from OBJ external file - void initRestConfig(); - void getRestPosNonProcedural(Real& abs, Coord &p); void computeOrientation(const Vec3& AB, const Quat& Q, Quat &result); @@ -128,11 +123,7 @@ class WireRestShape : public core::objectmodel::BaseObject void releaseWirePart() { msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; - } - - void rotateFrameForAlignX(const Quat &input, Vec3 &x, Quat &output); - - void getRodSectionMaterial(const Real& x_curv); + } protected: /// Internal method to init Lengths vector @sa d_keyPoints if not set using @sa d_length and @sa d_straightLength. Returns false if init can't be performed. @@ -142,13 +133,6 @@ class WireRestShape : public core::objectmodel::BaseObject public: - /// Analitical creation of wire shape... - Data d_isAProceduralShape; - Data d_nonProceduralScale; - Data d_length; - Data d_straightLength; - Data d_spireDiameter; - Data d_spireHeight; Data > d_density; Data > d_keyPoints; @@ -158,13 +142,7 @@ class WireRestShape : public core::objectmodel::BaseObject /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. MultiLink, BaseRodSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; -private: - /// Data required for the File loading - type::vector m_localRestPositions; - type::vector m_localRestTransforms; - type::vector m_curvAbs ; - double m_absOfGeometry {0}; - +private: /// Link to be set to the topology container in the component graph. SingleLink, TopologyContainer, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; /// Pointer to the topology container, should be set using @sa l_topology, otherwise will search for one in current Node. diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index d6184ff37..460dc3d34 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -56,71 +56,16 @@ using sofa::core::objectmodel::BaseContext ; * @brief Default Constructor. */ template -WireRestShape::WireRestShape() : - //TODO(dmarchal 2017-05-17) not sure that procedural & nonProceduralScale are very understandable name...are they exclusives ? - //if so have look in my comment in the init section. - d_isAProceduralShape( initData(&d_isAProceduralShape,(bool)true,"isAProceduralShape","is the guidewire shape mathemetically defined ?") ) - , d_nonProceduralScale( initData ( &d_nonProceduralScale, (Real)1.0, "nonProceduralScale", "scale of the model defined by file" ) ) - , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) - , d_straightLength(initData(&d_straightLength, (Real)0.0, "straightLength", "length of the initial straight shape")) - , d_spireDiameter(initData(&d_spireDiameter, (Real)0.1, "spireDiameter", "diameter of the spire")) - , d_spireHeight(initData(&d_spireHeight, (Real)0.01, "spireHeight", "height between each spire")) - , d_density(initData(&d_density, "densityOfBeams", "density of beams between key points")) - , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) - , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) - , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) - , l_topology(initLink("topology", "link to the topology container")) +WireRestShape::WireRestShape() + : d_density(initData(&d_density, "densityOfBeams", "density of beams between key points")) + , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) + , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) + , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) + , l_topology(initLink("topology", "link to the topology container")) { - d_spireDiameter.setGroup("Procedural"); - d_spireHeight.setGroup("Procedural"); -} - -template -void WireRestShape::rotateFrameForAlignX(const Quat &input, Vec3 &x, Quat &output) -{ - x.normalize(); - Vec3 x0=input.inverseRotate(x); - Real cTheta=x0[0]; - Real theta; - if (cTheta>(1-EPSILON)) - { - output = input; - } - else - { - theta=acos(cTheta); - // axis of rotation - Vec3 dw(0,-x0[2],x0[1]); - dw.normalize(); - - // computation of the rotation - Quat inputRoutput; - inputRoutput.axisToQuat(dw, theta); - - output=input*inputRoutput; - } } -template -void WireRestShape::parse(core::objectmodel::BaseObjectDescription* args) -{ - const char* arg = args->getAttribute("procedural") ; - if(arg) - { - msg_warning() << "The attribute 'procedural' has been renamed into 'isAProceduralShape'. " << msgendl - << "To remove this warning you need to update your scene and replace 'procedural' with 'isAProceduralShape'" ; - - /// As arg is owned by the "procedural" attribute it cannot be removed before - /// being copied in the "isAProceduralShape". So please keep the ordering of the - /// two following functions. - args->setAttribute("isAProceduralShape", arg) ; - args->removeAttribute("procedural") ; - - } - - Inherit1::parse(args) ; -} template void WireRestShape::init() @@ -187,34 +132,16 @@ bool WireRestShape::initLengths() auto keyPointList = sofa::helper::getWriteOnlyAccessor(d_keyPoints); auto densityList = sofa::helper::getWriteOnlyAccessor(d_density); - // In case use used length and straightLenght instead of keyPointList, create keyPointList - if (keyPointList.empty()) - { - keyPointList.push_back(0.0); - if (d_straightLength.getValue() >= 0.001 * this->d_length.getValue() && d_straightLength.getValue() <= 0.999 * d_length.getValue()) - keyPointList.push_back(d_straightLength.getValue()); - keyPointList.push_back(d_length.getValue()); - } - - // checking sizes between keypointList and number of input material - if (l_sectionMaterials.size() != keyPointList.size() - 1) - { - msg_error() << "Wrong number of inputs. Component can't be init. Number of input materials: " << l_sectionMaterials.size() << ", should be equal to keyPointList.size()-1. keyPointList.size() is equal to: " << keyPointList.size(); - return false; - } + keyPointList.resize(l_sectionMaterials.size() + 1); + keyPointList[0] = Real(0.0); - if (densityList.size() != keyPointList.size() - 1) + densityList.resize(l_sectionMaterials.size()); + + for (unsigned int i = 0; i < l_sectionMaterials.size(); ++i) { - msg_warning() << "Wrong number of densityOfBeams. Given: " << densityList.size() << ", should be equal to keyPointList.size()-1: '" << keyPointList.size() - << "'. densityOfBeams will be recomputed using Wire material number of collision edges."; - densityList.clear(); - - for (unsigned int i = 0; i < keyPointList.size() - 1; ++i) - { - auto mat = l_sectionMaterials.get(i); - int nbrCollEdges = mat->getNbCollisionEdges(); - densityList.push_back(nbrCollEdges); - } + auto rodSection = l_sectionMaterials.get(i); + keyPointList[i+1] = keyPointList[i] + rodSection->getLength(); + densityList[i] = rodSection->getNbCollisionEdges(); } return true; @@ -272,16 +199,20 @@ void WireRestShape::getSamplingParameters(type::vector& xP_noti nbP_density = d_density.getValue(); } + template void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv) { unsigned int numLines; Real x_used = x_curv - EPSILON; - if(x_used>d_length.getValue()) - x_used=d_length.getValue(); - if(x_used<0.0) - x_used=0.0; + const Real totalLength = this->getLength(); + if (x_used > totalLength) { + x_used = totalLength; + } + else if (x_used < 0.0) { + x_used = 0.0; + } const type::vector& keyPts = d_keyPoints.getValue(); @@ -292,7 +223,7 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv << " != size of keyPoints-1 " << keyPts.size()-1 << ". Returning default values."; numLines = 20; - dx = d_length.getValue() / numLines; + dx = totalLength / numLines; return; } @@ -311,7 +242,7 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv // If x_used is out of bounds. Warn user and returns default value. numLines = 20; - dx = d_length.getValue() / numLines; + dx = totalLength / numLines; msg_error() << " problem is getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); } @@ -321,59 +252,24 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co { Real x_used = x - EPSILON; - if(x_used>d_length.getValue()) - x_used=d_length.getValue(); - - if(x_used<0.0) - x_used=0.0; - - if( x_used < d_straightLength.getValue()) - { - global_H_local.set(Vec3(x_used, 0.0, 0.0 ), Quat()); - return; + const Real totalLength = this->getLength(); + if (x_used > totalLength) { + x_used = totalLength; } - - if(d_isAProceduralShape.getValue()) - { - Real projetedLength = d_spireDiameter.getValue()*M_PI; - Real lengthSpire=sqrt(d_spireHeight.getValue()*d_spireHeight.getValue() + projetedLength*projetedLength ); - // angle in the z direction - Real phi= atan(d_spireHeight.getValue()/projetedLength); - - Quat Qphi; - Qphi.axisToQuat(Vec3(0,0,1),phi); - - // spire angle (if theta=2*PI, there is a complete spire between startx and x_used) - Real lengthCurve= x_used-d_straightLength.getValue(); - Real numSpire=lengthCurve/lengthSpire; - Real theta= 2*M_PI*numSpire; - - // computation of the Quat - Quat Qtheta; - Qtheta.axisToQuat(Vec3(0,1,0),theta); - Quat newSpireQuat = Qtheta*Qphi; - - - // computation of the position - Real radius=d_spireDiameter.getValue()/2.0; - Vec3 PosEndCurve(radius*sin(theta), numSpire*d_spireHeight.getValue(), radius*(cos(theta)-1) ); - Vec3 SpirePos=PosEndCurve + Vec3(d_straightLength.getValue(),0,0); - - global_H_local.set(SpirePos,newSpireQuat); + else if (x_used < 0.0) { + x_used = 0.0; } - else + + const type::vector& keyPts = d_keyPoints.getValue(); + for (auto i = 1; i < keyPts.size(); ++i) { - x_used = x_used - d_straightLength.getValue(); - x_used = x_used/(d_length.getValue()-d_straightLength.getValue()) * m_absOfGeometry; - - Coord p; - this->getRestPosNonProcedural(x_used,p); - Vec3 PosEndCurve = p.getCenter(); - Quat ExtremityQuat = p.getOrientation(); - Vec3 ExtremityPos = PosEndCurve + Vec3(d_straightLength.getValue(),0,0); - - global_H_local.set(ExtremityPos,ExtremityQuat); + if (x_used <= keyPts[i]) + { + return l_sectionMaterials.get(i - 1)->getRestTransformOnX(global_H_local, x_used, keyPts[i - 1]); + } } + + msg_warning() << "You should not be still here"; } @@ -399,159 +295,29 @@ void WireRestShape::getYoungModulusAtX(const Real& x_curv, Real& youn template void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_rho, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &_J) const { - BaseRodSectionMaterial* wireSection = nullptr; - //getRodSectionMaterial(x_curv); - if (wireSection) - wireSection->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); - else - msg_error() << " problem in getInterpolationParam : x_curv " << x_curv << " is not between keyPoints"; -} - -template -void WireRestShape::getRodSectionMaterial(const Real& x_curv) -{ - //const Real x_used = x_curv - Real(EPSILON); - //const type::vector& keyPts = d_keyPoints.getValue(); - - //// Check in which section x_used belongs to and get access to this section material - //for (auto i = 1; i < keyPts.size(); ++i) - //{ - // if (x_used <= keyPts[i]) - // { - // return l_sectionMaterials.get(i - 1); - // } - //} - - //return nullptr; -} - -//template -//bool WireRestShape::fillTopology() -//{ -// if (!_topology) -// { -// msg_error() << "Topology is null"; -// return false; -// } -// -// const auto length = this->d_length.getValue(); -// if (length <= Real(0.0)) -// { -// msg_error() << "Length is 0 (or negative), check if d_length has been given or computed."; -// return false; -// } -// -// int nbrEdges = d_numEdges.getValue(); -// if (nbrEdges <= 0) -// { -// msg_warning() << "Number of edges has been set to an invalid value: " << nbrEdges << ". Value should be a positive integer. Setting to default value: 10"; -// nbrEdges = 10; -// } -// -// /// fill topology : -// _topology->clear(); -// _topology->cleanup(); -// -// Real dx = this->d_length.getValue() / nbrEdges; -// -// /// add points -// for (int i = 0; i < d_numEdges.getValue() + 1; i++) -// _topology->addPoint(i * dx, 0, 0); -// -// /// add segments -// for (int i = 0; i < d_numEdges.getValue(); i++) -// _topology->addEdge(i, i + 1); -// -// return true; -//} - + const Real x_used = x_curv - Real(EPSILON); + const type::vector& keyPts = d_keyPoints.getValue(); -template -void WireRestShape::initRestConfig() -{ - m_curvAbs.clear(); - double tot = 0; - m_curvAbs.push_back(0); - Quat input, output; - input.identity(); - m_localRestTransforms.resize(m_localRestPositions.size()); - m_localRestTransforms[0].setOrigin(Vec3(0,0,0)); - m_localRestTransforms[0].setOrientation(input); - - for(unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) + // Check in which section x_used belongs to and get access to this section material + for (auto i = 1; i < keyPts.size(); ++i) { - Vec3 vec = m_localRestPositions[i+1] - m_localRestPositions[i]; - double norm = vec.norm(); - tot += norm; - - this->rotateFrameForAlignX(input, vec, output); - - input = output; - - m_localRestTransforms[i+1].setOrientation(output); - - Vec3 localPos = m_localRestPositions[i+1] - m_localRestPositions[0]; - - m_localRestTransforms[i+1].setOrigin(localPos); - - m_curvAbs.push_back(tot); + if (x_used <= keyPts[i]) + { + return l_sectionMaterials.get(i - 1)->getInterpolationParam(_rho, _A, _Iy, _Iz, _Asy, _Asz, _J); + } } - m_absOfGeometry = tot; - - Real newLength = d_straightLength.getValue() + m_absOfGeometry; - d_length.setValue(newLength); - msg_info() <<"Length of the loaded shape = "<< m_absOfGeometry << ", total length with straight length = " << newLength ; + msg_error() << " problem in getInterpolationParam : x_curv " << x_curv << " is not between keyPoints" << keyPts; } -template -void WireRestShape::getRestPosNonProcedural(Real& abs, Coord &p) -{ - /*** find the range which includes the "requested" abs ***/ - double startingAbs = 0; unsigned int index = 0; - - while ((startingAbs < abs) && (index < m_localRestPositions.size())) - { - index++; - startingAbs = m_curvAbs[index]; - } - - /*** OOB ***/ - if(abs > startingAbs) - { - msg_error() << "abs = "< typename WireRestShape::Real WireRestShape::getLength() { - if(d_brokenIn2.getValue()) - return d_straightLength.getValue(); - else - return d_length.getValue(); + return d_keyPoints.getValue().back(); } + template void WireRestShape::getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) { @@ -560,9 +326,10 @@ void WireRestShape::getNumberOfCollisionSegment(Real &dx, unsigned in { numLines += l_sectionMaterials.get(i)->getNbCollisionEdges(); } - dx = d_length.getValue() / numLines; + dx = getLength() / numLines; } + template void WireRestShape::computeOrientation(const Vec3& AB, const Quat& Q, Quat &result) { @@ -595,26 +362,6 @@ void WireRestShape::computeOrientation(const Vec3& AB, const Quat& Q, } -template -void WireRestShape::draw(const core::visual::VisualParams* vparams) -{ - if (!d_drawRestShape.getValue()) - return; - - vparams->drawTool()->saveLastState(); - vparams->drawTool()->setLightingEnabled(false); - - std::vector< sofa::type::Vec3 > points; - points.reserve(m_localRestPositions.size()); - - for (unsigned int i = 0; i < m_localRestPositions.size(); i++) - { - points.emplace_back(m_localRestPositions[i][0], m_localRestPositions[i][1], m_localRestPositions[i][2]); - } - - vparams->drawTool()->drawPoints(points, 10, sofa::type::RGBAColor(1, 0.5, 0.5, 1)); - vparams->drawTool()->restoreLastState(); -} } // namespace _wirerestshape_ using _wirerestshape_::WireRestShape; From e267534fc129f10cc2fda0a94136dfa34c31847d Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Jun 2023 13:18:04 +0200 Subject: [PATCH 26/60] Clean and doc Rod section classes and WireRestShape --- .../component/engine/WireRestShape.h | 36 ++-- .../component/engine/WireRestShape.inl | 15 +- .../component/model/BaseRodSectionMaterial.h | 72 ++++--- .../model/BaseRodSectionMaterial.inl | 47 ++--- .../component/model/RodMeshSection.h | 37 ++-- .../component/model/RodMeshSection.inl | 188 +++++++++--------- .../component/model/RodSpireSection.h | 19 +- .../component/model/RodSpireSection.inl | 22 +- .../component/model/RodStraightSection.h | 9 +- .../component/model/RodStraightSection.inl | 22 +- 10 files changed, 246 insertions(+), 221 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 3ebd5ee67..2ab349ce9 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -33,7 +33,6 @@ #include -#include #include #include @@ -57,8 +56,9 @@ using namespace sofa::beamadapter; * \class WireRestShape * \brief Describe the shape functions on multiple segments * - * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) - * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + * Describe the full shape of a Wire with a given set of @sa BaseRodSectionMaterial. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) + * @sa d_keyPoints and @d_density are computed by method @sa initLengths using the set of rod sections description. + * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. */ template class WireRestShape : public core::objectmodel::BaseObject @@ -72,8 +72,6 @@ class WireRestShape : public core::objectmodel::BaseObject using Vec3 = sofa::type::Vec<3, Real>; using Quat = sofa::type::Quat; - using BeamSection = sofa::beamadapter::BeamSection; - /** * @brief Default Constructor. */ @@ -88,13 +86,7 @@ class WireRestShape : public core::objectmodel::BaseObject void init() override ; - /////////////////////////// Methods of WireRestShape ////////////////////////////////////////// - - /// For coils: a part of the coil instrument can be brokenIn2 (by default the point of release is the end of the straight length) - Real getReleaseCurvAbs() const { - msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; - return 0.0; - } + /////////////////////////// Methods of WireRestShape ////////////////////////////////////////// /// This function is called by the force field to evaluate the rest position of each beam void getRestTransformOnX(Transform &global_H_local, const Real &x); @@ -115,19 +107,28 @@ class WireRestShape : public core::objectmodel::BaseObject /// Functions enabling to load and use a geometry given from OBJ external file void computeOrientation(const Vec3& AB, const Quat& Q, Quat &result); - - //[[nodiscard]] bool fillTopology(); + Real getLength() ; void getCollisionSampling(Real &dx, const Real &x_curv); void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) ; + + + /////////////////////////// Deprecated Methods ////////////////////////////////////////// + + /// For coils: a part of the coil instrument can be brokenIn2 (by default the point of release is the end of the straight length) + Real getReleaseCurvAbs() const { + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + return 0.0; + } + void releaseWirePart() { msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; } protected: - /// Internal method to init Lengths vector @sa d_keyPoints if not set using @sa d_length and @sa d_straightLength. Returns false if init can't be performed. - bool initLengths(); + /// Internal method to init Lengths vector @sa d_keyPoints using the length of each materials @sa l_sectionMaterials. + void initLengths(); /// Internal method to init Edge Topology @sa _topology using the list of materials @sa l_sectionMaterials. Returns false if init can't be performed. bool initTopology(); @@ -135,9 +136,6 @@ class WireRestShape : public core::objectmodel::BaseObject public: Data > d_density; Data > d_keyPoints; - - /// broken in 2 case - Data d_drawRestShape; /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. MultiLink, BaseRodSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterials; diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 460dc3d34..1ae3484e6 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -59,7 +59,6 @@ template WireRestShape::WireRestShape() : d_density(initData(&d_density, "densityOfBeams", "density of beams between key points")) , d_keyPoints(initData(&d_keyPoints,"keyPoints","key points of the shape (curv absc)")) - , d_drawRestShape(initData(&d_drawRestShape, (bool)false, "draw", "draw rest shape")) , l_sectionMaterials(initLink("wireMaterials", "link to Wire Section Materials (to be ordered according to the instrument, from handle to tip)")) , l_topology(initLink("topology", "link to the topology container")) { @@ -106,11 +105,7 @@ void WireRestShape::init() ////////// keyPoint list and Density Assignement /////// //////////////////////////////////////////////////////// - if (!initLengths()) - { - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; - } + initLengths(); // Get pointer to the topology Modifier (for topological changes) _topology->getContext()->get(edgeMod); @@ -127,7 +122,7 @@ void WireRestShape::init() template -bool WireRestShape::initLengths() +void WireRestShape::initLengths() { auto keyPointList = sofa::helper::getWriteOnlyAccessor(d_keyPoints); auto densityList = sofa::helper::getWriteOnlyAccessor(d_density); @@ -143,8 +138,6 @@ bool WireRestShape::initLengths() keyPointList[i+1] = keyPointList[i] + rodSection->getLength(); densityList[i] = rodSection->getNbCollisionEdges(); } - - return true; } @@ -243,7 +236,7 @@ void WireRestShape::getCollisionSampling(Real &dx, const Real &x_curv // If x_used is out of bounds. Warn user and returns default value. numLines = 20; dx = totalLength / numLines; - msg_error() << " problem is getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); + msg_error() << " problem in getCollisionSampling : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); } @@ -269,7 +262,7 @@ void WireRestShape::getRestTransformOnX(Transform &global_H_local, co } } - msg_warning() << "You should not be still here"; + msg_error() << " problem in getRestTransformOnX : x_curv " << x_used << " is not between keyPoints" << d_keyPoints.getValue(); } diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.h b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h index d66682afe..d023b6a69 100644 --- a/src/BeamAdapter/component/model/BaseRodSectionMaterial.h +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.h @@ -34,11 +34,18 @@ namespace sofa::beamadapter using sofa::core::loader::MeshLoader; /** - * \class WireRestShape - * \brief Describe the shape functions on multiple segments + * \class BaseRodSectionMaterial + * \brief Base class describing a Rod section which will define a set of beam elements. * - * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) - * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + * This class provide an api to define a rod/wire section using physical and geometry parameters. + * The section will then be modellized by a set of beam elements. Inheriting class should provide the geometry structure: + * @sa RodMeshSection to define a rod using a mesh file, @sa RodSpireSection or @sa RodStraightSection to define procedural shapes. + * Method @sa initSection and @sa getRestTransformOnX should be overriden to provide the correct creation and interpolation. + * + * The rod section is described by: + * - Topology parameters: vertices and edges @sa d_nbEdgesVisu and @sa d_nbEdgesCollis + * - Geometry parameters: radius @sa d_radius, @sa d_innerRadius and length @sa d_length + * - Mechanical parameters: @sa d_poissonRatio and @sa d_youngModulus */ template class BaseRodSectionMaterial : public core::objectmodel::BaseObject @@ -51,51 +58,62 @@ class BaseRodSectionMaterial : public core::objectmodel::BaseObject using Transform = typename sofa::defaulttype::SolidTypes::Transform; using Vec3 = sofa::type::Vec<3, Real>; using Quat = sofa::type::Quat; + using Size = sofa::Size; + + /////////////////////////// Inherited from BaseObject ////////////////////////////////////////// /// Default Constructor BaseRodSectionMaterial(); + /// init method from BaseObject API. Will call internal @see initSection to be overriden by children void init() override; - /// This function gives the Young modulus and Poisson's coefficient of the beam depending on the beam position + + /////////////////////////// Geometry and physics Getter ////////////////////////////////////////// + + /// Returns the number of visual edges of this section. To be set or computed by child. + [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } + + /// Returns the number of collision edges of this section. To be set or computed by child. + [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } + + /// Returns the total length of this section. To be set or computed by child. + [[nodiscard]] Real getLength() const { return d_length.getValue(); } + + /// Returns the Young modulus and Poisson's coefficient of this section void getYoungModulusAtX(Real& youngModulus, Real& cPoisson) const; - /// This function gives the mass density and the BeamSection data depending on the beam position + /// Returns the mass density and the BeamSection of this section void getInterpolationParam(Real& _rho, Real& _A, Real& _Iy, Real& _Iz, Real& _Asy, Real& _Asz, Real& _J) const; - /// This function is called by the force field to evaluate the rest position of each beam + + + /// This function is called to get the rest position of the beam depending on the current curved abscisse given in parameter virtual void getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) { SOFA_UNUSED(global_H_local); SOFA_UNUSED(x_used); SOFA_UNUSED(x_start); } - - [[nodiscard]] int getNbVisualEdges() const { return d_nbEdgesVisu.getValue(); } - - [[nodiscard]] int getNbCollisionEdges() const { return d_nbEdgesCollis.getValue(); } - - [[nodiscard]] Real getLength() const { return d_length.getValue(); } - + protected: - virtual void initSection() {} + /// Internal method to init the section. to be overidden by child. + virtual bool initSection() { return false; } public: - /// User Data about the Young modulus - Data d_poissonRatio; - Data d_youngModulus; - - /// Radius - Data d_radius; - Data d_innerRadius; - Data d_massDensity; - - Data d_length; + Data d_poissonRatio; ///< Data defining the mehcanical Poisson ratio of this section + Data d_youngModulus; ///< Data defining the mehcanical Young Modulus of this section + Data d_massDensity; ///< Data defining the mehcanical mass density of this section + + Data d_radius; ///< Data defining the geometry radius of this section + Data d_innerRadius; ///< Data defining the geometry internal radius of this section is hollow + Data d_length; ///< Data defining the geometry length of this section - Data< int > d_nbEdgesVisu; - Data< int > d_nbEdgesCollis; + Data d_nbEdgesVisu; ///< Data defining the number of visual edges composing this section + Data d_nbEdgesCollis; ///< Data defining the number of collision edges composing this section private: + /// Internal structure to store physical parameter of the a beam section BeamSection beamSection; }; diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl index 0464da6e3..ffef90e69 100644 --- a/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl +++ b/src/BeamAdapter/component/model/BaseRodSectionMaterial.inl @@ -22,21 +22,20 @@ #pragma once #include -#include namespace sofa::beamadapter { template BaseRodSectionMaterial::BaseRodSectionMaterial() - : d_poissonRatio(initData(&d_poissonRatio, (Real)0.49, "poissonRatio", "Poisson Ratio")) - , d_youngModulus(initData(&d_youngModulus, (Real)5000, "youngModulus", "Young Modulus")) - , d_radius(initData(&d_radius, (Real)1.0, "radius", "radius")) - , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "inner radius if it applies")) + : d_poissonRatio(initData(&d_poissonRatio, (Real)0.49, "poissonRatio", "Poisson Ratio of this section")) + , d_youngModulus(initData(&d_youngModulus, (Real)5000, "youngModulus", "Young Modulus of this section")) , d_massDensity(initData(&d_massDensity, (Real)1.0, "massDensity", "Density of the mass (usually in kg/m^3)")) - , d_length(initData(&d_length, (Real)1.0, "length", "total length of the wire instrument")) - , d_nbEdgesVisu(initData(&d_nbEdgesVisu, 10, "nbEdgesVisu", "number of Edges for the visual model")) - , d_nbEdgesCollis(initData(&d_nbEdgesCollis, 20, "nbEdgesCollis", "number of Edges for the collision model")) + , d_radius(initData(&d_radius, (Real)1.0, "radius", "Full radius of this section")) + , d_innerRadius(initData(&d_innerRadius, (Real)0.0, "innerRadius", "Inner radius of this section if hollow")) + , d_length(initData(&d_length, (Real)1.0, "length", "Total length of this section")) + , d_nbEdgesVisu(initData(&d_nbEdgesVisu, (Size)10, "nbEdgesVisu", "number of Edges for the visual model")) + , d_nbEdgesCollis(initData(&d_nbEdgesCollis, (Size)20, "nbEdgesCollis", "number of Edges for the collision model")) { } @@ -59,31 +58,13 @@ void BaseRodSectionMaterial::init() this->beamSection._Asy = 0.0; this->beamSection._Asz = 0.0; - initSection(); + // call delegate method to init the section + bool res = initSection(); - //if (!l_loader.empty()) - //{ - // // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. - // loader = l_loader.get(); - // initFromLoader(); - //} - //else - //{ - // if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) - // { - // msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; - // d_nbEdgesVisu.setValue(10); - // } - - - // if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) - // { - // msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; - // d_nbEdgesCollis.setValue(10); - // } - //} - - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); + if (res) + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); + else + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); } @@ -112,6 +93,4 @@ void BaseRodSectionMaterial::getInterpolationParam(Real& _rho, Real& } } - - } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodMeshSection.h b/src/BeamAdapter/component/model/RodMeshSection.h index ba1f8554c..0c75b9c8e 100644 --- a/src/BeamAdapter/component/model/RodMeshSection.h +++ b/src/BeamAdapter/component/model/RodMeshSection.h @@ -31,11 +31,13 @@ namespace sofa::beamadapter using sofa::core::loader::MeshLoader; /** - * \class WireRestShape - * \brief Describe the shape functions on multiple segments + * \class RodMeshSection + * \brief Specialization class of @sa BaseRodSectionMaterial describing a rod section created using a Mesh file * - * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) - * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + * This class will describe a rod section defined by a mesh file structure using the link @sa l_loader + * Method @sa initFromLoader and @sa initRestConfig will define the beam structure using the geometry of the given mesh + * as well as the Length. Mechanical parameters are set using the @sa BaseRodSectionMaterial Data + * Method @sa getRestTransformOnX will return the current position of the curviline abscisse along the mesh structure. */ template class RodMeshSection : public sofa::beamadapter::BaseRodSectionMaterial @@ -43,23 +45,25 @@ class RodMeshSection : public sofa::beamadapter::BaseRodSectionMaterial; - /// Default Constructor RodMeshSection(); + /// Override method to get the rest position of the beam. In this implementation, it will interpolate along the loaded mesh geometry void getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) override; protected: - void initSection() override; - void initFromLoader(); + /// Internal method to init the section. Called by @sa BaseRodSectionMaterial::init() method + bool initSection() override; + + /// Internal method called by initSection to init from a linked MeshLoader @sa l_loader + bool initFromLoader(); + /// Internal method called by initFromLoader to compute @sa m_localRestPositions and @sa m_localRestTransforms given the mesh structure void initRestConfig(); + /// Method to check if the given loader has a edge set structure bool checkLoaderTopology(); + /// Tool method to rotate the input frame @param input given an axis @param x. Result is set in @param output void rotateFrameForAlignX(const Quat& input, Vec3& x, Quat& output); - void getRestPosNonProcedural(Real& abs, Coord& p); public: /// Link to be set to the topology container in the component graph. @@ -67,13 +71,12 @@ class RodMeshSection : public sofa::beamadapter::BaseRodSectionMaterial m_localRestPositions; - type::vector m_localRestTransforms; - type::vector m_curvAbs; - double m_absOfGeometry{ 0 }; + type::vector m_localRestPositions; ///< rest position of the key points interpolated on the mesh geometry + type::vector m_localRestTransforms; ///< rest transform of the key points interpolated on the mesh geometry + type::vector m_curvAbs; ///< set of absciss curviline points + Real m_absOfGeometry{ 0 }; ///< max curv absciss of this mesh structure }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_RODMESHSECTION_CPP) diff --git a/src/BeamAdapter/component/model/RodMeshSection.inl b/src/BeamAdapter/component/model/RodMeshSection.inl index f2dbe17ac..1867c195b 100644 --- a/src/BeamAdapter/component/model/RodMeshSection.inl +++ b/src/BeamAdapter/component/model/RodMeshSection.inl @@ -40,23 +40,23 @@ RodMeshSection::RodMeshSection() template -void RodMeshSection::initSection() +bool RodMeshSection::initSection() { // Get meshLoader, check first if loader has been set using link. Otherwise will search in current context. - loader = l_loader.get(); + p_loader = l_loader.get(); - if (!loader) - this->getContext()->get(loader); + if (!p_loader) + this->getContext()->get(p_loader); - if (!loader) { + if (!p_loader) { msg_error() << "Cannot find a mesh loader. Please insert a MeshObjLoader in the same node or use l_loader to specify the path in the scene graph."; this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; + return false; } else { - msg_info() << "Found a mesh with " << loader->d_edges.getValue().size() << " edges"; - initFromLoader(); + msg_info() << "Found a mesh with " << p_loader->d_edges.getValue().size() << " edges"; + return initFromLoader(); } } @@ -64,11 +64,38 @@ void RodMeshSection::initSection() template void RodMeshSection::getRestTransformOnX(Transform& global_H_local, const Real& x_used, const Real& x_start) { - Real x_local = x_used - x_start; - x_local = x_local /(d_length.getValue()) * m_absOfGeometry; + Real abs_curr = x_used - x_start; + abs_curr = abs_curr /(d_length.getValue()) * m_absOfGeometry; Coord p; - this->getRestPosNonProcedural(x_local, p); + + /*** find the range which includes the "requested" abs ***/ + Real startingAbs = 0; + unsigned int index = 0; + while ((startingAbs < abs_curr) && (index < m_localRestPositions.size())) + { + index++; + startingAbs = m_curvAbs[index]; + } + + /*** OOB ***/ + if (abs_curr > startingAbs) + { + msg_error() << "Out of bound position requested= " << abs_curr << " with startingAbs = " << startingAbs; + return; + } + else /*** Expected case ***/ + { + const Real alpha = (abs_curr - m_curvAbs[index - 1]) / (m_curvAbs[index] - m_curvAbs[index - 1]); + const Real one_minus_alpha = 1 - alpha; + const Vec3 result = m_localRestTransforms[index - 1].getOrigin() * one_minus_alpha + m_localRestTransforms[index].getOrigin() * alpha; + Quat slerp; + slerp.slerp(m_localRestTransforms[index - 1].getOrientation(), m_localRestTransforms[index].getOrientation(), alpha, true); + slerp.normalize(); + + p.getCenter() = result; + p.getOrientation() = slerp; + } Vec3 PosEndCurve = p.getCenter(); Quat ExtremityQuat = p.getOrientation(); @@ -79,22 +106,22 @@ void RodMeshSection::getRestTransformOnX(Transform& global_H_local, c template -void RodMeshSection::initFromLoader() +bool RodMeshSection::initFromLoader() { if (!checkLoaderTopology()) { this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; + return false; } type::vector vertices; sofa::core::topology::BaseMeshTopology::SeqEdges edges; //get the topology position - auto topoVertices = sofa::helper::getReadAccessor(loader->d_positions); + auto topoVertices = sofa::helper::getReadAccessor(p_loader->d_positions); //copy the topology edges in a local vector - auto topoEdges = sofa::helper::getReadAccessor(loader->d_edges); + auto topoEdges = sofa::helper::getReadAccessor(p_loader->d_edges); edges = topoEdges.ref(); /** renumber the vertices **/ @@ -125,7 +152,7 @@ void RodMeshSection::initFromLoader() { msg_error() << "The first vertex of the beam structure is not found, probably because of a closed structure"; this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; + return false; } vertices.push_back(topoVertices[firstIndex]); @@ -165,74 +192,15 @@ void RodMeshSection::initFromLoader() initRestConfig(); - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); -} - - -template -bool RodMeshSection::checkLoaderTopology() -{ - if (!loader->d_edges.getValue().size()) - { - msg_error() << "There is no edges in the topology loaded by " << loader->getName(); - return false; - } - - if (loader->d_triangles.getValue().size()) - { - msg_error() << "There are triangles in the topology loaded by " << loader->getName(); - return false; - } - - if (loader->d_quads.getValue().size()) - { - msg_error() << "There are quads in the topology loaded by " << loader->getName(); - return false; - } - - if (loader->d_polygons.getValue().size()) - { - msg_error() << "There are polygons in the topology loaded by " << loader->getName(); - return false; - } - return true; } -template -void RodMeshSection::rotateFrameForAlignX(const Quat& input, Vec3& x, Quat& output) -{ - x.normalize(); - Vec3 x0 = input.inverseRotate(x); - - Real cTheta = x0[0]; - Real theta; - if (cTheta > (1 - EPSILON)) - { - output = input; - } - else - { - theta = acos(cTheta); - // axis of rotation - Vec3 dw(0, -x0[2], x0[1]); - dw.normalize(); - - // computation of the rotation - Quat inputRoutput; - inputRoutput.axisToQuat(dw, theta); - - output = input * inputRoutput; - } -} - - template void RodMeshSection::initRestConfig() { m_curvAbs.clear(); - double tot = 0; + Real tot = 0; m_curvAbs.push_back(0); Quat input, output; input.identity(); @@ -243,7 +211,7 @@ void RodMeshSection::initRestConfig() for (unsigned int i = 0; i < m_localRestPositions.size() - 1; i++) { Vec3 vec = m_localRestPositions[i + 1] - m_localRestPositions[i]; - double norm = vec.norm(); + Real norm = vec.norm(); tot += norm; this->rotateFrameForAlignX(input, vec, output); @@ -267,42 +235,64 @@ void RodMeshSection::initRestConfig() template -void RodMeshSection::getRestPosNonProcedural(Real& abs, Coord& p) +bool RodMeshSection::checkLoaderTopology() { - /*** find the range which includes the "requested" abs ***/ - double startingAbs = 0; unsigned int index = 0; + if (!p_loader->d_edges.getValue().size()) + { + msg_error() << "There is no edges in the topology loaded by " << p_loader->getName(); + return false; + } - while ((startingAbs < abs) && (index < m_localRestPositions.size())) + if (p_loader->d_triangles.getValue().size()) { - index++; - startingAbs = m_curvAbs[index]; + msg_error() << "There are triangles in the topology loaded by " << p_loader->getName(); + return false; } - /*** OOB ***/ - if (abs > startingAbs) + if (p_loader->d_quads.getValue().size()) { - msg_error() << "abs = " << abs << " et startingAbs = " << startingAbs << msgendl - << "Out of bound position request"; - return; + msg_error() << "There are quads in the topology loaded by " << p_loader->getName(); + return false; } - else /*** Expected case ***/ + + if (p_loader->d_polygons.getValue().size()) { - Real alpha, one_minus_alpha; - Vec3 result; + msg_error() << "There are polygons in the topology loaded by " << p_loader->getName(); + return false; + } - alpha = (abs - m_curvAbs[index - 1]) / (m_curvAbs[index] - m_curvAbs[index - 1]); - one_minus_alpha = 1 - alpha; - result = m_localRestTransforms[index - 1].getOrigin() * one_minus_alpha + m_localRestTransforms[index].getOrigin() * alpha; - Quat slerp; - slerp.slerp(m_localRestTransforms[index - 1].getOrientation(), m_localRestTransforms[index].getOrientation(), alpha, true); + return true; +} - slerp.normalize(); - p.getCenter() = result; +template +void RodMeshSection::rotateFrameForAlignX(const Quat& input, Vec3& x, Quat& output) +{ + x.normalize(); + Vec3 x0 = input.inverseRotate(x); - p.getOrientation() = slerp; + Real cTheta = x0[0]; + Real theta; + if (cTheta > (1 - EPSILON)) + { + output = input; + } + else + { + theta = acos(cTheta); + // axis of rotation + Vec3 dw(0, -x0[2], x0[1]); + dw.normalize(); + + // computation of the rotation + Quat inputRoutput; + inputRoutput.axisToQuat(dw, theta); + + output = input * inputRoutput; } } + + } // namespace sofa::beamadapter diff --git a/src/BeamAdapter/component/model/RodSpireSection.h b/src/BeamAdapter/component/model/RodSpireSection.h index ca1000cf2..91a793d88 100644 --- a/src/BeamAdapter/component/model/RodSpireSection.h +++ b/src/BeamAdapter/component/model/RodSpireSection.h @@ -30,11 +30,12 @@ namespace sofa::beamadapter using sofa::core::loader::MeshLoader; /** - * \class WireRestShape - * \brief Describe the shape functions on multiple segments + * \class RodSpireSection + * \brief Specialization class of @sa BaseRodSectionMaterial describing a rod spire section. * - * Describe the full shape of a Wire with a given length and radius. The wire is discretized by a set of beams (given by the keyPoints and the relatives Beam density) - * This component compute the beam discretization and the shape functions on multiple segments using curvilinear abscissa. + * This class will describe a rod spire section using spire diameter and height between each spire. Length and mechanical + * parameters are the same as @sa BaseRodSectionMaterial Data + * Method @sa getRestTransformOnX will return the current position of the curviline abscisse along the spire. */ template class RodSpireSection : public sofa::beamadapter::BaseRodSectionMaterial @@ -45,16 +46,16 @@ class RodSpireSection : public sofa::beamadapter::BaseRodSectionMaterial d_spireDiameter; - Data d_spireHeight; - -private: + Data d_spireDiameter; ///< Data defining the diameter of the spire + Data d_spireHeight; ///< Data defining the height between each spire }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_RODSPIRESECTION_CPP) diff --git a/src/BeamAdapter/component/model/RodSpireSection.inl b/src/BeamAdapter/component/model/RodSpireSection.inl index b155a1498..cb9ff3230 100644 --- a/src/BeamAdapter/component/model/RodSpireSection.inl +++ b/src/BeamAdapter/component/model/RodSpireSection.inl @@ -39,9 +39,29 @@ RodSpireSection::RodSpireSection() template -void RodSpireSection::initSection() +bool RodSpireSection::initSection() { + const auto length = this->d_length.getValue(); + if (length <= Real(0.0)) + { + msg_error() << "Length is 0 (or negative), check if d_length has been given or well computed."; + return false; + } + if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + { + msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + d_nbEdgesVisu.setValue(10); + } + + + if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + { + msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + d_nbEdgesCollis.setValue(10); + } + + return true; } diff --git a/src/BeamAdapter/component/model/RodStraightSection.h b/src/BeamAdapter/component/model/RodStraightSection.h index afc49e478..629c946fb 100644 --- a/src/BeamAdapter/component/model/RodStraightSection.h +++ b/src/BeamAdapter/component/model/RodStraightSection.h @@ -29,9 +29,10 @@ namespace sofa::beamadapter /** * \class RodStraightSection - * \brief Describe a rod straight section + * \brief Specialization class of @sa BaseRodSectionMaterial describing a rod straight section. * - * + * This class will describe a rod straight section which will parametrized only using the @sa BaseRodSectionMaterial Data + * Method @sa getRestTransformOnX will return: Vec3(current_x, 0 0) */ template class RodStraightSection : public sofa::beamadapter::BaseRodSectionMaterial @@ -42,10 +43,12 @@ class RodStraightSection : public sofa::beamadapter::BaseRodSectionMaterial::RodStraightSection() template -void RodStraightSection::initSection() +bool RodStraightSection::initSection() { + const auto length = this->d_length.getValue(); + if (length <= Real(0.0)) + { + msg_error() << "Length is 0 (or negative), check if d_length has been given or well computed."; + return false; + } + if (int nbrEdgesVisu = d_nbEdgesVisu.getValue() <= 0) + { + msg_warning() << "Number of visual edges has been set to an invalid value: " << nbrEdgesVisu << ". Value should be a positive integer. Setting to default value: 10"; + d_nbEdgesVisu.setValue(10); + } + + + if (int nbEdgesCollis = d_nbEdgesCollis.getValue() <= 0) + { + msg_warning() << "Number of collision edges has been set to an invalid value: " << nbEdgesCollis << ". Value should be a positive integer. Setting to default value: 20"; + d_nbEdgesCollis.setValue(10); + } + + return true; } From 5a16d1f97900316ffc02a7ab8c5eb303964f267d Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Jun 2023 13:18:41 +0200 Subject: [PATCH 27/60] Remove BaseRodSectionMaterial.cpp --- CMakeLists.txt | 1 - .../model/BaseRodSectionMaterial.cpp | 39 ------------------- 2 files changed, 40 deletions(-) delete mode 100644 src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c7705ef9f..2ecb75afd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,6 @@ set(SOURCE_FILES ${BEAMADAPTER_SRC}/component/mapping/BeamLengthMapping.cpp ${BEAMADAPTER_SRC}/component/mapping/MultiAdaptiveBeamMapping.cpp - ${BEAMADAPTER_SRC}/component/model/BaseRodSectionMaterial.cpp ${BEAMADAPTER_SRC}/component/model/RodMeshSection.cpp ${BEAMADAPTER_SRC}/component/model/RodSpireSection.cpp ${BEAMADAPTER_SRC}/component/model/RodStraightSection.cpp diff --git a/src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp b/src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp deleted file mode 100644 index 450681d63..000000000 --- a/src/BeamAdapter/component/model/BaseRodSectionMaterial.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** -* BeamAdapter plugin * -* (c) 2006 Inria, University of Lille, CNRS * -* * -* 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 . * -******************************************************************************* -* Authors: see Authors.md * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#define SOFA_PLUGIN_BEAMADAPTER_BASERODSECTIONMATERIAL_CPP - -#include -#include -#include -#include - -namespace sofa::beamadapter -{ - -using namespace sofa::defaulttype; - -//const int BaseRodSectionMaterialClass = core::RegisterObject("Wire Section Material.") -//.add< BaseRodSectionMaterial >(true); -// -//template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; - -}// namespace sofa::beamadapter From 93fd33fc74248298f4b9e7e8a3ed6e1bc6e85bf3 Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Jun 2023 13:30:19 +0200 Subject: [PATCH 28/60] Forgot to update cudaInstantiations --- src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp index fb5d3a1c8..94079918e 100644 --- a/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp +++ b/src/BeamAdapter/gpu/cuda/CudaInstantiations.cpp @@ -91,9 +91,14 @@ namespace sofa::component::mapping namespace sofa::beamadapter { - template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; + template class SOFA_BEAMADAPTER_API RodMeshSection; + template class SOFA_BEAMADAPTER_API RodSpireSection; + template class SOFA_BEAMADAPTER_API RodStraightSection; + #ifdef SOFA_GPU_CUDA_DOUBLE - template class SOFA_BEAMADAPTER_API BaseRodSectionMaterial; + template class SOFA_BEAMADAPTER_API RodMeshSection; + template class SOFA_BEAMADAPTER_API RodSpireSection; + template class SOFA_BEAMADAPTER_API RodStraightSection; #endif } // namespace sofa::beamadapter From 5c1be5ea433012780262a07ccd663cf66596b5a7 Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Jun 2023 14:59:09 +0200 Subject: [PATCH 29/60] Update all scenes with new rod section components --- examples/3instruments.scn | 23 +++++++++++++++------- examples/3instruments_collis.scn | 21 ++++++++++++++------ examples/SingleBeamDeployment.scn | 10 ++++------ examples/SingleBeamDeploymentCollision.scn | 10 +++++----- examples/Tool_from_loader.scn | 11 ++++++----- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/examples/3instruments.scn b/examples/3instruments.scn index 2e1843149..8d876cdad 100644 --- a/examples/3instruments.scn +++ b/examples/3instruments.scn @@ -24,25 +24,34 @@ - + + + + + - + + + + + - - + + + + + + diff --git a/examples/3instruments_collis.scn b/examples/3instruments_collis.scn index 4a5511faa..cf1b01c4c 100644 --- a/examples/3instruments_collis.scn +++ b/examples/3instruments_collis.scn @@ -38,24 +38,33 @@ - + + + + + - + + + + + - + + + + + diff --git a/examples/SingleBeamDeployment.scn b/examples/SingleBeamDeployment.scn index 87e118747..755ba098f 100644 --- a/examples/SingleBeamDeployment.scn +++ b/examples/SingleBeamDeployment.scn @@ -15,12 +15,10 @@ - - - + + + + diff --git a/examples/SingleBeamDeploymentCollision.scn b/examples/SingleBeamDeploymentCollision.scn index b455d0f44..4797b11e3 100644 --- a/examples/SingleBeamDeploymentCollision.scn +++ b/examples/SingleBeamDeploymentCollision.scn @@ -32,11 +32,11 @@ - + + + + + diff --git a/examples/Tool_from_loader.scn b/examples/Tool_from_loader.scn index 544bcba57..e76e8fd76 100644 --- a/examples/Tool_from_loader.scn +++ b/examples/Tool_from_loader.scn @@ -23,11 +23,12 @@ - - + + + + + + From c6c7d2183cec29296a716b3f38c1fb693a46cfd3 Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 30 Jun 2023 15:42:37 +0200 Subject: [PATCH 30/60] Restore exact same density of edges --- examples/SingleBeamDeployment.scn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/SingleBeamDeployment.scn b/examples/SingleBeamDeployment.scn index 755ba098f..6b6287acc 100644 --- a/examples/SingleBeamDeployment.scn +++ b/examples/SingleBeamDeployment.scn @@ -15,8 +15,8 @@ - - + + From 2ba8a9d420f6bac796ef5233c8894c984741ba6b Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 13 Oct 2022 12:16:58 +0200 Subject: [PATCH 31/60] [doc] Update documentation --- doc/AdaptiveBeamMapping_00000001.png | Bin 0 -> 251094 bytes doc/BeamAdapter.pdf | Bin 126196 -> 423507 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/AdaptiveBeamMapping_00000001.png diff --git a/doc/AdaptiveBeamMapping_00000001.png b/doc/AdaptiveBeamMapping_00000001.png new file mode 100644 index 0000000000000000000000000000000000000000..3137425a2ca33038f0e94fe332b801eb20fd353c GIT binary patch literal 251094 zcmbTf2|QHm{|A1?gd((%vQ6C1 z$bbKkgveurMMPm6;_w5B6JYyfGHhBHb__r51%Ho>nJ7GI#^O~XlTCMv{^KmY4 zho$Y_eftj_w6k|{bvx$nar}hOS>JQ#|GnUME%5q{n?bj32j742@X_P&h{z|;;u8{| zCncw(zJBxeU1nDH`wxXh#U-U>pTCq>*VNY4e{X1PYVPdn?&CW^i_?ce34jHP^JrHas9X;VGL181pqV$9wG z=3RU917}HE^QzFCb(mYYPvb#^;gm(`>=)&^P(P*OpJiPp$sXB@<}Bqlk|q6A!X)y@ zd?f25AL;#wYBj0e=~zDJyQdU;KlQGwhweFVv7AnndpZP5U0}b9BbU?ZJ#*cm0QSKI z())t7(j=ERtS-4EKEj|ErfsOzS;3wJq29DWIa~^*=cBhUYEv~GWlvITcU!G zWT00WIimUbBvTribqO@+9Ur+GdBjU%t*6xI166z^60JK(K6~F!1!43_^^U`;Ftb+{ zUWo4MBd4mcZAh~UY#lTMsYz^SkN*nN-H*9#iD_YVO-ljx=W?4LAu?qi#+aTnA4z9@ zESqWLe)cr>CLo~3>H9(Q20t(j5SsUjSOqkzhtiwH34R;HR1i`N%jP3Dsl}zU5t$cN zPQ6Lgw%Fcixyp`3bFA)2RRd9qGSaXvZdv<0axgts-xnZdODc1kkh&vIcAdlZFriov zCrtk)A8Du5+57M8DC3@Az(*>n+4-XTe(B1DW=dx@m3IW?jVTkisSK0)tPEsF;IHHK zgmKgCp*9Ec3N}A}Ep?dCT11e zrB3>Qe-?d1=~7JMBw=S9;uzY5mm!8N2&EV zFQ#~lu{zXPDIDeAXn0bY-F8G}^MSsG4ivVB|PA~fC+WD(>J zk}^7yfZ*I?g@2`Nuv{a$tEvYK5iE0J44S>O1|t!e0AaZUqk`mp}9ki)&H#xV3y_XDuIDZQlf6;-afL#@-aX zcrtt@*n9E8`+f+JZWVhU{ZW!%My)b2Onv!-KB(b}+lN?oXDs*3WGq9LkF2sU1EF25 zH9?R?45Y}gVpsJrgkF$Vy{zg96Z*yX<^Bh-)%~>I4nD$} z_@v~(4xsl%8PAi7owZLyWIlUXVS07(H

cU6%he@9KwU5PI2ax|Q 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%0AwyWFlO)R@tB~`;1Gm%_R#P-th?ncCj3U+yZ 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 literal 0 HcmV?d00001 diff --git a/doc/BeamAdapter.pdf b/doc/BeamAdapter.pdf index 3ebc90859c55c51d35c85e7c6d26b8b4954c5c18..43ccf3cb9389ce718935c1e7dd8b61209b2311cb 100644 GIT binary patch literal 423507 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%0D})RGH&w)bk^}Nunq?*#D>d)$xNe;E=lTVV0b+M zTp^w5>DkcquFtpF#J7RcA7w!Yr#3S*80sX&;9#j4HdiNK`fklMX`==4fWKR=ZXg@A!;f=Ybwh5z_a+x9x?+y zburuwleH@a6bb$r0Hb2@oG; zqHZm?w}J{#W%Ieso&n!{K<;1fOhQ(=So2*cBU71F70G@IEiv$VknSEeg14C-aWyDj z=B}vRx(XEw>Z`W>&2v$h8~#Fn50XQApyq3QAo}B_k=ezn!Ov_HW1*qd{G7+qG^q#c ztbJWrigL-9XwM^#*$|ia0E-~yCQiZhMY#%<$ADLq`L^(i#J1Y&- zK5h(3#*VDo%ap(0V%V9`-38(nCQ~&>dj2f4m4mr%wp1q}E*0SW`o72>j>;(?*K_Z& z(o2bfaND{I8;{;jXW%feiJryH5}V7cel{G{zG_@3<%x|<2C^0+p?iaI8P~!_cE>T4 zX>ylAfI$)TZmPl>siSSNOfJ^BdwO> z+`Dt&c-7|C`zJ2xn$bGg*PZu)QPB(#baYoO*!ANkdf7-+CWvK!R+n)TivrKfo5oOUC=K@_wPm{H9iu#L#d>g)HN8n%#Y}ob3__ zIha;x))Bzw^OWD2Z8^+foxo`eO9L%-*^ZL&VgM~lizL-7Ax3c~^hz7{scSN%{W{zZ zzQ@Sg-<;S?XuRV_^y9Blq&U?mfAR$U)Kt^r-h}RAp!s%<{>%Dmas<hD-W9cyl{;))>UCluO_G16YA0_y(!l+;xWw5(Lr>vT_wgih*#jk2i6JKe!jMfZ| zfCHdO?Yr3Vv>A~evV}T!uMjg53oJ9lI&RlfJ41Kp4ATyiQ|n;dM$0Ibm`$F%S#SAH z@{izL-CmcOw)vp8on;%VQO{ZHh0lYXez^4b+7h}Aw$%kGoUGXC(h#CDT_dpA_+J73 z1!gcd{X1pBTXk<%K_(tr&7A675pR_EXTW9P6NnZ zn4pvH0j2G~zYzX)@H=7OLAQN_;_}E;wF2s+0lNzhH=;)&h5)&0$i*vxwzq*`OQjkv z7&s*YU5r$M;S3kQF89akfofL#Vxb$!+!g5j^&6OJ{DjB0PxYgwU<}jdiDm1W_yIJR zi)s-Cco}m$t0Azi;H6{U^zo+~@)3mCN+=IFN&r;haR{drN^)RhuHuZLcD_RbKhwx4 z3Or=Hm{wUzU@%Gao1ossG$ti;Z>=|;xAEoJRa!a*aT+gleElq`@z>^P=(*=i*{QXg zEN=X&RjrV+t`gcvRV59+eZ8H(0b|~ozI>qC-r{mnD}gL`?i$UoVtE1YrBF7Lkq_!X z-?AG}*G{%V3UuZLHEviO_%8v*YZVqqrb+@y$Y_JiYtU-Eqc1$)EmWXGSmlPJxPs2v z++D8AobgGR^Jy{t0xP{ONbsvtOYK_;Fs_97C|cu{UzXQ{9s4M+5Nj0E|q7S#!r zD&i)RyfcvBiv{G~OF>R0*s~!~MD^ z1GKk%A)$NXX;|4srgr|~NLFarU@u(*>Z^*z?pLXtVOr^8=wD2y-TYxnK1lDfhQ1^q z72$Ac$KY6KxG+nb!@9cdU|RnB-1h0kES@_KNvs<%gg^$$48eV#rAX z!;qiw)UlgI1bIX$q=jsH4@{tf(?e+c(8EQC&#HG!;}5U*3t4+Ck~3z~-QC~z1luN_ z8qd_(Y+~lz{c;9r_8`1*#*spY&$1#ip0&k)PUwXAw)0PBvz}hU=D@jR3ltC@LUuz8 z$fd?*9sP^#(uf?ypkKbL$|N*_Nsdg@FQph!PlQ+tjd&y0ei!F5kM846`-E~fFP8yRu0Z|3zrD_kaLp!=l1c>TDQG2DW)KPjR z1D8_hnMOY^$2}P?PNF;K5Z=nlZaKsFUubiHE4dEr6)oFjomRPnFLHkB0`fI`)xJYj zKoXGLVgI85I3#&f|3wcBFR?q`|vHmcvU`@=!|Gsx(0L}dt~5gVoLWu#OEC6)Z_&OFEoxwih&<hyfn^AZts!u5@^u}#gjVeZ&v~my%+xq=s5x{I@(AAkj{fBypwm}WA@O{)yDx6c+ zb>gEvwS0MpwZyh%op~}P$ntE!GBTnSU5?GFg6k7E8UoTM^UvHw36qOhMgR1c=F0=J zbN-oMFjnG55l#!=J<%ntPI!_ALt|wuRAF%b{iqow>l}S)iKge!IkkO&@87jo`3aI5 zMXMK(uyqT(zPMf#87Z3uSU-B!=%YL&&w1EB>VmTM&%9gg>PhM8$EdZ!XpYxhy%>k>UI??SC_jLsR6)&r?FmE(vhGDhS5diWP4$T*vW z6C;)v?RE$d#q1py(ltaC1s^`hsJQtep8(%dgi{~qyyZmhIl? zq+|)R5(EZ)F@`YZ!Yn*m_yF*MEKQgExgBG%>&ayU!{l=^ z42TnsYd685v3WswDk^EhAhNtBHgnnkNGit?bF%frMsmd8b-_p!c}T*=T{+)sHAF*% zn|p~YVE`wlx~Z0+zo-RJhq~*VsDs6A5kPB504j#jM@l_N);gJYw=I%uw~BkR1PX&_ z9cFmDGm5Nf@!8Kn%}hc_GczU*#H{s+evwuNZ5Y{dQz@yg7vLTfxQ;pL)iD)QRvH?T ze~kOi#_JL5ESM?$_d`~%w_)DMKi3Tb(c9u@0yqoM9Yt*othwi_TBZVBi6y(v?%m>| z=z$idun?`7W}sPHl&ZA6cJFu5fke({q@1ojuInD!^wqXLCGOdT4DS*;4CkM3hBg4G zdsdh=r-hhqpRJGy!Zw<0LJ>B?**%`$3WG>Bm?*a*^*(5yT(Tr8e5rgw}HCa%9Gqp_!omieZ6thwq5~*lh9HdeGerZ zTVvdZ3ka+9)3vx?uNheXO>dXh^2Nh8UObHC80EL6IF25BzNWv5oV-*ylSp-WQjk!RMa1K98#XN>{qye%t( z|7emDwU5Jp_*>>1o(xW?+{Fn$vjcOM1|Oh9TpLh~3zaz~BV@!siEqML;LTkJNR?&S zJ8@~r{@v-cdQ_aH&ds)71KNy_xqTMOH&QG=i1(1bY!pTF4_s$+&9-82hTr_)~8v; zoImJr0mPdn?WDj_F_KIt=sf08+#6u{Gc+q)!6yi)t%FAi!R-WMSqShz7ScDYJK@e$ zkjtJIfgW#%v*K-x9`JyB6XPzC-r!TFcd1MolV+^_e*Erh8gQ6!Loru0fUql}^#?M? z@T1#=+7EcFlGk%aHR|58Gv(ZX*Ebn?njx7_5vA6Vm?`@7R~#v|?z?MM?CMH7 zzTc+28f(7@jcKgNUK;V6r<6iAyJyMWw;T(onV6}FNAewaY?Nz0xMm*Sb|%&!!-*_rTrfGt!Z6S)mBQTN zx{Sr@&Ju=CtHue>l%{q*?0*s*#3^r%{o3a2S>vo{PY*%|a(Y55nEL?G&~wnhf97B-OjzBrM*Zu-Pycz+v%3EAuE*|x z0l~c^{rC>M3Xo_PwBjXK7}{68)wrkWw=7l$TN&FFtBAkzJ48J-jN9lZBv7zA zm82l@k}ce%=s>CNdxV}K>j}S0(55? zl*C}u{1)nHFTJ49qwPsOqq0J~B?1C#y@cGkvs!Sb$K*^qB?E_Q;=x!)gOKkT8>y5< z1tO21leb#|XUH}`gY{5Fq>rqB*dyRxd^*Y9Y_X#MKvr*lc66etd=!sCT_DsOR9aR zg4oHXwuzWtfVM<(x1F7pimHJ$7;o<+mh=XHj?=GBqo;S1)Ydd-W`n9crNHY273s%g zBLm$Q^VsGortPCB zGD4;?Svfe=o|MEBt#5sb1K&60tc#Y)HRHeQzl^aCN_DMTs3C>|PFQ!aWN$|L!$WE=L8Q#DMLdxD_QP`omm;xjY%$E;aurnd6rt1c!Lyf67dFH2ladlt=a4YL z2p~`v)qgE+Lyn5`v#J+gpAJV3UJi=SrU=_b6*1W#FW@dpR?<&!*|HeOWYM~W2_}Wq zC=sE$)>^emBGW(jlRL5WEV#vXEN+7h(!S9&EU)GZ*5m=gW>;<+{obK3GFp{4pf$(4 zD;VV_k1vp}$(Eqxn@&!jsBQ(Vlwu+pe_RQxT`gU_fbcozrgTiG*W5G3&;m^Nm{e}5 zl`fP(eq~hitRxk4AuKFfKaQGV5DyRy#|}Q&)BKLvU%({mqRe27?VvJ%>S+>~R^ooF z_rEgJVA^g%`5|?H?*N2U_Ncyw0tPVaSGa1?`E?N``ob_|qFrfO?O$uk~dM z+9VVO8{ZW;bi}g7akGAv8Q!ABCuqN6f{EbJnC$iT02}ZkeS+ar94iVtCa4K$qAb?Z z(!YVbwo%DA7iW9uE-}+h$xJEM;^TH>ZN92bQ0QzZZX&z`E&9v>*D#Myw8Qav9M?rz zv0Mf!<#u@z8wC}RJPK>ku=#H90*-cPFIY2c1$5E=wOh)EkN?RDd`Z9znVppN;Hbc+6;4Q^jj#p|UMb?&gg* zHU%hG9GKZ%N+05xWfcYD1=t?(H>qR|A_}ioGfB97r!{zb2Bam;gT`CQT=!#G@9ds+ z(~K=2(~*8SMpgv9lD|rNn^)Ni%P0_VltcZcIEC}V;E1o-ZUb>c>@`5|4-si9+zmDS zW%!hK1w!~xJmazt0u` zNYx(7x8K^|@1|aQ+4I;$6P0*XTd0nuH?SVf4{m^!&v$wO!cxqTdWP0M+?d%`mQMG6 zJQ7I-2>JtSX}h`uj&if@7!TgX1!1r^a!%HaH=>|wi*AwI4-X4@t?0FD$9MA|Hgyz8 zP(OMzdWNxC@BQvg`+AEEg=KE%CU0vW~i>swH{ojk_kTmxE3JhzTaZr~jk~YGf#QYf5kPxqWXGPtg z$0y`ax9A{0bt`V}vDW~y9)W&lNE$Cy&UlOO0dGY2uo04OmE z7^mg{?d|+90j`?Cevx(Sj^e{#wy&bw+dK|Xl2d&GBU1pmFyt}!$7ijfx3-M5j@Ap! z9?8tH9xE5Zy~juPl0yEBVmXVq6U$4;cBi`ThLiL-tSz<~4TD?%uAND1Z#LtG6^@HaJ6GZY|$7aD<1kK8yobg|RDtIV-L5I26pcpr{2EY{c};2}YMmcsl3 z{gI8wol>qiRlj%3))rqtirN`tSr6RtpEDpD<-UilfgsYUHA-6B?mp^>qb=;=Jd^1c z|DdT%Q$G4zP~05Uh+y9oN>+&b2U)n|5YXuA(s1^T;VRHlta)4SnL(ciL{eeAt&C5v zWmm9k63_~G!!N5k>x5v1GSx{%?XL&MSs(mD7ukETaieGS>Jh8y{q2b(ar(ocXKLED zYsa>$n#0PGKKM*j)u|eBIW4+4jQ~YRQc;IcmCr{BDM}bogMg^dfzoJ?lx=5{f3-)C%@dWw>E(DnS zi$wTxo^fCgy~Hb1)maD$R?^SVRryYmpTCxY?rQDcEN3Ax8iWtMDk*1Kr^zi{-D)8L z_hANR)%1gvjPKvsGkR~uEhY0lBf7s92X!&e)hF(j(UZwnxqAsMCxETOmy$Bf9xe57 zMBDkEb@OU`zRbB&nwR4k1a4;$!oI3iK}G>AsnIlVY|oN~$mx~f(Av$7Xdkhrrmds2 zG!!sb2~gqiigw}O#CM&H_D?&FPMmVtF!Uxt0r&pe>0=B_jOq(TXTVwbQv7s8p+R!q z%dObq&Mq!Mey24g)Ni3eF_h=XPYd3%4fL^^po~=F3QpDc_-*Z9r}aalLDfFEvP#`v zG|Xhs;0jLN4#}POB=QBGY0&ZY{W<$trb9t%t!R?aec3|JH?ezN*LFTLy}0A8subWS z%GxO_s&IIMs!?-GSwOI?lSah{m0$(4;@&EU@Xnp-scU0S)=L1hGB1+FY|$2-;%L|7#t(uMb>6OtNW1^d1<=H^{_hh^X|Cbona1#k-=@WAxgW(|krNYb4ykU`+1;cG|=bep|3#OYi8s zzr7#hcOeDjk?qUq#mf1Pwej41GUldbNA$IyR_!PRSn7}<8_*f+qPh*!9Z3?9G|{{f z&2>m`i^3@raw@J*uys5ONeuXz;Dv-12tYsSnnrCRyO#KUCE9V$x)I|xxcB7dY)ZZ~ z8St!JuhMP#F3{X>r=Jfz9QGI9v$l|a$UjPq3r9YfTw!UPH?7%++Qde_h8X`jm%Yy+^3PXOXs zInF716*#HH6L6Pws#yKC$(coU?tZDy;ho8wW%a^i?ys(gTt$MJAhRvChvJ(X9 zQx)@etu(tPj112H+wFw(Q>HJi+;IYu8X?rYln{MwBQg^;j!bS69$x+81aCW~tSy!? z{tUhjQsSaif3u!z?wkH2hfKjForQ(9zTe|g76{i6LP%TYkKM~M4~<6hfIRvz=opJ_ z+is2`Y?N6qJ+w}UsqGp!!X<6v`O8^Jhc5{W&d%yK{f)nXsx6o+afGXN^&$&)g|ke6 z!9YwjEIcCwWse{2mNgi?)DZhIqKd(c+<^z3+^CL~Sh}cnpt&#W)KDZxQYD4>vT6ZV zGDyFukO3r)xJ7|`uN7`=!ixwYA`5v?_sRYdAaP=$Nydu^5KNx)B||>^m+4yVxdN=m z)q76`$XA!L|4C#<;>#2vniL)4_(W#0zzO0kEi5fY``M#ziI{*XD(U6ZlyaH&7tdc` z2(a{=nr$~uJO@??E&P%gG4I#-*Im{+loQoa9&Je8nx#wpv5?3*oHhka!NsPKzn;bx z?J%w_FxeguqILGH9sufW4Oy=p0s5LT&K{~pKV$))+Ry+(yxV*Vtt8xV`9w?9LaHfn z#G}#Ry0m9&Fv$8>C8vefawYAi)x7Ca+4=*y#iSS2i*=Pl#Q2?EwOcF6Bh9{|^F{&r zDW38X_sk?Cot@vco#3^Z6_dB^6ZwSh^>%ggdJPaUU#ccR(d!wu;yW90{;F~~b&^&^ z7dy%DGWxOXdOyZqe|(&Tad!|^bD*8iJx@N&b|e9i3s^) z<{4u}B36&g$_riUE6-_!uOXqN5p8mkq?*(pA9o3*G>L_RNh~La7ueI zY>p3@*tSOr5d;ho;u5_fnAqaw3peY`DTnzO27KM@D8r<*VY;zDgn(m*_J9nG{0uhk z#L7v2#hOzvgwh((5963Qy>6-%zi=It#bp z9c3}43e(c&uoShD&Tg-aTB$^oEtNFO*ofBK-wzBXa6L<6H|UX5m0#HPh0jWVm-jK+ zki|WkvvKj<1m^~Y_7EE&Pu;-9glU`M6ZUvqbNHm_L#Kb?6PqTnqTImWYnd=DKJefJKUiHeVFdChB z3{CdKRcBz2Bc+oOnvPfecLoPLMWvZO@}Ky^jwc8^i!2*0So)cbY6ogv|2|orPx=UX zeOc*Y!kG=uP{>Dfk}N;6>bnTpIXYwU0LpNgHg5KGXN7M3lSE>cpTiPwazYB;H0ybp zRIQ0guLvyy(KHv*fN=Om=?i$)cE+0-E;Ym&{60)@i`IS4+@~y^KROo#e`=Gb-E=DQ zc%;|;BNkmI6-9WtNezoi%aavHQjO78rLwdMFD4W-z>!e+UeqJ@%$xqqmF7$oZ&FFD zV4)W1-#%`%E^)EfRNPPpCLQxKny4F#Z%~bSW@heIORo{ST)lTtAGnjBBvU~!?Tx?I z`2biWpfIALy*Vz68AQ9WI&@8AAa&%sQr?Ux9nZIUokN1{188z(3_`L9@uLlsGqx6y zoc~R7kFXsM$k<$cCx9*TW04!uEzJtwmPX&qiv9*R{G$1IST(6&Y%iJL-vOmIL3lavHs1ce`8R#_UZ>xty;chO3Z7YG1XtvyLZnP1xTko3}?)zENx zg>z?c>@bNLkmnS{lSV#TQ?+&nqAGsqkW-|F>9FH5RA(Fgin!nd1Mmrnjz9qL3MZO&vw_uT^W!aEIV3SG6-MME) zWXOJeh=jqN>k4l5wz9}9sl;$YB8=C+Ks!ouFUw||JmEJkU5XgpHctU;KXlZc5qtn3 z#+vV4a;CSw%Y$p*YR%jmE$3pqKjk~U-Q=56TV2kovp#7?@@Z_3DfJPRr*X!Ecu}L| zB(v3$iQ&3%WdsXbR&b-1-gv4Bc@pp{hv<_+z zuPcigckmKWvijID-pBB@z`sJL4!I1QMEk^v#t0Ll1XG0M5_{|AtLH;^kB$W+C#&-^$+ge@l`BBhY2$rw~! zjP~lyXMDpSb0rHj+ZdNaAyIrdwJr}jYgcafv_mtIg5i3vYncrokrD;(U%kpMzu_=R zn+e3z^^jdQ_-_w`M;E@!U&%ZZ82)r8qfjNIB{Dp&;ejp3tF%NYL=}3db@_lw8Jo2X zu{8;iM!Py!d^VO)4#(G+&a==b1*;-6Is4AGD-PyUv*-z)zONorZ38ZxH9*Q!z87d9 zwGU3m3`7Nn7Z4WzstV#I8!(^S0l%%LXH)>aqL%$y`M74@S^#MP(?FpYcgY-lO3T9v zPN85;3BOr3SUnG#OrIuI><|?qQeGQDLi>0xc1#- zi(s^p)$;rd5z1xpyg@+XvdGp+7_gQ_RuYU!qf_M{-Vh@G3}h!hLqDUVP;d%O^GC+z z5RqX=LqF#>tq)sPWU9g&%meBrGG{)cyXKSyg8&hHFPFpUgK={8a^Dt4DQuiW)SIz3 zu9`i;dOPGJ(JB(BrTl(4Wvhj_GnU$P0N10bN&qyA_OgATG}xhlv#ZfJfsxfi-=Fcv zx9rd|M6G33^1FE_diA+)i%dLS*zY%A$i|vf3!|kJLWh<>s5|X|*~OJydd=V_--37J z0nU@q=hLamMOC*TKKK2^o>zxu2z+@<3+g8E#8Z0YE!402h>vOeatzLuk2!bz+xpPW z8%eHU0Jncb2d%f$858n z&9bgLH|l$A7!li4@>%dZoGSaWfVlL4wGP<4Meug0VmTd>bh~Y8JNPQ?Y1zhIOoNe{ zep?U;X-=UrlXGHvUIx6zL|HKTIxR5kI>ddDTPApt&^&0O_WTBBBWjLe_)gBFX`_U$dOxh`!&*dk1w4XtrPwwl0u>(gBE5i%#@$Sw{`W@eDE62;N%WJ7ls6enp z`YS`wJCg7Y6&|^1oVZ-70!|0kwapJ$rnQ-_Eq#pMh32$tuJf$7aS|+&{u!lKJ3;qT zCb15EG|sjv80wH5AV0sJRn4--6DFNa5)%_vzFT6jgt_PXj82zAeG%txLNZMFQJpQa zd!q)pJxq!%b{bY+XPTqZW7g9VW}&-$rUH*_~aH~M;JsJB7YspQ~HRnbW_a)%4@5i5u)X|S?+ z3N`TPFk5CkzIyBG6Sd@9b~P)gG|T#>Bh%85d~nH6-wU3WFM^=fB$4j&@+sSorT~8$6*{ z%r6S+TB8c(&;x}F! zmAaZs2WyQxqD?9_f%}y_l*7j_viDTarZ#O8KRqEV2(37N7kY$kdc(5))&aUh9Yh$a zJll(NzInt-WR8)(-nkd|ei8?(0~r!|#=*D`W$3#HQv~-H9{;h5p)92wj2t;sQ=9r= zHo&Vc{7`v$?ySPqJ=Fbn=&&)P1~29Ph1oUCt5fq}J5xg(8R(~U5?$0)F-s+<><=P; zXZ`6B!Z{2itr{}GVk?lOK8<;F%qi7hxsuGKu!|0Wpjd!>;k5*$TL7%S%LHu2?^i$H zHLmw(R~$iQG&ttWnk>Q4BNu#M%ps5VignOJgWQCN3n{?{TWJ=h1{@uW>1JY%WdvwI ztS`ZPnY(8*@*GgwwWsj5ak;bPn1GT0*Z^dGZ9VaiM~%8H`#5;E7+FO7BorYG%(?wD zrgSXQr%2Lo#kYXL9+u>6@fk!T*Zw?(_)Ra~BL?JQrxB;hAtjj~TWg35IPd=Y#%pvbPBK~ab_s4TZVwm<#$}W;v`Qx$CKs`z9E@={Otl=K;H+7xE&fBt-F%V&I4l149z}$kbOY`XJta{WZ(a^IxsS-Lf%SQUMZ$&k=9~TWeNqI?c2P^>dw4jY@*Awzq!n(jJhWopItN8um z%?d@V{--X-iDmXr0p; zH|l`ycQ0&{Ct-65$BT;@mksF(4Z6+Z0_V<4b%7eA{X08;vI^)usfeseO^HrPB+ot!v2S^1JaT7!Y1zpZbT)dG%+6j>)InmC8Q9v;u9=Orhorgvj zD8q#5!*b14ACZ8&K`nO+6~~-2>U7g-iG4-;Ny`z_zdq}cQPwMj_~BxqZFP^$p>PTp zuBAj7d)(|2V2MXbxQ<-$rfKX!1yyU~NME&hs_MgfPB@;roO|&fT86!71SK_*!-47w zY)-I`v+(jNZIhRzB)%;Lqmm?XqmMLQ+|pY3Vm(NRPoQ2oHyGpa`m-+rO4ZkJX5KRj z`Pek}@Q}tn8aS3n8o_MNI=j_B88dOIGx4Du--e1%usjDDr;Ni7#mu&SyUnfE-( z{I2&{ib?If?EtH!2;oOJsDC7C*Xzq~sS6xFf_g>ITWP1QT}?q7))gbCO<2PxM*D@) zj9|o@aOZ;%*2|2rOyskF z&tJ~bGCK7q89Js6{`?95$iy}niBu!j5{xXJ7<+;}9hq-tc=u$27!>1i8q8W|l}SfZ zxk0-#(eDt$El{Yg+tZ?TyC8WALZkDNfP(ibal-yab+=WYV*x4oIEC;KiHobm^&X=&*Fvl?4Q1 z$CR~Lc;^#!)6E6bGn<^B;Q4b9sgAbp&C7t+#c~c6wy{z0Wr%FCL%+k#-u|Q#Rjrj^ z9i5-Vy;*EU(U>zBrYdpnD+ycy+vXNyI-5S+o@4TdBmwFnCy53qV1^UYX9_a^vt&pA zk3uKmY7A}!1+vK9#2%lmXt;fx=EUPBB*UVt+>B-o5q&K(rlLojEpiU0v}vCAqTA|1 z9C*-7o`|C_Lh3rfz~q2*wwlZ0_@vJC`xI(E4OWc+{@0TQY$90u2$##;<`!9VZW3-R zbyQv=_;BB->ChAL5rXq=IF%vN1EJ*4G7M4Ao`lMjaksibut~3CDo7@dQdzJFu9D#x z9B<7Z3Hunz+N+I*)^TWh3}VX?uqQudMI+_sQmFR02`|^^quZdH9>P}gN0sA|h^X+r zm{9e$ZDe)I5^C(3e(RIF8Ny(_c~VdW6FHvXJ+4t#S(rm+$TcE3GOT?u8%A(#ctN?r z?Wo`eQeS>#h+YZtkI=*MEva&$O|R9Ers7gZZG`wdkWvAj;rRnyBu~j$G53pE&6q?N zRc*>YR%PTAe2g!e^hdXHl3Q#{JrN>fq9fU29I2L5AL<3^yKN4D>=v}PWi2Ez!p!bf zMSIG|WW?HcL4g#lr)nglGIxGz>cK3ojEUcjKa$GgJap$*G}tN+?ssP-TpnAFizK}y z*h^zE=`|?x0x3n*H(%oF@&lK6c$e@W8Q68Kzo{u}shnC5qxwqo9_yUSj&@iK@EFh4 zaJfyIhG~CDg{NB| zvmEkegk>vg2uyYEi#*K>!)#ze38TTt}26 z;K?IA{r>nRmz_`Q0_0(;4A85jQ|ewtuA#h42Yb1!B?@*y{y87Z-0+|+br4TrZ92@dCk8_cCR)VWO_YAPS?az*B2j>SXHQGqA0AfX zn4Q;x#3V}-X7nbwhS`TDK7OgJc7HTqZj=_J)m4GZcpZ7`Wofnt)Jg>><_Sl+D*Avm zh_5m#WMaAJV$ z-KB?C_vyNKU8fG~$*e2~A=#vLIjB$LqUwCHJ3|g!P~g(uUs}QN)A@=YG$60$&2Ojw zO2s4D3Cl5W(OK3Klm+QP#> zt+ok6T(Gs%D0NROHip6WbVVoE6z$tjqvrw1bANP{Lf0c8-vv-EK6<{;Srz?S*;qVXUEgwe2te58;a+rMY`NW7pfqa2=ruNFR+t@N{Z(3&ZWTAmbl8 zJa5v{=_)0|E{~+Q8VhUciXfUtV+OM-EVbh%<1CSSz)5Y6K3&rb#?|&qe;sL@+71pVK6UzlQlk?zQK&HFkej z+(o-+Gs0Xm5H5rKY8H#mLY+^H%A`ER})ZheM_{0BYD^;p_aWk~G zf8%GoZ3t2Fih@xQms4z3B^WkvJOc_K0Ut`DhhGytUkAoJf`2!szuBqWi>4g~h+g2L zMrm~)lFM})6#-5A-8;e5-RQ^V2%!DVw3$!>zXB7lxIQeu(EAkOOh~*nWk~odG7?Dw zMiCH@Xs_(1V%649zUta~u{#pic0DN*P-??LUY6Sqc?QjY(3j{5iZ!Wwq2e7P|9C39 zQWh9-evjaRjVqBWb3VBeNw!!nx#T_w4r+}={CDH^;2oPC$MT069BGEpfAxhpY}M&K zuL+XCpzHJ-4(7?~kFSALGSrqo38(QSA4L!IqER5C9);E4?-jX(J;7w?EJh6)E4aIZ zOV~e&59ogBB~rwXNKx><#g=Er2XU(qeV{!5_mGD$vvMA5S0x(sE@ zhW((&vact&U1mA)FrbTa2(RH4YmsvGSCF>#$i-e7p1pYVK{%tKxcb+2IZa_j^YHm* zO7xY-DPINCJuJjGoVUBbmt)=Sb1tzv99- zQl7bmKmcM-1xVsreEFl?B^>eqBnwnVXxYr=#g&&*X8a7`gacm2Z87DI%)*j|_42jrUBEN~Z?VZaeeF>^;o`XgV8DKyYFHK)V&i2t(12&0+Yi`7}>b#=7fBu<=%CJyi&V!-bb!de*KhEfZQ^ z>01hDaYRNS9m?%Pci}~n>7R6R*~15mhBaiVucff01!8OrP>>rAP3PO_0xeS5; z72jDUL3q!ok@0XISi*fV$a(qnfrF9~bb%`{3Ap5TTMiTqdR(~tJ;4UPwHe!Yi6o4A zI56kvmJ&@O%_0jcyVo_YHf1h)e@`fLVCGQgShDWJb>_IqjvwTy9Pk%Dn6tL=~ ztL>+bjmAK|uGEoUjihS!oDH+ORPXu3Yv0oj#W=`t#Plw)5|fMc1+-2U-8S3>m|g9F z=%>%yKD+-DZ%FR!#}!J5)~(jB^>u1^Cj)45X~BbOCMp;OES-lm#9BTvPD*peq5s23zIbJDcIku z3yfekc8ySc-R?@@j~_bLf{a`#nOH?dr>@n-;P|rI#Z@!kjg%9sk%+!!^@!HIKTG5& zS17`z*LDj$UW+ZZjVjO&Zm}|9OS-YHw@8hn4>Su?{HfBDJ+vzwl%JtgzS9wf9l4pK z5kV!g<~-mLk{3W95H(3P)A%*z5$i-HSy#ZHR zJuL-^mlsUE8Mm5w4Ak2b|Jeb_%Zr&EGaBGuZ=cD@&Zo1z;7?;=h(c*=N08{<6R;b- z`O;S`<4kaZjl1Jg1{_fj97RrK+W8rpNoLFGw}a2@1|jp@mjkcP?{3a`aSjQGT-$(smEol0fIkr_oG9JC(5fB=C`q2kXk=_>vJu=v~}W{0UT(}^{Ca8c+~0$GR>}9+9j-r1ycWxQEM4%D3g~;p zoV7L@N>pMin{R58g|eLy07xCxgX!O>oPir!xB~|NR*2TyQ_={kM6vs`l%j%f?16KX z5@>N&ce8VxC&WbtOFYR=?w#@W-uL1@qhQjc&V>s!KIX_qT=#4wVCPSU08-xu6tU<7 z_E~oz^gA$*yft~R0hmdpYGS}K1s@)MQ3%#eSIuL#E6l1xt%wjd5SP^l;Ac#+82D`;{PQoTJF3p;MoJnRWzSq+Fu z($xefcP0-5n^_&)Ap>4|7IMbp(32@pvADi`kzYIRkyIqIZpNRB8x1a5A5uyWxb$Lj zVfl#UN_k1fVUAPQb-{3?&Mnc*X;5Lm3EQbmI-??noUPfD}77NYKMND@upRwMPxMgP%`%*5M*AZZIr~ zV#l&Qv%@(U$sf^+RMlC8(9VJL0|1HyxE`4n81__%_Mrzf$HrBsrjtp3Lj0s<*F-A6 zb>a*`Uyw2RY$})qdNp2PcBD@OYDIafhgrgGHYe0$Y?HlH&XypnQbvGqhOQQ~v3ta7 zeZ**7hA-%E=6i8{o)|*%MK~=;LK|5K;@z>f+LpgG1-$s~j(!K==2f{D9r~;#()nXj zMZbieo*TX~15e%+JQZK=#EKMx?&vgB z??Q{X*+aCvd6zYSu!!r5e}^-c~OvzUcV@h;fof%%VsKKj5cZGahz=gRM<#|hAN zSjq;wa~pLiiJ(pzAe?txZQwYIOy<3fu(X!#31oHr6vhM9$Gc6N_G;6Cjp9h0?ryBe zmCC_saP&SMxY$C1I>uonF9%tqaJfl#K#J_a0^Q<^VZQu?b!nvq9IWbDN?4&T=XJW$ zGdHP48)~s+&YbHp!MiXYbssgCm0o>OyOAe1%`!3qYFZi^Ik#&4A|xq3#l7ENq!&QIRY` zQ5>|BtJI-CDHK81!&`_P;PBlW7u(fU&gp9HradxD{u@VFfb7Z=8Zg}ynmonmJkbp90gxEu{bO(Qj4xKwK_+01dI!D;;ra9v+DrooMGU=sXzj}Wz% z7XBRr#nW`D29r077iPv*WZXMGR`Pdn7X;vJ2UyaY(cf`Sb?%<{O7x)*ZF-MRWNl9j z=zX9}WmyVABXaQ?O)}h^miy5eQ42NtVEeUA^s!uT%oUnNIR8kznwCq=+)fh0RcCv-knkxQmG`Hhl`EL8A7x8f%OaY zDeT}%q1e+B@xU;6frB%ZNP&F%HB{&Y1+Vu47dYpWs`0mefCNc+2I+NN53aJ}g}}!` zI~T+CJGi~{Y>3IQ0dAi$LCsNsVq+bMzgPKZ0@clFH4<=cP#dholP45+gj-0Q0-DyAjQt{1lf(~^ zr~(F@zVRpsmT1im7l`2M)Ry{)UxnbCec55%LXp((YX(glf?bhKT6Srm@QUkdmsSWW zWI-pOsyM?H=4s=sDh9X-Qecd@Nx2^+Cw)jB!q^vhv*2I88k$z6LH!h5kzk7p4cQ!; zWzswzzLD^pwbvWPYPOnf0IDM!=XJ5Z3Y%0Jaa?${tmV@74*9mxrs4C-H?>@``8i{S zKJY?Hn9)!;ngJ()ZVVgo0UEUD$RzTl(Kn3>EE;mbGQM&JIYT@0?hJyjy{^Izds1}R z1OwML=(xXn68MxIl*s}g9p%T0-Pt4*v&`XimHMB&7uL!-p#F>pR4kY{qh3ZMzybctEL7O86YGGOuS7UPGfVBRK1@l zRj9+hzCGSI>|VcY8Z$>utl16};ptd`YT#=2T&?z?AeSh+r#@iWWTd#BvsN#3=;5zf z$YvCH9%wKbpz((cl{-=UoJ(oSAxcr8e0}X86^O}lS+AGCqBzh4$AKZOV{6n|3+h}a zdQ#vrQ5q&)XC*%4DR!dP-S|ra))o3#KDTamx4^hx2KA^^z&z6Y5RwWLqN99^UN7^u z@TVX+8b44ya8|F^j(?l6<>pF`mUZkPmXlAUopnIKbfei*&Q8c)bqN^v4s^-+>8e2J~xXQ9O0$Bi;xMZby}#ht=Uo)t4%r*VBCl0 zGt3cycE;8uq(#jqSMXCV_6wZZbw9s+<7P2&keq(2J-fG4OcdWmq|*FUl@oH?DY853 zdV=*$ZWo9v82ge1u4p62YVAWM4rySZ>Kei%EAef}1zdoil`@SfuQ2X}O#jg$eYq|t zf;)p~H{t3)XIyxGd8(BA@S;O>Rve{M|1G%}GjnNAuCHSDld6N^|W?Ng7qF^9K_OI(yoItClY(Hh1W zYq;!oMvZ1SidM5FXk5mCcc`NsT1y;C|QPxiJyLHAp4y&dp zC$gL~Dk0TcJBoRc2oh<@7;M{vCif&%`2Kklp8cD&=WdDgsD%OF)uzUG8*Zbrk+(Cu z9}Y*QOBud-%!SHcB@i`g+tyQF>He60# z;1X@@B`hs16Z?J^R)PBAVVYn~#?PV0ddpMqe7m=CpA?Okvq8F(QU*$6Q3+f5M!B}E z?nm0cYx0^Sn~L(t=U!3(dZLpeP>WJ)p!}9U$l!MXpxMa%kf#)ggA9NLm%N#F|8xgn zhYNllw9=6M6wPggoIT3oP?{I&#BXPp6z8P2NkGbdA5V31-$tR9+o9EMW+nh=SM_l4 z%X-%gZ%sQaCwxRnP|nC0->=&>VZu=EB?o?MKa1zg5j_(c%_Aer7X4&#o2os0J};It zl%3$OTBCc%isND*h0pw=k185_N@13Q069P>+`TdRLt8ALZjd^o%eyNyFfn79+8@OY z>D?v<5v&H1vo<|;uIL0 zwi12$=cqc;cvozIDt(<#P3-NDl3r_wBU~AUv_Ic%G0DQoFP!O~BnnnM? z?>*#3uHFcb2xxRC9LcK%V+1!#0hzifr*-Po$mzXX$jF>zfz9LWydH`qm{qVsKzY0IUVjLg3bD3kG;C=8EC}PpSdL8 zT+@w}Q(fp&-QXx5`5E8eHu*Vhj-*d=wT!Kjuqk-XJxQd@8CWgq&259Of2X8=C;+O) zDdPNdg3}CyE>MrfBhy;7CkX-kJ*}i4U6!TGG1@Oj4OzJ{=OvQ95tj(!|AEr2w7Ct} zMM+mB&f;R}23T@E((SrYf)i6e&w+SN+g1T*r!5GZo4M?5LG7P$U-FmIG@#LvITUQs zF#PmzJ)@J6S#1$bX=$r*D^4ipP_0sSK?UgIQ=Zp4?na2&0>oQ}=4TRYpuF>IiDqf6 zN0xPk3r`mxVDK07t=-X%`Ai5!Nu!EUs8ypW=FMN$s%}pjyj=1N?`@PG(3OA7=sK-? zy%7AAL`0mt+E?;yJn-FB#0rgi^MoGaobSSShc$B7#=w#?(|X>tJ$6w?LhryJSyk2u zPKP`&@w#;8%iL$QBNq>mT~w|jSaHZsEU=iKep}?^M4Fbq-&{U5iyh?Hpufx({S(n2 z(~CKtv<(V8JDX_Xrz$r+BD&PbYI@T4CD__EXT$`l?>uI)hqz2Z!oCgY1k14dx`^|h zy5fG?C8V!N;v~Ydd?!)~Ri0avTZ@D~%abWC_EE^uo(0X$$-+A3rr_=Wo{Qq&BF zD#}r!^tc;?MlL7E+Z`lX0O2oH}h2sue2m@!<0m_!Oupkln&1*q9$(fCPB*{kWW;^SB(IxDfa2j34Y5 z+f_H-h;%9O{{tL=1sLR8EPSg%uTm zdAJyEIf6rNwI{-|=GL+0an)R!VzAbWXBsj1kA90 zYYVS}z0slj`{}z2Zz^w4cyGc!@PDyW7eY4Or0c~;FNDBJiHEwkz6?AnbwrZKI7w_r zEmQgT#q6gjUQ1+-YfdIPs3vrOiIwicCRp-*&=TD=r(!ChH_336_-~Az51>7TUDl+(vm?*h{m3Y~ zQq$UccdgswIL4~xsD9Tv;h0?xA)CY$Ouk04tdM3Y&?gG7Ivlr37Ui3yD5NcIg)11$ zRN8A7=1A*}x_cP>8e0MHDvZ)@TSiTx=T=ZjlQ&1Z2y1w}0kEx2S*JV>>y7E^w~l`y zZKvr@?P^vv_+=RvR4h(`-`(RpRl9<7^s&?Yjv8B%8@*nQOmG9g%11&zft|^O-txvt z@qJ-9a2>EQ;?*^tfKgIgu1~;!X7(aZ6zq+Fgmjw%CbUA&u|4?zmjB$l&HI9Uul6Q~ z4c_SB3W~FugI)~_@x6FmJgXvh8DH*#Bc(O)QMjAvt0Cokd>OcojP*xZgiRAVrc*;& zHNs%Zcy!nn_PtC8cONz$t zx;E5Rj9o!^r?QbTkrGhHzgH{6AD7pBs!_bcI0quAADz`!G!SikwbFr_7KsN|REWWG z6w@a){o@Uut+of8gbA4nk5>ozSSXntL*Ip*0L*4Nl=g>V{EbS3Ld65FA&0r!?LpW%MvjccTI99Y20> zbFp^v76hz|UUR6;Fr0xZfS~wVNBSgl@(f#UXCyaPkH=B~>_3iu@i&PNlceU#{Q*a7>yIZC>Gi~_04I5C zJBkqgrTFtI%(+uM;2sFKNz~D$L)g=Q|Jm0sa>>H{XEcCl+E(Lii8WNb3GgKUDu);% zAY;Z5@u<}a0rGL5?amLH8k?`Y;TSp|hKD;`r!+y_2lfXO?ICXwWyGS651Y0lD)_*! zGiSk@#~65DbgM|tI1XwLqs75J{Ul-nSh(g%o5D=)VIS_wS9-RsoL=4>RnFGWseN#6 zM1Gb!wH;-)7$-`n3OVuu1B}UI?^)BK`25bkW*V>8!n4i=5~%2WB=bbI$~VqPAM`qw z7E(i?DI1RYNggh6S7%k;A`=3Q410tEGdWAz9z14DiqsQKj6a_G*vQjY-sE+qtWLU8 zF9CvH5O?k~>j>zx9H~@di)j!wa=YYR#!FyU6`{+X91gqD1?sEXh*`*Gsg+l8X$pQn zH;|d~k8T-qyfv8X!kFLk-rnWn+ofKqt3$}!BH8)+@RiqyO)!yNByJj(`>B?R-`V>@ zwt?x~t;K=0!*X_{+Bmf?wT)jQ8w7aJ@9Cw0uEseQ-AW&KK#3W6{y&? zrgMsM(|oLG;;-6#F}W(qv$LG-K_dxfelNKK;sR$bQ=W zC6RZuwL<$~W|2zhkf8*HXkTPoCob5BtA$UxJJcHorR*3B17Xs-&G0)lIxaCyG$wh3p)k9{@robzC1GS4lyD!p{oLG{I3?l zVb;Vo+eP!wxJHaKolZ6cn-n^pgvv5RmTbA^hM({=1%R@dj#Cp4?Z{d_rTaQ@bQr<3 zFRYgE+r{=Sg=@+j_SHErzSQ6|Y|NOus8N+lBce_-)00(1*-@ppuf%SR#@*YTgpZtK zr~bPdt0)vMZxjwOM2mQEW=n^Pp$dQ5D=!)M=irL=ssV0smh19b3KE{pDkx>Wndcbx zn+O2KhMS=kPj#0T!J`mzSl*^-K{T(FkDT-GV$Dgahtz5de13YT|7D@Amz#eI@N0+z z;?34<1PDZMOCPBTA2azsm?CvI;^uE+`&En?c(u+1ay_ZQrK&_NljdDVSI5$6HQhOW z1`i+6S$JG9cnv;_(%Xt9){Y-~#CcHB*a6ES`m-PTQ%>fvX10^RYResfs7un$7mb zVA~&QwtcKZIGRtTZUq)gD*gPqGV_%M&bSSnd?e%jMf@vItFfu_0)&QKj{R|7atVdk zE%d-Qe>ddMw|SFL29p!@VqVYslfwTc+yPk}FBPg^5H@DQ6 zxL;!u5S(FkaKp&Hd_U%?%CbsQt$f6AO19*LBa-Ox!e#M`n#Nl!VGs!i4DUJS+qq!R ztC+%i@XG|x+OaZ%1=o5Y|C&Dc;3&*OhksieR)-UtN8}-hQ+YsyUBQrVh9kWRZc=aW z<##Ruf18qWEIFy|xLx$4Rn1U>G8VeTGu3rK?_J-U%czp*=}t9 zz)mLzk_}Ap8XDRlN2mwtTxAqo2C2-RjO}F1FNHPIJ36{^TkZ&I@6!bdnk(fZw?xu(OUwjo<4~(&CR3G%0(n%YSl|u{ zGW*n&-Trgf)RCnmj3obxJ00F8gU7?s$P62vkGUwnT!EH%JYBs7`gU2(tD#$HUAN3# z!m-G>q_`l-JJW#PwEVUZf#at6v4+m6*ZK^tWfH&t?(mLUaoyL{WjZ1GRGl964<(q@ z(5YBTtk}i(7+y8{CL8j<#HrOE#rXmxaduHLh5(w57t3`oNl*U9u~o)%FuJ6+%Yw59 z!ZP}3yzzWJ##FTWM4CWy4$^lfb&rW@V4vS!1oT+t0>J2O{R*iBpGo-c*XYI zJWa6|8KHFK6Mlit=~BhpIYnG&Hc0^58?rB0uBXcth|FS<611E;7qMw zP(jOa6QgDZqU63pC_*O-&7a#*BVOKli*f{!Cy^l(k8jlwGYZ7wqW5Ip`XBEtb=c4dk zc(q4zC$$B&l#e?f64}%_QN-e}wuT&q*_k$&{0Fo*qa*RH2i1Q>wNnElO4ubIUN@TB z4-b%#%o`UtpzgV#SI-0h9IamVNvVHB0j4O-AgKEtL1Nloh>D5(xNBoqm3a-2ISqtF zvnd0Z&i2y|$bwi_(=q;8cr;l?>m(M^9@4Dd zzP(3=T6`73p-SjwYUib1S>{IFJttB481Js8Ein)b2INYHji>Lg9;|N z-_5Q(Tw(vUi#w$1Mz1R<80|>x)kK>@&(|Q82{=s91hh*T%V=s2X;-hw{tP+6^rFJ| zRZ2@JCNgF;{jN{LsDndHSiR|UWs+?(8_~*EbmDXF4sDt+aVdTgg`b(%7?DJJ8?`afh8NuZJv46KO#!7z`C8M8>`Q2f z8sQ{&eH#NAo~)s1&OwK{{!@XwI^1|lScu}-?^I8_2*25^)XN||3kvujR?MN@@z&Ox z{xL^?EUt`X?#iG;wNwpY89|fIbk2v8Rbuzx42*T(N6Z!Uugw){=Tjlk2Fge$`KHQkJI5B#Mv~c{)8rkh|)%8d7 z5blW~(m_p)_#ka6)t7VS-u9{5wS-)djEOjPTMWrL9vZ5IsaFryGZXnNg5{woo@ zFafzPRcmi$(dG;PnTV|k{G;&Z(Q~GAm8jVJVhFPUMiLBhHPdMkU}Tq2U3(Y)g-7i^ zpdJ-Ym~k=h$rG%oSlFf_xf74-VV^oNvc%)KBY_3hIm&J5kjmoXbW%~VpROfO1cSoG zkUxjH=dZZg*2z#2`uQi=B?vNXR0wzwZj1pGipS#G%~{PpfNGZO`llO7925Eqd!Znm z_uW(#xxh6%d+;9~nfQ|NP-y?w(Hbb;%A;cHMiTC?{!zrXtc!g5gyWbM7O&Nb+vQ@y zX)F@@GjbCONIO|knimzYzQbdW14?!OTM|Rj&-jRA%;57hAGx@YO0wZcl*j#QPQ-qj z3ShpTtqXa`3ZW9XN=XwJ2>For%jh~s~mj}!NIfOWkf4~dSK%eH`&P}=)dFRnlrUq32x)Xtb{)A zcEfmz=rfok#8zhL_sm_ecDYHp5#@rgn6~}Uy~mCDgpM4(=-Wew*FpRgjIX&HV@joQ z8+%Hd!a?KzzkN1J{o5dl;!wI6V&D!8H*{6zdz@B>Gc%8vxS10(<&;LB$WEcuGV}s- z8lf78wKQ#4qAas1+q>;(-YeXS9bsFLc6}9ywzH_}YLJl5Hs|%ao{wOUMNZ6&_JAee zzMsp9_MyaqzNNkGi6Asn@z*%hs$7S}O-@|TvZo2Fdo?EFQuy(15&K8v8-ECFL&K*hVtR!6v4Q6HhbMH0JS zekf4?C#Yzw$5st65ZiFy)8_9c)Gshu_4V|WT>W-h$zpvsg{6wsO|&$|(ve>ml7-0~C^i-}?rsv@B0oo}R57(nQZYoNTUNyzdZ}B@>2pLzz zisPTUg>Orbcq;cK^`3n3$)?PcRvPmk!P#$*a0t+tiHp-zUN7IFh?I%2oQkImJ1WM5 z(p7G;7dV+=!`l2vLiF}iU)-cj2@?__M^XAC2!KR>(|>WpZKTy7uvQml<3o`D&l!qZ zjd7O(6hMLA8OOfQAMv;dt<@g1fmD&wOE27c&i)C6vA1igS>H`PFV_v`nGr7D;YVxY zfoX6B(;e<(xc;_QUjjmcQ9_*9k7eJ`&jF9jsXuHu$aS_w&;Zt%OYnOb{sMQagh{A> z4clu7vU?vyXIW_zSX#5{&~$UvL3eb}p{(b*0K)YUs9`%TbM@i*N~0?Cz6k0dQd#Y} zjc37jsPxX0OZv4QN}WHQ>GXWzf9+dj6D!2Q`llkKMuL_@2-A+1Yr%GvUF+*ma#g+K ze>e>7K_y{-eb&V;vhJAcMT@8n{H-*Q`-!12@G4&;u?NbMI9Il^`(qZ+j)m5LiuxX` zkq(;F^|O%KEoFqmM4_F4iFeL~68{rtT%uE_4M0P}C%hD@ALON}2s?cJ*S!;6$p7$W zzZHF$r;2TrxP8u99-5shWB-S{C{wKMOqW82J3mP%IE$Ng(OBwabD7!Kg$?q(p!r)# zdIbdBeEZ#!p-h2(KP>?-5+Dpw+EZxGQ zvVgpONGXx(f9aR#(kBm*Gu*?~+&Q@wAma+2siqHJM-XT)(0(3lc}O=TBIR#Ag5UvC z|K+m_i$wQGgfPc!*=Z;rZwTEa)Ya0+h;O;`(2>b>Cr!l;6kEpbH)_yQ@?nr8Ty~jw zQME0<)ha}*jCK%WBG>SGI~p>tmols8%zqZ}=>Rs*Rhgo{m6T_1o5vYH-m2z{%2|(2 zq`=m63;qsJwdH@P%0Q;;Sejr$)qijnd?C-3%Osp*XdGAAnk#qNy%IER*e6siXQuEs zL}^;73n_0#(|)-F{y7Ie9@Lnci|0kA{P{^|t!F+!Eh<j`X?O+%05#pgifgRkD(PB+Uh*?Zeu*IPiA4 zMhjXA2Sn}rTai3^ySD^bo@3l3m^I)`qy zpNkV7^3iV^LFNC)m;%p+-)aT65<@AcurukLKdI;WDW#d}L773pVG@0?;CUB}y+4E9 zE1*lYL7^@#X`1$A6Ly2AlL-v}v`{4@%_5XYN{eOMv^K{g&ep=oItwlZBPZGzi zl9fMM?flNYY28~`)p&mQ9M0gbv#IO<^!XZZee9y^Q#3^98%c zUu?hSiqw9IFTTK?bhd9~Fw~Y)Do|9-=#-Yv%3mK?@kXex>^NHbR8qU=L_c?0x<=F2 zrd@gI@?|Gt^r=z5{8B8Q$(#!#`wUSLN}G0E>bSAoa*kd)N*M#IF%8}o)Uk6*xqv_k zryxZ#TBEspgd1M!Z;8uWjl?igDViZ;8*pI|PjLMQAjwn_!yUYgrnC4C3zf}YbVIFw z0e>7#Z*TYBc-~Q6J+t36Kgz_9x%>&DhI^u$#^@8C+>B@%S;UgOpLr4A-VixF*gvl? zb}^Qb;~{;sw`ZWtc&lb1=fVmRZE9Fv?c4iIricqE@=iPFvmu1)_tTtU0>#)*hMgvC zAhL?jtq+al#Zv3}xQO{0pwUOBju5kK_{9cfSUd<+ez%r!oHvNUza@vh7jp1G>UhoQ zGsljqYeBL1BVyvDEPJJK@qSVas)% z5G+rTBty2OEi>Y#*e{fTW8l{wR2NpzF=7zH=KYhq#!)BMLlQCwgQEsvQ8=GFRu(0K z0|6}@!Dji1U+CV-05Sq(W(br!;d|>w_t+Ab&P){>oK#sT-GO}ZtY~_Cb@McuE|+(V z2;VCe!FKb~?>&iDGDiAtu>|`mmoHJG>LL@CIHp~DyuGU{Hat!1ET__S;(5!yW=Vp- zZVaMLe9|W>lFC&Go;SJXxV4#ddD2qiMef{nVLVS*MDcb$-v)~8o%z>=jOz+-;)|F? zZ&$DCoCz51gh;Z)69=DSGAODCjmW?dvxb0VK9|dDi1jk-3a1E41kyOl`+G2^cq#v|7T;G_&auYqV1P3fWqXM?z4}_Rgu=d5~^LNBS5@+0u?kp z<{@OoxoRBNRxa5*0x!V)v2BqA4V*R_>Quf?AuxbXVhn~+sJZk|&PPKLN( z3qEydRyn@c_+GEDIQ05G^@lQrX0=koi=&y|lbf6pfnuak4A zxuP?G^2XS@{|cNC_F*<-wuj80XPg4#1_Wo+q9Ig+A$Nah_83B1frHiGQAHoOEmn&O z&G)9PQ9|~Za89pLt^=^}Cdt?N?BVyH30S-Cn9cws;M-9CeC3!2e+OH<;R*Qz#sAe( za}eFl=pjW{zi=0j{+~FtYus!&W=eeg$_$`ctIZQTzPG1h0asKhc@>FPvQl$m!9 zoTZ(Fn2J*VNH}%|E)%Z?yK4tDr<=ZR6Qn3As~|Sq=TmBhOKZvbp|PE%E;!LYOUcLu z&H=!@7nWZv7bRp}05?F$zttNyL-4))x<~tpc-}b)XoO2b!3V-8=?Nkt0P~O-|8-MQ zNg60d8oTS@ZMaH3Z!bY5G{Qz++8wIFq-M#iWT2&c6Z);ohHE419WPb&Kc6volNbdt zj?RGGk5X}8HuW2jyaoSmzvYZn;>$7)Fg`p{R9CA{@_+}j2))b;Gd)=8<1v^I>sXw%Z8JuOJO<&RaNDVZ;{ldgreJZ--A3IPIt=ZW?X zn>{Guh8M>x{DJmKDmp2N?vb2}n!U84OJI+62se&Shc52@<@X7M2yyUxU#avG?lGIr-W>Gpj^3rHe z^d3M98PBLxRl!{O@MtlrIL!+Jh`h>m@$_0Resm@y4Q%0XnmHC69P-{Tf63kqaPK5q z!O^sfR=48-4hZ^4bF%MYET>80AwS~HNw$kK*dEap-BqIC6A%4j@x-xBNaZq8L3f0-hnkU3Y z1Y}IT75*GY-C&j=vzBOS`nvS`>uXHqE|A|5wFPIwdQ)?h6xjw+`Ftp>%;2Ou01i2h zc!^mF^#J_-Fl9`PKXRT(sOrP;8*ObTIDp|6atMoz%A9 zH#R7XH&lxQX7uaV74i3r-yCkp#=gsJ~9AJAU`b(4H zE;$|J{3XAB423?OJQPOiBz;+UKzLzRbTX_ZLUtD5Wu$X)y7zB6iHOitRgIEN_o$$4 z)hJxpz&vvr(qqi=PD7WlaHMXl0*v_5hN>G7Pg%ir`de5EvKfS?K)i*=5#r}DB#*>> zLR}n`6q}p8&4CF`fbWTJpm9;Qg9-{xzhX^8pDr%(VYG?G_2SZQ=QV{yE5p7*SA_V% zIM*I^HkQGR&3ZIvKlPGD_HM*+!kk!eRyW9%ZYE)Ew+f51ejsD4KrN?Htzxa_Qf=jY;0{v&}L`zw=BTsv((w7x>HcN8_YV z$ZV}dtNaF2t%A8AUEw>6E36gXwVOJ+t~3*jkwzd;Re@2JrXX0O+XiS}$xwB&s;^`@ zO3Wmy|D@tdR{_@ z-0GP>1e;>}H;yf)u6V|K7Tx=mhv1gkzBW^ewOmebKVdf;@+b9{P?jnEzf^&nl#OiA zI4Vjil1L}GK{&b0Gm6fsf4sv+NYmqyHxx7wvF514Sj+s5qV}b2!A_v7Kk;fkrHKVF z^hBDk2ca1`x{J})Cfc15VDT(;n zO?@96FpF7erQjd5tds2eKe~^CTMB_uWPgQM@An40f@5Rz`k=z;nUm7KoJn9o7wvo=3BQNs%cl zy%i2yj>b{Qlb0U$u$Uw5N#*Hj-_ywGIBOl|*L$Ml37;Bfop{jv!|BaQbx@Zd1lF(y z;7OY@-4!EsUh*JK&kZf*uvu-vRCmlbXe)j(C^kRU+0%pXzfU&Eg10|Bbq-;p8HSA6 zKf`X0E~|U1XBz&Ux}#hCsWvo7MH$Q3RIkFp{&-l7u^Dd=LPI*>Kcmvk&$(h}7&~!1 z5o6PKY?C8)LwE}NKA9~o`rvO=9yvSNH!w1Dbb3G4YM)r9%FKDf{yoij7Wh21XWdAs zsm%y{TZm=)=q`ZU=Vj5wX6m@ggf{&Sox>qA>gd1RMZ=vc<%tb6X4lZ;@6Zyl{I3Gd zqqkAht^mj>-9Z`1FGilx5{4br5K_zbo`MW40M_Vnd;0`I7;o0A6zOsXjh+Gu~&uJNeS~J zfrh?TG<5!>MCLy!H_Yoa^9?lqN~bxpII2UJS)pDfb&p2fg;5@{zQJU=mwvU{pp^cC$m!|P zDH)PCh`yT`WLILzqzGp>aFN9u%*>4)#OP)wYf{$Rz80FJNUOq$cbI zpp_6uk3Gpy{O`L;!lgN*gwQ^8UKUwhnt=98vfF=lh=gtrWVjq;M^WD~Li-C(w!x!G zY3c3CEs0u-9$TYpOWnkNU7etjKN=i;(yu$8yO!FfFgW07^^kXIVnquD3W2p>%hx#0 zK=OW4sCrE6YSZ^zep!8jqh#7@dU^u?l*cX20$cjNPX~U}#6E zSQKJP_(3Nkc+)}e>aiE|d4tExqNWEiiYWVoYok(hqUh4X?*?RTcpERc%gsS5qaGnpFZyJUQgITYb?vjw3~$g+Nh1Irs=10^{R1dw0G?Ht#6t z9TLJ6Ci&5vHj9RBq;$ z;dnA7b1U7uDu1AOP2;XLV=4ax9*649+ey{$qa#KNf9CGhj{Ki;&VBuI=Zv8ly4ijE zOLs?ccn%75-d!sBb9JaVi6eYLs2Vr(&|qn8vPW&bGRtsZFFV?^#A$Tk>|e+ObZ<1! z@y}{)hjVS(osDZ^b`_3rf&_Uon!3!JO@+OgUPgG3k|rO~lcxHY^oXQyj1k?`8dOjX zQI{@tBPwy;0NjJP$(36Mx^fB!=a$3LynB{{H>uXr*p0;$=QOch4y0W8Tt#befrI_hA|_|ct| z*&vhp$mtfV=h{#lE)s2QHlo=fhkUR2K~2DWiSK83I^dVv8w`8#!~Qg)XNB!>kP*|m zzm1DfzBPj@K4{=!cn}ft*|G(U;bJzq+ypaC=(|1BRf`wAGPj{LeQnEIh2vHDFI-~rn|CxE8RA6&wYB)G zJY(loufsV}f_ZRpLA_uuk9K3OxmN5}MrTW=c{amGo*CEbLtwGGT%CY9sst?z+gZ-+ zK<1yC7;is&!^Whn@P9m?;Z*S$!%VIggy92WS+u-ywW8WG368ADt_mX}u zV2-SaZblC;FSQa8I#e0hff^X;&Qdc)CL&C~X?Ch*uT+{R%{(67ZGQtFwkX{47UCY1 zzhVN3{rMbX7U%vhA`QKhZ8$TuwHT8Rz%~&fJKW*M;etz5ZZyGh7SZ8oSt`s&l zoX4vE|K#U!Jo;g}vq@Wf07U6E-H)g)bB(3Bd>E)lc@d?Q`4}YG$y+C zGP_ue2*?JD%9f;P|I&^!wKJI1WC+q`0tctv-=e z$3p&Qtn9E^m^L@|q`%)(E5_O%_>OOZ9?PBJ$ckj;!t$?m=f;r?S7j(pczBjwEdG6k zdK#1KHg0cw4KnUhIb%wgSY}#jmZshk@;H#_&x1;S;b?DLo?q~(u|q#IzRa@qQS~aRb8*c} z>t&=fX}5R~%sj)A1sISRQOc6LPnAhUkl!uS>`+SJfBKj4dlQ?Nu}TpRsz+3zby~hN zV4Q(ugj^jd-+h4bQQl=rLxg#>4vV`? zwS+@v%!T=2g7;|G)Xp&3(pFipU#Ck1q?^b#jhrvMO}4ZPH1s%@7=QoedqVjOkWN^4 z7I?T?OB4>3VXzSlVf@z;BjVe)g9}w8-V7P-5+qO!(`SrwbD%V>I)V=PEEV9>!$#*D zVkb($K>tFlKicjqhQ&trsa42;Pn@bPI_(WCyOd407Y^3&G{8f|O#V+8n|LXx+!_0y zinWSrG)B+!r75DM1QIAa<~%okUKH$)1A2BU&9h(zXsPDiTc&_F1NDOCFox074);Id z3~A=pBD)Z*EhV&_TN5hfs@4j^xkbn!$R~#GQ)MIl{k*K;jP?(5%(V zzQLFSuUaOXc4~7$_R$er^G?w$g3L@8*Zf+_%75VmOwn|rTP1aC+@+R*ecMsiV|dc` zaPAD)sQyduJH2crN#Hd~dz}~S`>29S!QTSRoR=BOU02N*CG0{hO_8a*qtAOmPC)>4 zWY29C^QzNO+$bYseL&R=kIt)QjRERogZs=I%NYyB{mwU^`dEYWnvxm}HUO*^uqQa# zgad2Xf|p!(OhnxkCQdhM1`&y=LOv+;OH zAICyx5Isd1sew1=JRtpP=mXsBg03N7QkV3Jf2(EowvB}@6MIWzswxON@G$J25U>X* zOAzKsJdBZa&I^)dMz1B0#o7+Hg}Qx}>mkaca`NUZB~P#i4I*6ek1Jlidu5aOot-k! z&9kTB%p(l!?5_w{*}B;JNWMq=%x8WXB?Ue|-xo3_@i)<~b3tBiamY%EaI`+7n5kQ? z0A2Zfem`1z77r5?8}g&TiSq^j)GR|odLQ2QcU%EL%icRZSwvC6}J9K4B+%SAIU zTbgIB9?-tqN=Kl=TUs7?A3T`S@h5T)^!P=gA{Z-$D>P5`CIPKoqjq!jwP&-#?;BOM@tU2|tGVZh5p_N@IC zmYXd{bMe@A0N+j6ZXFQ#I-I7MI(?)t-Wan*MCwjix?7j*(0gVFw(y6Hl1Hb1OlDPo z?L0SRPF8h+G+Xw(E8@YU!Y8+OI9Y?M?DSsz&YMtZ)Ls9peumg!G^p`I!eG!M{?0_@ zX;wV_a5BnIz0UL`t&Zp$mSY=|zmfu*XBr?YSP6z-SD{CxMW+V_i_Vx7 zz0HjL$z}6ji|gkE1^}pXjbF)uAMh9}gS)j%fHfr2j}&s#CndRWptKhfOwJ|y6PM=a zR48X!3moDR1nmCRl2VMZ`mDgP6hx^-))L<|*r9OOhlHQ70~s&+5LM@DN&nH4hE_0R zxhlT7TlpoJUPux=|KC-&j_Q5r3g^)r8sh@_lTp&mx^QRfy}?kGC%^nZa{Nr>XvSA~ zV(pyWUsgn&FDWFC(PrBEPmP0%Wxtz`1X#E6$%l0$a*OSbW*y;YOwdFFF;A9Y@{Up zOuX{rO&?5SOo>ur#$*(s9Z=Q?)|5-^=SLzDtS6KE$Lg0{xS0=Alo4ilBg zu1V9AmPB>dsMxY`Q7?k%r?KkkuI_Nfypq&L8?^n2%gCq)V%PQu zj2OZ3w7pw7o&~hAPhvgP_PIJTz$~eiLN=q(Xk{onza-5t(~4tr=iIgOl8O9@Ly{hG zpi>sQJdV_;*%7J;&N!PfumwIpbIcY$+>ZTUYaczIzt9Msp*T;C1v0^WIorTF=V~Rw^uZfs#@YzTI=JkjxL4?#)!ipECPrh9a5&BK6X|^LmZf@r_U(ziH@vApe1{wFW z7%ROk6@G7WL*ALzLIX;i1gWg<(q({_D=Qw}v?jw7T}zC`qu1n#M?iHTfjqcGsP>$Y zb8&uM^G5m#e*;(UL9|(W{^>|EROKw?pV(i2 zR$W9zNno4MUvziu+F`|=HVLb*1HeGNrMj`0CeEU}7x__JqoC7>tRDTB;( z5~z&mx#>$`Y8ZK82sTb4!y{)ER%nMB6dibGw8JMZhETtumr9)zjpQJ&@%}=VT`}lb z`XuU-K$t+aODC3-01v;{na&Fp`-U43sE-I2eK1YlOOy}1Y|w{oS>r!|Wv{v+%>AS- zY%Yvz{kB^_W-h%QP1>p)r zV~Jz<;(ThJW)r&Y6@PeHbl>!EGCxwfUtcQPe6V5}Q!Ou)7)E7CeKfT;j0sak8R`;J zW@$vAJMpEwANx*PCx!eeRxMfDIaC76#18|g9cbfg@%ZyY9FLjG`#B@=gplQRKlekXg{1SD184Z_S-T01TAE*!aEWD6z^D7=l$SL<4A$IOS=pe) zf3OX_4vmC>_o8g$+GCYF9&q%$+t<${NpcQ1{(k^~yQHf0ZqJN3>Pg>eWGmHQsYq9@ zY;oehIC>p3n*?$(qqqls)0Ie5@gbUGR$StZ({|zuA0Tre7=c_jnO&wxitq+b4hb{q zRev=2eQyc2Kk4nkqAFfNGR2NjY6*KU${NV49Ze3Z!N9@pid4n%yJ#9bClc5Cg7c8$}(odztiNir+`rv zXo~Z-?!m_hGE=}8ML~8*LQYBWgE)64RiZ<7^Ue8FEYx2@;iB1_z>6rWKyK~sK+H&0 z!`T<-Z_UW1@3W03ja=cq^GG4yjmkS**m)e>q+RbwDly^{CdbIE&e*SN{M;5I=_#Yd zJv;aEFc9Z}IV8f>C=^-F%sx>{#*^aado;)JflgHYI)y)cfn_~6faw(dna{Ti#`2WY zxAtVf>Ig4-fK3?=Lt;;)^0r_iq*B<5H8S;%V#YE<#^nxm%pc|tpz$RD<*+&oD4yLw zR_?|MJQJeWjEm3N^Qm$L^?WJ-XWVb?w1oT!`Z&{MLveO!sQ+q3hwQC4?|X$dJw^|b z)JSR$^ycM>fK;QO@yMFs+SbPIfa3x4H1!eB2j>bI{p*nR+WVYVvBI{O12ed`K{0=2 zm$CIfOfOz}i0uZV4CwM*FCp5)KcICXl0sR|C=UEnr%GaAtM1syHh~cbabwEU$Brmk z!FE|3!4J$pqcX8$uYl|09`qlz+8A8F9EHyIMqIKFOC|fhwWsiqHhWw%JYWwDsXG}o zzo(!v9*8KpbbP$-TmnQc=F{unWG6LvyM?0U&gY#VnfNu5uY*=x>V32oUqWva-JCciff@(xhK+LlR&#Mg#nwd-R<}u0P1F?$Tyh|5I|hNy zFjT_h?8Df6%K;|nIEFl=bgTt#SG;R8g9A4t0VyUsvKe0~H|=kVJAY2OXr*Z`OlgiL5$s@LuVZ0O2|blSKesiOxpO*q9N|HCh!r zcpt-qiW5&_$80=E-bR^&NQ|k>kKZ*%QqtihX0xDu-+TKr@dl!-l8j{`4lA^%GVPaN zB$nHiN&@-yml+_M<2M1L8~nR(+)s&063#jZM}Pp6kD!pe{Rp!L2ia!Jk zR`g={gFoEf-N$+1s#rB3+oGZVO8sFFyDCh#$wT9PJ_n}`ALuT`dA0o42HG9}QA86e zVv*xU87G5;0Ubv77Kq#l(hC%T7fRYDUe`rt(ja5)N|>NG6@ZrodARyyAaXLNhVNgt zf!I@tm_^Hy?v9VNo!4@1r!|<}uPbogQwOw+G~~GAhj9Y6zl3y5lW)^L8ZnAY)LYI?uus(EPB;xinBg zz#L_sl9leVy-B<<^dTm}f4P?~B5oN>4TGTC`-g;JD=HK?8$WL7#=mej?u+I~qIy%E zVA1$d3E8?}w`3y2)=bkQ!^^g&#*2L{d>VY15bS|4C2^o_l}#+*D4=9buy{c5VE=c6 zZNz(lG3 zgTvNt2f8Zqh-Bgjx!5O%a=vO>8z%&kz~9VsTbZ6b*mYPBFvk~B`35t68tigmpDNuc zSXDp?i!~GVw#>YH0e5v;YL(aJRecF|?L1xjM=g}z(7fDA`IHD-P6TFOe}&-CBFfbu znV*rmDK-ALfws-aM*3F8;qt*g7ptqy<`*1Rl;PE$7`6A&-n>iVD^n|!uCcx5(0A-B z%eM-fEh%KctT=nyO`+4?eY&wQFiTpJ+R3X*7$#kT<$qrTJTNn zz+1Fy7wCNi^q)=cP=&A@u+M0i5C7Ehog-F{Vj5|@g*DF$@M^H`;5%ESl0S5b6K1Pc z7}JsMY*Av)1dY)iIKP)_Wr+(YG~ey5PxVFM#s?1^ z(uh^$(R(M@kj)gO5ZN?Ew~9I}u{n<7)~%Fqz7hyU!{U6Y7cdIINkUVciCM7c+6tBm zY~gjuv_`F>SAX~lZ!@F0gbvgkKE-un&|(T$HLc_{1Qw@I`0dq{Iy%k(X9%EpmF1K8 z%}zcgbPY&^TdK*-xqu-vVp25r?req9yW4VU6JIrEmH#y8B`EGkn}U6ssrKL3zT(#O z5@Kc2*GrxmS*d3Sb)ObkoIf8J_ckfLqO=X-iU)8E}qR#J1mq&F+kQU z!U(3_eT3)qrY++#@9}CFIF=XvdP9H|Hw&wFmY^58`^G|0P45r)LaymZz~Cht{_uyG zuoHOVM%7}BQL==mlajNudR^@TB6%4U{Pi@?WS`@@(7IEF01q&Y{S8gzJ~ILYrAs&x z{~HpPAJ;O8qNtJ0Q|;PdWV3=DC>4mWKOvef5FcamfGP~Xyo=j}@nYiNSeNRI(hI%U z%0`wHZeL{;=>hJ$aqlq(pl%@uRd;W^!s^QCW11a^2_*S)5^RCId}OX9KAAtZ}#NC!P$wMzU41vgu^QUma&4-Vd@p|lZWhpDiY4U{VsY>VHxcI0&)Uazn zpURi1k&{ehBBTx!rpRj(NgR2#2LTr92;j4R8I(i}GypqX9+LXTJ1#9ZlgwT@XgWun z*e<|JtoMr>XM$e&fSkkdWk9Pf97mxV>n2*1YIHZOmk>dHtF(A&yCUY-4XfP7 zR77$>Les<31}rJaHLflpwEVOK;obB%iN`BKFbu#{Qw~8c4s@Z{n*sWE*(u1f&&! znZjevVod-wfM*PYWR&NfpGvIhJ`&xt|9V?1nrXMqmB%h?z!Wqe-nN8p+7fUQfntPr zU4lbmDi*NrtArP`mx;vk=oJQ?umEl8RZ>y&5%sL;dcyjxvkxzbJCqooU5mCQjWtzWWJL0s4RdSY%UU0t;ca*Ad z9eVTfUXwLI6GZHiO`kq{wQ6nT=Ji3k22Q zR+Z^N9Le!c$LQcvf#^Xri4q(=4f27OKF;w9*7L*HRNm7 zQRCtXR~TH1{9A6@J_V6+PQbh6t&rLW@(!rkQ-Wxs8%LrpkY1U{b!i%hcE0C8_~EQt zF;XBts6(f$^5aVFP#vLNw@3X>s0?@H0veUM9V57zA8ODlWggrN@^NB_Q~kC7$0V6F zh>1%wR~0k2*(K@7za9H6hVoS7p%QQiu(D-h4Ko}oJHU5IB)+>3WLuriO?>@SQnSW{;O*(3E*bBoLTI!AN0`xy6GO!^50jU zUO0&_eVKS(Q$~y{l-mgB5o|%#>Dwg9i(2X8Q0;ovcwR{bLLhlYxEzK0ayf(@HIaQ^ z7rNu^pjWc7mM{kgdW(*m6_n{UB`z1KHl_LEr}?0|$U}c!d0c6)yu%%%<(CDFGF$YDl0YSf)bg3NCwp`jImZgdwy-KNNx~)Dg)Vr07d|6eOIs>mv^z9}Vr_Rq~}zlMUD_ z`twGS-I#4@1@BIhMEv@Tt~h-|msK1qT+PdJG9#daM>(1ITsbig@!!-k--%oi0?_66 z>$ph%i;4asj`n?T83Uj*%yX2k(5(5}gAO z+}bVJcEd9Ka*xkeqFjvS=A5O327l5hHJ#%QSji#R@nrnMG(wigRe@oi_p`oz* z9QWUwyl6TU=l1@vssq#r=qwT#{Y5V)T*D_=g&QF3&CroH0tyYY#uLY>4(dmBu~819 zpnWu+aJZM9?Yim{&^3$=Xh&ZDi9sSIFwf_}DmB8eylT)$;{poQ&Rk{GiM{|wc)#0N z!5Wn%X0(72&|<=P%UxMH9@-5mn)A;kiz#JF$(WX|43KlcfauhBGq`R6XuID{QMyIy zW1vB#TLX35YGEIlLPO1&e!UI9a&cWE@*k0nF`tEBBwB?JL2v^FQP6XO31L|)kjieU zCMz_2+0uAcE`>O5HvMAH6h&RyWS9PRcHBi*>pYjY)ZpHW1~qCl$omtb@WDb!bjfRL zBjRw1d@uUgP`*1l{3ATjKN`C~hbn!dXl>kbdP--4k4_+i)|OgEpR)Ud)uT8;fnh`728~cn zv`7YoH>L;WLQt-{k5;CG-S1|z?9*5&|PZZcNZoEH~ zQC+x`>a>wR_uL7IpPU}Gh|%x%z$$0g6>@)^7=mbEX)9OWkOM#9n_2&Q0I z=r+F0>V#HaPW-2lwXl621;;Gc74k*W+M_*w0M46O2Cdnq1W}wE4YPrBre`2S80JNw zFT1LO#gM8V1*EbbGdmMB-SJV7FfY#ay0J$aq}FEIOUg!VJPD9b7a^zTGuz2CR@#fJQ*M?gnJ07c zHHQ2x|2^UU%(9r6<3s>b2oANCn$odHV}d|H7==QX2cFj&bn|If6`Dg&t~?={$Qo*A zl8qaKleOG=Fv1;1*yF$ph(9cQrioJjk}rP@J4UwQkDh73Xf|h@KZxHT>v6GI+LF`E z5{~mcMx<0m-}}JgQubcY1FwgKm7hk~A_#E4kKyX|Zruy(p&n3!aHFsCK=gf@^iQwK z#w0>L@Myn}a#EnKEzg@@%pG$UBgSXmQSxrSUIN$LX*aO2R9ZD=#?6hk>2-HaQvGu@ zz_txm5Qza4Hu~IPc~KP?jVDfa`S` z+c*&S?ak2*zStB_$E_z?!O^hErGg*(E=!qG>_BcrKs!{37-B#^gqriqj}Lxwcmu5P zC>P0A1bLZZ=VrltB7!l>^@2)Ln`G5CZW>NXZju_!A@6GHTUbh|$Sc`lzE7vOwPCb+ z`Ke>ro0~Pq^KVN?xHfOx{Kd6Hw1CWzkwSQ9>!lK-_E*GCfVz}1`Xl=_Azfexd4mN& zQYxRwCm<9-*5G|axKhJ9GUzy>3(#{b8%169t{dj>$o}_{^}_(eoO$^jBN`?y03mHJ zkCM&p==$guJTlAWBt)oD(IURqD`}Fzc8+@oYxtUoB6*jmaa#(0b4DFKbrA5iiIFN+ zgQwxQi)b4OJ8T~4emH%be>7}PRQbmXM7w&LIcWMPu1sdSq#4Gc4JxBd|0_K^)jq2R z*TaNautx8QW!*$Io0OSDZk(rC&CPcu>zecFcx)cxjh*T|ZVQ_E%>1|rVgPEq`Vs7H za?qS&rpwUr0& z%$UYf{XYE9BPt^Fk}tvGQ7QUg+tz`-KXiE)`N*Lw5F**n#(lR~*~rTSIOj5(OPa={ zG=#bU2;}1hCTeks&W_ol9i@y?8Lx+I^_YP=-4i*1KEmrTsvEm1s*zvkDC{PcnPSM$ zkwOb?P4D&bi`06DjNqO{`p0_vABP~u9F*5LPZRQ@pL{0=n9RnFeTs-D%F0c}o%Apv zpdSRSWKgzqr(0gpZ6}FaEDM%q9rktk-)JT=7~aQ3_znh?v!(eE=Vzu8#Gk9rf4j)f z)mQ!y%WJ^ZM8N`f?t=?=008LYgxB2MKufL#OJb6S+laGFhZ09M-JAa2T86M&IS7le zY2tfIPTxsXOAUg7O*1^bd-=U(Z@(EPjkqd<#?vF`M*t1W*)pV3k<=+!U2t2PfO}j} zrtnId=qk3kLu3$2NxJF3qoxwD=a`^)l3m2w-KX;99@z$J4S4UZEe#*3+yOLrZIH|F z)2){^-$6i$$r(YxX}7;R?|+CbktAWnQW~P2B~@fvY_@4QRfPs_k~=0Rt+Gn$*Rq9v zvv%3KeqQrSms<`lEG_p0NME2j7Bu-nDr7={)~_+6dUh>b=aJ}fNl3!{wV#nEaV5SH zA&7HTteFw6k7}aM%|~W{>~$N4$bwj^%^7(~JI~To_76vClH^aZ24;h)ALWPLX12NT z5nb)wvVfWH|B~>Fm3&_FJl+yYLeA6YMSe5%>0m{8CHvNjv#3ap2n8r(qRf$sRB7nti#W5Au2lbkA^VAU++W(nh1&$CRIYGcMImtGYl>F z_QrwpaWx;u*pk)<@Z7?Zp@s(>%XdXljxRQ`ScM9p)q@53OYr0CXNaARwza*X=h}1? zE%nN2-A;#M)+s(IQ>UZmjp8l#dAL$h9_0qvx9hS}`_MDZKNk4Bq{~Wo^n|Ji1j&{o z3yPAv0G}=j_?M4JpOpLn0dDy$plY6_VKfza-EE3VoQ5mJKR;%c&EBsx00I{1gq6K~ z?MTwCPVCzoc*!~nRRJqs=~*WCEv%LCbnOoZU&aqk_#}a^G$V-64JNP*E$49-4Eaf5 z@V%9z&D?I9*C3cdz4jvPG@IF;CGjK4{F)bU_vX(5S>*}P`+~Ld>+mv{-7ylhurRCv z6Ag@%1M_9f&X$7nk|okJ9EN8dg@JjYm_3f8gT!G0A_sa2Lk3IiIY06h&l66C`6T*4 z!_1L7jo|w{>IcixcI2-VI$>WyD%7boQ9cO#t@6TL^HHgGP7aEA&Fk4H+VfwAe#<{7 z+>OPw==NqDA1>+V)Z4n&V-&*euJ{Jj`jjl2ow ztQkPPD6x~SixqJ&7!Cvl(A6L3Khnc^;Fvn2fVq!{s+*RsmCB=}pp@qwOsz*#kG#G@ zFFRQNkeL$>xk(~z&)$@Sz%fc(ur$x*g#C< z%Yq%ADX=FM^0{90SGc~mum;Hs5w>gP->z}^5g%$o0(4&@qj?c z$o{tI1AnXmh(@+9HFcL5;UPKIRS_MlI7UrK5qtwAg)x#`MhNj`Uz?V;;S+N`0bS=L z9BIx=MZc~2FoNJyLO}b6sO{1E9NMPcO^X9cbpr_TACYh);%)yd$DKBnv0c1tE3d<_ zNnk?V$>xT7V4-w6KBy4$OK~%_@OlHRRDlw~8p=w=$rks_m~tGJgj-E=El`GxL<4yh3?=;Jmwx?$W3XC- zR58NbPVx5PPpU)b_y3_WEEu^~Ea@M$QLM+UIStsSG>riFIlYiP1icwv5# z^<3Y?@y_peQFDH#Y@zmNG&j`t0|HDH@)QA!1(f)#<$Nh59sSV7WP}PYw0wPx$=Pp$ zPzz@cF~=>H_~ zC{Cr*bLGuGe;_-bXQIaU1(aHN!CHO-V+NyTc9ox_4mIf{G+NJsQ>qcZh9J#{wF%c!#wyEqd{)3kze{-M9wSAP;?PvjU5gxcktcG`{(aMh#j2^PV0x{tHsA2 z>^$Mkn|m_C2n zi!*+BRC4im!x|%5Tg6j*7ypU#W+*^Qixwa-X`>JDA@D>>sWHN{EgRTjczqLdVwd7EM;iV+!hlCB&N>>`}s7z9_53Ia{cz`YCch1pu@|HhF@Fxu^nytNn%-SDCt)$LMrLbncqA<*hY?xTyd#g!D^7wo%91^oJmwYk$q+V> zX5GsgcPxGoQ?D^nTOj4n5Oa;azjS#q>}$$Rt>kleSFm;wq#)tv*DFY=H6kLv*iT72FAk!XDpYX4MjRt%1oqUj5$J z{DIoI6RS)xpX&KBI-%xk0Fv>Q{Ng5n{m2SCV#o0Cc#ec|Ur=)omo|t!xgDc}47L)9crp%Oozri4MqxR>O1GROrmkdOjBcioLRa&~6=Ee{Ou0QWNd%kPic2kC zVvqt)k7Mm+L2)VF?l`F#-Z_}xsf9d}HH_QH?b@G~-y^Ybh~d)uIe#%vkm zk@rvGYq&kLIBg!5feY6HX6_>C{BFxyq#zT0$HkoopOIY#{_{5abzH#vjj^1uOJQ1O z(|i_H2r)@v#qzv!U)5?)q=H8g+xs@eb@(lUZ=?zxP!;i?b)1)5Z}3S10LR@i_zkNI zwG`C+1yoaI`P0xYt$FL~@$T?G{Uj<}|MBb=VY$R2vS;UZUZjYSBTL`Xw9i#DVEt$B0-ik z(LS@v+da7$CROpXgaaq0y)jb8k|i)= zkWQd#u}YUwH9@ZO%^D-2A?bz__+d4I|8geSS4f9+le^FDmxK--&<}Wk zWrW8ZYaX~^V59T><;=GPr3cjsmiuaNqsNjeL6tQt5k?`?OPx!NMow=S0O*NuK@B@d zB-qM~+JC}fGw@~XQqQ@KPCfKQD32R24!*&X67Epz{SKSk^=%C2A_F@69#V$HJK=hW zMFemv-OP8|_fErCe!{9tC=|Fd|KQAJD?bTAz9!PJ3$LkZ(obpX2%`D1A*b;Jv3M0f z1ugoh<`HMoigGUf+=$ej&epG#1{w1F=D`RW4AgIvLuK2T7ViDTpQ%|{<)ZOjZ5RlE zBPdaw|5Eo1E@_2PNPZ%=(-Po!bD3K+?p5*OyXV zx2D1#m(u2(F9h@+G!55Z5Yl+&1KnWFFr6iuP!TcveuSAP`X4peCFKw@PW0$$E~(N? zvvk@(O?p~YtpcP3g-=ZK@43AqNUWk(w~Y`69csHMusHc8K;FAv;zwjLy(;JUk2545 zVaz?^lB=VxT^F`2M0&o{aQ!!xGCjnr?pLotoOud%M{9!&oK_#Wms5+2F#0EZ(#^LRQiO3BCM{E|Qo&88zH%47s&CfZ zY!P2_y+Riq53VA(b(Kp&e^apzSL$EupeeEog%57Jwt10<*H{jxtKuDy+lqEYAtAG& z+5|~8`PCSt0kZC}WK^Ife6Z~d$^pHzafeP;xw8DvN*7H3a>_;z26O~2q?)a8t6YbZ zP3%aXgs^%?dIX$6Tl98K!L;om9zbzbu4yV$@?uay0+~#;JU``e-PQ&GWV4p;JVVZ? zr!!81^3*QZUjJ1MP#nV*X`-Y}vPTPoCj|IU@<*gM@VDq_E*hI4A>ZhF!Fuq-Fc)|y zTohB=xi4G*pM|G+~egYOO+7 zrZK$#lfFDy&fkG^B=;NE*L8fpf2J#!q;g~6{h6|k?~u$wt^kMFP0%%n?b=p3yi#XM zko{JJhB%PP4~5sfTFaub71T_#_J?#mynP8gRNeo7Doa$#R`xBGtYgM7h3rcryJX+V zzOPYAg(4ElnzdDSB}%TBJh79orrr@sD^dLFqnJJseE|6u6L;0m;w*MI zf0gKee)wZwTUvr` zKXI@ON&DV|xBi@+pU$X>>@&OG5g>4~Ib7Ey%DM2A;haTCo^G3O>;bAoPL&hxFnX&Z zy^;^xL*6Ub>q(WJrIe8^OQ4^#9~iw@Or~rTa$GpX;7-VV`DCi-_J{$kJ=<;c48%XEn5CAiZwWe95=;H_Xw9^2=puQIBXKq5VZKfY=||7^ND_yjkhaf+Z@O&j zo{l%o%6@UTfFa@gKv31?GO{w72Y)moS7Rt<*SWnuHHuTFQmp%!#QIGplcPS-MaOV; zhM$e1{65sx79sWBsFHVvw{G`NiJvp>hsMgr#WnVmwckoP9=yZOg3qUMis4g!Wx%k{ z56S5MZ_L8wI@|T#O2%vobIK^&!zen$1LfWl-yNxBNovv)lycs5&GX^Dp1K{ylZ}@$ z*mW+m4Fm^hBfY;3{yGpDoA@rQM_#+Sz<2tQtCp-koW!}q(KsR3V1Ve{K{a>cCqdth z+R2)jnT+*5ab?aLa!OO*7ueA}BC@q^!p6;orz5$@DoZ&7Hdiv`Y|f(gsm2nq<>`l( zB(Ls+^K2h2RBv77Y%~vGofZ8;SL!X9$o=aO`QqX{7rW5W0GZ+@_4|^!H$QS^J|?qk zpE^+fN={p$Hc004?TbHdj09b4XdQg~`l?h|=hj#E^zVs`rENoo{(KIrJ2UF#z^LHQ zh%#!wY}U>>Q%s-qL2(k4NDa`}xRD?Ju0w_b%T3+&pbr#&PFdi@|y%`Q8PRB;`>X zV}#2&s+?5ThCk6tO#?=iFX@|zq~jPJ_B*ybP-POLcM%Hh;e7hsV#aY~_IdGVyZq0G zdrLe&)HJn_(*H@hLRye=Gi|>6CCMIo8tRykr}nw(xzSH5UI;w!+1fhl#1*?cwq~>S z<2_uAGGVAK2U&Js66}wAYQ6Q`#rWPXV=oTNH>@v%=^V}*&e;@a)AN-3zC*saxu`6& zrIz|+b%~Zz!h&>1InhI^DWMyaY6&G=kDJS`KAg%6HgzQ{d6SjzaQ=X7#E_)!g5`Mr z_k;Pt`h9IK5%d>|(>I?@A)P4y4HG#h^eUh75qrPt%#pI81O-Z?FUFeHF2X+$_6Pc+ zF0*`4ec&T=M5FBE4xf@CYZ~wN;oUuN?y=wa9X#$D^XOhFrM_~uNoK9aprGWL?=Noe zzp;Jr`8&7lNY%rvhdPTiGV)!8Z8;Q*&fT#a_NO&1o^tK*clRCT{3e;JRY()HiMURH zdxzNt=l%T)MykD!Yn%$@M=ltjeeW`0)m!-e`n}-s8OLM$(n;ISaoSh->~=2rJh#mV z_NXyzvsem6DeDjm>1~lfj|h12xg_Qxz1h}b!THJbuG&z$o2^^zM@w2GA_MtYrCY8f z9`^r6=bXyf5HY$HwObqJ*BUjgeL-Y1{{zm}bN5rVF7Ep>cg{_;Jrb0v#iPyY7aO(xEqL>!HYbMdv?6=a zB0h7vI(*`|M_Z)jE5&)I^da%GPKEmPk|@oG&cDWvTDrb4F{cgrRCrM_?0jmDQK`o{ z2gz$KNp(Az1xbc-uMX2HU*J^K-DYrP>dU*n3&&msQ@`7jD9Zhn6eXS}ocCu$Ir051 ztq;VU+kcQ|mh0BGF|Ql8G8qiDwcIFIL8jE}E3^7BKTfThTeg$cO9~I>-d*hRl;v-VD<76fwy9 zTn%eo3~MrHyuR=ivH#BR3x0e%kYoDaYya(7!Cb%J^Rl^ zG8~cMqYqDaq;?mG8YpQmQktS6*`0IW`pPfXL)4x3bz%ChJSJh68l0`i3{I;Q*-Cdd zs0|QD{3d%Bh046KH6u=9nmQu*`P|{djBl%K=5+MBJQ4)y3jPRQHE&Ws*V#NW?(hGu zXt)AF#PIRyr%lSmS(?Y#NH$L)vVzzX-LjwiNZ$5R-n55ziw--V_x`?e2ZcPPnm|VG zSfcVro7Ar-?SHS9WBKt(kd10sus*#n#YrFf>HF6X_&MY1jD*q@j6R2B)+ zY&NqHrEhLGs#mks)-2<$EIwE;t$2rO&Vc$G=ka-&#uS+I^=_M>oMEz~bBTy++XCUd z6g#{Y*l2g3yDZe9QG1yU#q7*t z>Yz8Ys48ua6)VUpu6uF+D7DhwPd}){4?YnSKG4s1GqaCr@1tZBvxD`KF}4W;38QCJ zTZxo{s}m3A{^0N;7Wp7loVK?vrg}m=j8RNp(8uapM%A_=V7I#pm2-&_XM-K_O3VmJp zQ`mf;QR)Pz+tpi(ME&2pT4XLw6uVW-X0qp`Q1-m>zNd-O|2ot&-Xy%wMXc1sOg5lB zLQ83PxmE~K;tzwo&Euro)w4Vp2Q~5oZ{O~o#FMYm-~OtXjSLY zvAm*M>@|6ADza;b$BBdP0d$EqNlHD@v@sGql;ljb9Tm-6#kiPKc{fp8{VvNrrTp^F z@5ij~3tyd(ur>C2?OM^F8=TPI`$#&K^Vh+!H#wPd6FXIHavyHb`qZH<`npW8_>pmI zCfjpFuEYKiA|LhJn|A~zsywWDLUvvL<;&>ZPb7YRr@LzEaks&1J-r=X%zY>!j~<%r7d5LInHUjoC1JXje3+Z_ zz|E5e+C%njk3+JrA-8*yI?ns34=b7To%bBio9JTPA5CG zaEd|R+O&4iPFpxnRwL{ivYWC=#jo=BCvL^c{2vWGB&lT@W&E#R&OMF4)w@42n!4@a zmhH5LN_!rb4_pI$Z%?#Hq*-yOob){v#FZ^8I^1bLWjg2^eO)aW;P*TJ7{vyktzU%us|8#J* zZY9yLx)7uw_WsgbAX#3N~jmsPhz#c5UXS z4-fW_|ByOuz+@0mclCVy&$}n(%-mlzatel@c+!{H4?md@$`R&iRam1$EMW0vQxnYZ>KtGeH~O zcH5svrD}C+l8%hU_Wp^uc|bay?agq7?CkYG`iu8Mj~3bzRi*WBOGp*btZZVO;5pyf zvE!70ZG7vF_%qUH;WMKT6kmO%=<1oxzuZ%re7HS#P`~Zb`NQre=@#dA%N~wj=$*KL zAg#_h(1k2nWaIF6h`GcPe&vcuL2$Z;EskH|NlMzhti(ftmH@&A!{#a$%4|KKUz)(w;K* za4vGPUZJwKaj`&grTDCqU#^7cY8S~xl4Oj%^xm;2$ad!z>KDHofnPX~=^4x#lI_Z5 zEMLhHdCX@RInAKX-qodFYCG9i%pI^m|`yJ z60a_JcnTQf(!X)o<9&_ps@ZAlPxNfvu9PE^F7@yukEMMEh_A~8Gn_bcylt=C(=-*f zf#f0{-X_z1DJ_Vqg!V11wAm%w4chGdxb|>8S1MuL+ZA>}B6ZImw*#geR58PY-DOV7 z_K(UsqqlMU*1Y`aCLx}ddzydYMAKMXMpo1Ti5^rh4^gPYWTX7ERPNwC>U%>pD!YPz zT)7t6Epn?o-FKjvL54id#gUXFk^!atW!&>SqQ~XQe#x`c4UA(4?)K_+#*bI0onlYP zDAeh`bz1aw?dcl@P9e7C`iBp|Y483t$;zxM*KuvgfwRpUwkPi8JRUj$jP3F z`h~(*tqeZuC!^z&UhAn1YH1`GFnsh_6 zo4%Vx8>L-+m-Qs%u+B%r+i#ReHOl2TZPykg7j0zB2&KxT{t@tD%X6uOHxm zMUTqleRPMBNfFG++rC3r*dtSsT>8wm$HbwzJ->7W{B+7q-}PSeFn{u{aZ>GVl#w{O;Gz+LDWdyk&Qcu5(1WGJn5 zKlv{!abF|f+>WZUCkqw^KL;H59UBncStoQ}$xEo7!be&&>`$)(&1TX{#cIRAX{PKW z=hGHj-dmhJrkhKjevs?ET4NHC*s$f0-=WKA8gqHn?mz1JC_JlRp{HJIaN82;WNgau zG%0F^!jSUEZ{@V!ilK7v97YP0YebI%&r+st@*Mr{NRmHCuP++!G!uAF@qT}F27_Gq z#T+v=AJPw$M|V~kKC`i6X-)gHk1xzkD?Zypn<2lI*P3H~K`xB=i-pRWO`=w(`YtX0 z-1X|Du~!Tm&DBl1>UW}x$!9}@-r9Q$3G?d}J_y~W6)zs$V|1$Jh6#g~*(OfDqFN)n zzSMp6mW%_ipYF_=5gegJo10?WzwoFi{L+~2t+F?InR_BSiIT*d%6+!6Oa^vY{G;o@ zW7l&&DloYui~N2>?rgB{&m(E(GR109Tx|I|+jv{&l(z8xqLb%8l0bP{N?jd!dz1L`+=sK<#(bne2pB6nRc@YrVeCV%QfqucC- z2_@IwRb+5T-kPy#@20To(0k%s7NjHtBtxSiFe@fXHipsj8Kp2DbzV1Q5wbEGA0tJ zH)jrD@E;DZ@8>F|*=7>8w>|U-*}GWfDd)Nx4o%ZR2?ufh+~}bLUi^qiy3XYJJ^HZ+ zt*lM8tlG&+=XM?|yiamthr;_;49AP%y632-Rb| zYs_VC*RyYvvzJhMjGV?@>{(YX95mERe^G6sq&^i^{4nzDv3@d}da1Yfk5C#6JAJl# zE70amblAPyzRT{|2P$Rr&|lwop6Q>Rw-lJ#P0P(dX$JFssdMx}b9a_mw}_;(_ML?Q zb_wYYssdDY-z zL%M+v@BI+3gd4QcDi7a#9A#66eyD8DsNBX`2qjsrL8b?E!txaS$3nM7aGqTzx zx>Z50Gm9x{`>v+$`TQuq&Siv>zkJ67t3n$pS1%ipE24A*L6ZtQ9l6hc`th6Y+NX}) z(!cgh7Ko)AI}U#6KMQ-I^ZoIKPfuIUj?w0tzIxAc)<*GzDI(x-1*^*}wSar0ym)Y@ zoh970&o_X5FKs0al0roSc&D^IDb=L=^1Xwi6@qWe41@Z9$o%$*s5`0ba-Wn*lFh5& zrqX)_Aw$a3ZoPMzZrD8grbI(#w~2dtkd5Z&re}|ye3-DMxxh6kTkFvwyy`1=eCO_<4BEEJ0if5 zK33(VX5VXN6h-3KMwfC)R&Smyov+_Bf2)PH?TDZ;`*SP|uCmb=XN0q&Kd@oN@v|jPQr>*ZeQ(x5gV@6S$zxi`}9Z~4i zr0$t5CErc+_Z~(SSuvA7bF7K!3H<0x@xv(6>kGO6Tewcvh|`uKA_0GtN$pFEl$4^+ zJQ7YcW2L%hm8DOQHahCOVrS46yUtp!4nH}5fr70n_1D#d(WOxZ5(y%qw8CK?gI@Bf z8eTu7XPU0%2xi>4W!x2hKGfZXTY^f?$Xo8R?_Fo|{^MuEMh^(b0Vq!EIhrS z!Biuaq8RpWo6JxT@!7<4(LvOjqMi5OHH};vWsqcW);yg4G=|vQae(YV*dK-0zg!+z z&pf!Er7L^5HU6tWzeUSk`n-w~rKiES&o`PFUwQd6xctrw#MF@P^lyrKm83*&jfATq zI^D3rP7jh_O*$`VnvB&lZzu;E=$M?0kF6W~>dC=)V?kJFT&_Rze&ma5#Tr{D)o6x2 zFKxD{Q|MBj*~F?+T*jSbA(=?sadG~&U{~rH(Oq6_QH(OlwDA!R#oGIh-Ly}tWe7jN zC)0=|BT1a-&R&}8#WbPc?__ozXme=s0p8S-&fiD6ka!?9@CQt^TYQIH3ai8qcN?0h zRE}pTs|MMO0xDkQ?3JHfh?m!;-ABlB4!!#2^=2!=Ui@0N`ll(~s#8BV_*vFEnR?GK)vCnJ6rF$?S%$ZW{2 z7t=a0OD(f!*43yi>!vK<=a0r)AB^prqu1Rn)73yLUG|w|Ub9x(!RK0x`>*`tVTA(w z{j3)CTr#V@GX_VzqJGOX+uWiF8@j~}zw#5t@Ui6P!OH6o2bla%pTB-%P^#OIUoJTGQ@UEv$C)I-_`-O7`OJhT8hQQ?QV2@AaJdNYeujryHB7y(Y@u7ksJs z&5w|WAAkK>+?q;$mbm+H4x?MVjBM=LCuAK4qqW2JT&kAS8CA_vj$WL1Lkmuxu$&lV zN}|)+7EgVTk>5_1`RbkQDz{$Cdk&2QrSF^;nIuxv0}e0@Mhp&72XEgeC|cz^p2>Q? z!Z>Ps>+#%e0lR{l(o==RPWe0N&5r*WdSkoAM^UIzwdkV{)$0p)4IU*-`0&5bpVLaG za@&+I#~^9c_;X$-k9Ov(@Kw&y7&?VbHO6lf$qp9Qb3XFtX?NWxF|?TL% zkKQG>L*cg7dpowz(N*`SNWLUT0gAc z(s1GJ+_B+%jgE>VgA^@vk`7}1W^C_R!lPtuDDNN@zg!9OJ|LkrY*t&QJ^5|7!#i8{ zYJ;%Hth?QJ+1m??e&c={E4$?+2jeVX<>8o#=$3@hz#CigrNxsqn1{TKthh9aPi*tm zPnnGEAYtr`FnQ2A#lnzwx$TZO$2J#(dQ=N!(`*DWO1SO}dT4b%v^>HPUm z&lV|USr=8{?l;ry*I3WLF+2Um(PL9RZL?k9o|i)=cP#CWS%-*R&zBf~UiD*_yKMLu zr-z3R{`{gg%59`Fduk}r`UvBdv`bfawXs}Pe=6U0Pi64oy#nNIc?UC*DIGb^DHdV# zBKZ)*R}bF%g`JWcZ9DD5u;|vPD>~BXF-+-PQQrF}+c-|4!%LIO;j3U9v5TFA&#hRh zgr-;593n@*w{i3>l#}@O*oSHQH(YnA{Cee#=48_gzuTwCKS$|xlt~>j=jY+nbgCSs zxSe#cw?igpSl-ynyjwN;L5z62re`HrsKU=nm*0e)ZzZnNpe;Yx$B-5AP0psOXCgwX zt=amM{g>X0dlmB7-fo7?6X)cN!Z{qXALkl$F!XbMqUxD$Vr8W}b>=w3<+kT~`2&oG zWCd(M_qHr(I&js-%G&r>$y{C{5`^vNhE2&kJ6^<9B5*?NoC#=C7|v=NI3$Pv=0o zUxfAL8#?XLaoa_Qyr0eXc)zOhHPa{Qd!#q|VfxM?gpNX&Pv6Cpzo#M)^%q2Vb8h@} z%jDSe{h9vGZK@F^%z@*f)-?6v$Js{q%cZ{+^?Z<2k`m}*>qIR5;88q}sj`SbZxU^< z=l#2~($^MUe_08KX|zO0$0L%=RkqO_lA3N!k9*%PPI)?zukSjNttPNp^%nzdU(vN4 zYG>a(6K87jeR`;ziSGNrtp_8AB3K$K`i-BlZcRHpJzP2~-a1xMw&z!1{H5tUq=~b~ z=%;rS9a}gu)z~gvm$RO>%d&FRdG|PzlJ{wflbPM6>G&NoIg(qdEI5u;RUcPo>N}}R zsfEbNp0~W@QvWK!DK9p>r*_A?Ma@krbiQ-&Al{kj$MZD`UpOPSeR>yMl;6(!^R6b{ z^cng%c{y(HO?KuQ&7qn(S}#6b@8Uk$b`#M8YP;vxZKWjBic4d^==P z^SP5=;v*aT>xk@XDV-vR1c!7E_9rtb`8k!99nCqxYPQ)lPcBDRxy;(^Yo6K@Hhuqv zu_)#3!E>iY3ogCP@$;&m=&yRqF8D5Omsn6u**oTMM`=Egyk&YiFZhcP35v0PoJ<*FSb|^=~^XkgcAiO2Xcw{w$pDk@@2DXEp;$ zd~U>DKILAm7NtJL@7i|`eXAoD&2CmTM`dd|lJI$a-u}hjN4{F!uX*%qPx6>wcdU-h zSXod-f?2zDKqJk-Hbw?L@_4V+{$bgMD%V99zi!1u zzG2R4{-;So{SKj@0`{1C!QqlpZ!9j(Nanq`9$4&1r;?VzoAP7f3TNTiAz*W8L5min zJeiNrUGEbCn>|gbc?XU>(J?Z+Hpz<6h)tbHur$oVy z+@PHbyUu)mIBHX9o}OQJsdzMdK&wv4;6SHI$QMph;;wy~o`+^-yw4K}F>}q4vU>6b zInq6-DUYP7eNav%z=mAt`&=pV@t}QE?H~A8KB@OQnZ9OpUw=1Kgg>up2yePDb7yp5 zawsw-&Mk_p`jp+Zl<)9M4E%4ddQnBGTBaQ;s@4CL+ueJ&Liuu-RgLX#7n@@ax0wp5 z)E301^<`!hrIV>w)|NF+L!|kT*Q3}Uqwd4I9R7F|hYW+HomBqcU3zV4M{;|){ zQB`dJ>+o+ufuG_|YxxCm1`ca~DNO$G)wzmf&M^F7JMXtT;FU!>(mOO4c020#X!_f3 zsoVMd7%5qPHQD!wv5W*gZY$gP{hApXb|K>avHEXh>|S4)v0U8F+(G6hN7gI)B84H6 zr{+ZU>(EE4pXo2t?%c{{9i6f3wG=P=5$eO26Kb7BZKnEBY+|P_!4SVAeP;_Fiu>*c zUaJ;o>8ZRk@{_bILp---3qL1a?`c;V50l+H+Et}hzi=HUKe8EFWpCOjcQ2H>cH&{2 zmeqqoNo~!+6TDvj8q%+-cAt`MAhP8b`|~G&i#zBJwYi?i*O&2kK29d~OK8EJ72g^= zJQlijIWN)B2_>$Xu74`Az>h&!*!fD#Ir1i5Yr&dp4`RQwJXID*UXZBu>33nGpE@Dm z*X?bqGg?9suvcTiUT8E3<(MlUGV!IAt?G@D>Y2%^3_D`gA*0^czWr^n8Wm2WR|75| z^Q(0k-4yb$Yv085-nP?M#H2@$zEp~7*jv*p+fOf}E->nsw*MK4=}q^-^vB0O$UVBL z-lGsw=;YE;TKcA-Cia_(!`2sPV~pJ&oLaOpJmls(Nv81RQWOPS&R5B?J==#XZ^=F! z(``8RzG$waPA22*tkeByD}EdK)YubsMItG`edMfB5kc{SG0c9MVRGh{_p&+^o{COq zT)xB?B*1$qrGMgunaG&z<*^QqHdeiEEm?-UBtyRPo8nt43p(OtNS(fU-IOOibZEi# zSIQ2b+`-vfzfvzKQ`2qId|Hstxxe>bl(MI(+~-6crbp4LsdPhRx_c$aqU$vfMVxwP zzwGpU`8nNth`e3xvD~9A4W<$ja(#E~Z)Grga&37V&U`q;z<7Z8=;hlN$49tQ+sj>fc$z^&=56?e zZc{NT5_qhX@|RP+T`l?L_JuC@Dy%n`$8Yz1RLJz%W{|!hJ$}kE-h2EZQPHD2wXC%d zKU{CF*>*YV=%@qr%^R0y>`gvbO+Dg}r@l|V3;w}KE<#(M_{$HG1gqI|?LLFwCU*)^ zc;_GS2mZm=8*xk%FSi>n7;&hM%N{39{o>H)UX9H8=_QfSkV@%zs`9*|4GUZHAJX>P z+D%WR1evc%pMNCT)#hTNSj7E><_foxLZf#*+or zS)My}@MUx}6dR=_InT1U+%;sSH{y}}Lu##;aI{NeBqbScJy^`B32lFmHdXynCwYY1X3~@T(-3 zj$A!@BJ=ZBjzfvh`8%eLS4d_uiEYjmkPK<|K}~u%#+vT%=Tog1XUS36YhNt9)2Xmn z`Qz|B<&)<#RyVf)IcY4E^RcF!EPygxd2S4W=>6gNj^u}v^Y8`u$i0aY$1yP{;#WLZ z<3$QM&Qs|smQFTUU5q4o`{!P$vky%OcSt(NBh{HWr zZ}EM)Ecdv+IUd=XdUvng#n*m?%))J~_F4%-i12ycmI2M$H;fX6vaJk-XP!>K8!Iy$ zzRS}jDbd?Hb}xgAC*k+K#V%dF*4c`qWaqZkMYq108_Ih+cfN=2NWA%Iv7JsTeSS}J zdW(Nng6#~&?m-es`>f&)ez<M4#y>2qUI{^IKVE3gj{`@(dAh_qN z^v~??1tqAE1jOSPkhdL|Gb*tobeZiGDUq9kGh-DyBS5dBNuf|=UrKLe3s7n z$PvQ?cM8rbK6ah>tH)#3n?A3SqxD>Nx{sgEOid2%QOw=Xm5F#epCB&Wo!Wg~JaV>A z=seXOgNX1K4wCFe6Js@EX?!{6$=PFZ-dQ_^8|PI@BzHfT9K1*UTcq^j&{O8J44KX_zt@K?W**|UA$9j&y;O>52{Jn=jD%S@cX=4%)H zQb${E09!R(%87B^;Ukitu6+o$$1KTpd#zfO01FS#u{P~P&bFbi&s%Gu>NlO2&5JyL zpU*5QcKEd*q(XdDxgH zCcl1e-te?*yy1b*v>!xHAL#s)3X2Lf@M00lzPliZFnNpmg<`%87tK{98y#o=p`J7G zjnhB!%GAPh-^aCr?7Y*LJjo`%PO6K*zU+7u-0Fj%J9R);fkn7J&u(wIQ&y46yJyVLd-t2pB;b)vo>aA&E3Xg}^_R!jwDi_hmtuN3=2#g|3mMUk!HNvcx;L_J1R0W37P15_7?dID5GIX2QP63r*KyOUcw zTDZBpTADh5M^0v^$;m}gLTrL;;2{zvDky|=9gev!CMKZe<7_D)@8sw%Yw2e0YU}Lo zxb7Z_SJtXIn^{RQCiV6UOzwM-s!0OQ()prN7pZ-GncdK%@-b@3QSV zOaDKko@EO)0zReMlc$UCtIpbHPjq~moBqW0sNOJn_{7BbiJ|#c|N0S%@^WLh_L#nl z(S7~V#*Z$UC++NWGjjOptLt#dw79PCdxV>c;Y3n(R^Rl?g7-y_i?Yqj;@vdI|G>V* zJdxY^nn*8>SnnonXWWj?Z{2SjNM^%_ylNP~wy@mfbTw10VRpMzn&lADonNNF68DY8 zamzf>f@I*?qiH!98sptRc99f4XOmIN-MN$AA2xJ4YLkVf^VIe-z(xqn*4O zaK3jyWM+krVvXe0zC$g9k9o~82W0hr+W1F=ySyl8;_gO8>kIG~okctBBO7P8@Vw7+ zt^K-4p~uT?gUr}>1%Q5IyAVS>;(e(|A+)w@^}scpmdt z$J`rJ;$5c0zE*Kh&rQM>e)orwo;YDW_N#uMWJ9^weQpY~CNEvFGd_-*bg=oOshvCCZC{ayg#SkD65$AFdYHL`>;qnb2}ql|S%P7|oOHCDv>k21 zcm~)241EoNA8cLS++}P`U4c`9#E)_B-%j zqeO(EzQF#le@LVV8}J>Q2+#*s4zPXj7`!eDv;*A>^bg*Py>IC`@IK%=3W0z=vDZNv zusT692qPi=!M4G6aX-O(!E4|jMpx*2@EEiY<~wriJ&=8XcCgPu@&fmQpU|J6AY?-! zQS>L+zu>ywS%reQ5~D3jz5T zYzR1ngQ*yOhya?vToncmF;|g*P?$pz;1Ie2Kf8_V5cDTcn4PvXcLzFG zazF};vVnhKr@$E!03`4So@u!vg#j1>f0#2Q2zsy*0(B9P^LAIzbO%ZVpcy#@O(YU< z8}J9-3!MV!Mq(8gP;+%M*R*uk7f_Rx7tpfwb_e=0wYHQ&e<-0pqz!T92Zg|x2x2-l z;C=x$Q&+I)5yf<*Vd>`N;c9N_2IvNAt0ACbX<=&$mQ$c4!ho$r5kiInn(nS1=I-c+ z-M~sp!PUvb84z3((9+b=%^7Ug+($r06R4{^ZOtt;6r=@|*np>i(nmlBFdopW8yi;l zrMmEcCnN0N$|y=GBn)!d|HhI+|5i%a5;U;36cWLK>;JLC;r~`lbg<)wE*uJu|BW?) z(ZIjMC44C=vDQQYiRph8K0s;k@5DqPAilyOLSY0*JpUVOBLA(J!U%}*aKuCkf>-`G zVgiG=e`if33?f@xF@Xx}eyeBpajv4V=MukkmIY0RRa(k5*<_>XmUx#C2=uof}$hQ$B;Ur zz&W5UXaW&T8(6iG!pl_@M)Cs#3m5>qW%{YPT6!+|4y`O4DsOP$iBIS$C)E(_2;1hHu#)Y7MkgFm0VcG%h1)c+c zpgj=4z0f&i*H!cvh70lIS^(ozjEA8J#P=|$8J^PkcohbP0I>*S3=|l2Am$o~OW=|q zQU>!KpdI-AO8A4EgFwOY;D^N!27cJ$7MpWXg5Z_4gagn52?SUV5)KR`Kp0{091uq7NQVHVTQU`3Cj=O_7+*qW!uT2r zf6%v}wBS9W03sQ5_!6Q)^kQud zf&#QZ1OT-CK|erJ1J8PMg#$tE1g!agk~?wY0%#Hq zD4aYDc?UcP`4to5;C+y{foE5G1_B~@KNw4xwy<&dm&wpG0vdnKheQ$P74$p~2BB!; zL+2IPGAe@%wuY;**$tv75QTu?P;h~tAYws208#ue6LKgf4Z34JY2(SSN!~bMA&`zK&L7Rj2 z1z`d7u>@hT3CG&DPEh|ix zMinr0rb3UPgjQlk&`m%(1R?RCMiqq22&xa70fYjmG6)weTY%R=lVJLVj{g%oE_1su zLWCc%3Qoy^%Z_-IBea|y*Q=O7h+=gDj{)N$u)2a&1L}%}0Pwkns}Z7t_@xn=tFdgj ztQvx?R}BH8fNlh<9;h+`#Q>`vP+ZXb;P;?wK=T7)E-#svnG!BUh(^d@z|RA~fER@U z7>4PVC+&4gA#9lgF*4Sq7&(_}2~daCqXh;>5->5Ie7H4_(6ZSF=*s^*!qF4ZIIM(3 z3F8;^7`J0=3Yigu0U;=pTi>Jpr^8zc*S%G?iRI`#^I244g?g8DwYao8G*aG7M&<~0U z@EFWEpuRv%h`?9X6D~-Y?eX-)Ew+S~RWQ(%HT<=rKQKCiazcIrb-++2RHXp13&jqo z3!n$2BPOPy`v8ZoRN+9Fz}^Sa6kwOXMJDudO+bGEdPDkvHURB|u@&|{@H=b_fOx>SBi7f;bcTtn#dm1;Vllm}Vt`WY zS~_F!D1s^ULEmBJh2&pVFRZ-ipI`8N1o-4{qQhg76`TS(5Klk^b`&LqTPwgJsw5ai z0m5Qyg(aauCt@54jeeGZx~jkkQ6NPA3XGl-#-9ezMT3tkeUB?gMp0|wCfH! zK*|9_5F55Q6!kY0m$?}sD1@If&~*zIiOVVlq4g>SOs)OjYS(3A!r=(~f(9cdIg$fv*#8g@Fzm z+$;xOSwkm)fYETkVK9KW1cd;IfS>qP+>(sY&xW`%63%Sm%ec(cP;B9e1+F0l)|CN2 zIiYDC^Q#LKkOVvc$c*IyVJxA6#04f01kJ+27(`>T%CbTQzTR{Uh-uJNp!)$BVDY?aA-X=r5Mmz=F0=THeSGP0Cn?~| zN)G7CS{4Vv0Ei7nCHD6rNE;ByGOIcsCW6E-?eS%TjEF@6#1VMGxva_{Kmka0phZC$ zFo6aQS%7O$*}AR;(F+pRB0zk3mz!-_DFIs|Ks2Lc2oO5KCqTTxK44y`(!>A+s}2~) zP;Ldyzb3z6U9e0gB>3b15-8AX1~f2*5~gaxKzcd7gHo>r3XJigk`1J8KwQWHIPiv8 z1aJ z7^DJmw*(l>+7aBiMBpUN6Tt5!K29F)eYgP$!&}vLT&t*k}bY*47DQZe@Lls(=-*a6)NtoVFopKt5UB$!kjk zF)glzQ3xD|ZK!+bx5?G}Ujt-dPrzbnWqky`32=Y#TEV_pH=`$pas4c1?(Sh~4+aEg zb(NGXz-r3+BKYm25I7Fpn2um*tghqQHpakFSznk9$%g*1iA|JHA{=CIOd^~(T){?b zO9Vj=-|ILa+F1WMG4qf6hcX~u|G?`CO9tLp|2R?dPy2^DgMf!3aDy<8pEo83PPF`E zF)(}!5E3EF3U7$|aab0b+5eXSg*t=G0Ynr&+Y95MY-9Go!SO$~$1=Ldo$z0wwIw1z z;|V8)5fZ)-zFxSK^8dVDTX#MsEp#FwMetpCu{w75i0=s#h6rEn*1|9QKP z_I#?x(f&i?w~GSap<2>?W5&V>kQF3Z!&pnn4_IG-p7~`%|Kv+3(uQ)C0ANdVOKD3h zCs#{0xCkz{LbEZeQ-dP#?#9YRpzu=S0@wwQ7jUO5SI~ONub2k@mX?HmB}jv~Q;Pqo zT>@Umo!0v=?E-OzX9sB1y1HpMYzH84@!MTH1UKF;0q^0?_xvY25EN{x*lEQdSR{paoe9ohjJ;kAo`Uanl%BRG{5?zn#iNtW!7dDjD{=m5se z=vO(xAqQY<$W|J_yCOhNAuuEEe8~!(9G7;o@BwKVc=Hz;BK@@^Fj#^nRPfb=?pvLR zjw?ZpEu&*VOsI4sXl!i+9$ztE08K%%;x~nYUL*ZS=3hIZE}0)QjQ(pF!20NSR&j#~ zh5It$1_Kg5doFv;k6;RA)$ECW#}|SE0bAmZuvc*YQVgNT<~RT&$euu?;$aYd!CGZ~rEj)YR4j%qfy98MjcLeaC+9k-MxW)2+X%`rd*mUFV66P4(*DY7aF;0$wMBe~vq3H-6k^5F0QZ z3&9acGs0}>0U?NC^iYfqc+VDck_H>l61toRcJ5f7j&P?vR`BFfI>Jtz{FMio)LJ3E z;m+o))E<=$k2u{s}s=1+a<`$A{!e^t#1c{yezV@*@N}lB?u5;_q_iTJOFy*`EA*z3M&gr0jn^&;7r?6r9u7Z4U99fuwZjZEx>DAMy47FNv# z`^Vv%4fPLgdG#;#N8=l}e`qhQ)my{TD7dK__^U9GPS7vRk^@U0@P580%&)k7x4K^V z`4vwvu*cN}Bdn>gQURqnI(k9qp*IS{4=>S;?PFc>b6_~vRIu#b1sc+Ak%38o326Zh(}r|+;p+JlsI7w?JW1NWm;au%sdw$%zciA=>{W{! zWy<>KZS?R#4Bfc8tmv6V^yYbZF$=V|!oU#PLvHofupEHhMsIZvAQ%&%a8u;J^U2yd zb_uxX%>nUL1$}~vVIcVfCo6y!=SSETGWcJ&EGIv}kWk|UZdseN)^f`Vl|BsGyJvmB z0847uBWHq|5rtc0{42+x`&?bNzn(#7TwF+lo>?l(z-=d2m|lQ3a9X|jzplZQ890~( z7jCRD8IQYN)Jo2VW)+AYOZG!x+m4Flgf+d?qB!kpxu%40r#U73}s;nkLA< z!0zCG3x*BaZSA4cI(EYV8-yEVSOCZ?1TnC2`ac$HgQT~jJC|>W3IpE>S)-ErYjaFc z;=~f6I|*tNV8{0Vv!)5=zhLVuVEiXi6O8a-&=SSf?;O_=eZNXIn2K@hH8kFE{E zzr=#}vIek&9DqYKVF6n&psfg8MX$;vU>a!8)PE%GI%`1J5f&;v@JcT5HAXBnS2q{l zAOU~o6^6UF$qIzB#xMcu8(=RWfC;8*P|#>+UBlpsML0JI!`+}{1;N%a6(+U;*$7iN z?tpDAldW3k0^6?qHTqhT!O$BM5LQ*_K^15>VBrnn8X5F6tH;(-;)bDLvc+p0&=!)7 zV2S{J>l$rBsT+pgdt_OIE7X0kbr#bt5deDW9$u3Kj0mg|!>bEmxNoYjVBCMwGy!d) za7S_f&hwBys~d6&lQ8tsMLflUQUN=51w0SzVGj@uWJh3q3P3dI)q;e^z{!0p7y}0k zm}H8RdH^t>%}>xK5D-h0u~M6BfdR836W?RFJJhVyAYg?ROF0aJ0d7UpEncfA+-Zi@ zorPOheRS@|Yj5o`;x7_0BUc>TLm>aVAQM=BM4%iFgRHI`9zPP$_Bv}t z*P?B7y$aGc`i)jX*>Lc&LD?YgUSnnew$4h$CD*{vE4!A(4F=uN0x;kfJY%AtSv@HK z1_^rg7+&Lm5iqOB2-?JP&`Ov_2MPLBa>52NtJ4S?T)Rpk__-ISEWs>!!)px%4YM#R zukIsUFt4+wbIAiM1_x$ThtnPkcLHUD60ALkvyKGNun({FS^Bq?fbIBKmtd_JT4&wp z8Zm^O!U86%2nJ{<+*z;T23vyt#Y zFQFtvJNgwvf{set^g=#rL~W+4K03L&4w#wRA`Rxzu6FHw6Ov!{>35oMN1qtK^tNc zC4fUS65hYr1-&ko5Y5nwrNH{>|#a0ulo;B$qkRCIHz8|5$X za8^WO`vq{a(wa!vh89J_RtDZm>mt#&t|27AuqzKIF^inh5)o1@uouK%K&QBJ6GHo5AEK1dE}K7ynv|-lYdrNP4T`kwI5HL?%xdU`h&YG)P?; z!#uL;aQPMw4kRBVZzo9etN=erYBTA9voZ2|+|rX&M=$4*JWoy?y&Nu5+hn<~58j=7 z;9Z59ru1_)bXHUwqT1Q;lekdBAe8Cl&ajeT7`Th)UTQtQ=n-nUGQ#CRcN5{5{0I?h z=UxaNh*6m_yNDIaa$qAdI(ZzylT*hVDByWrF3_iL9t%_A;s=6 zE}5;Umfvo#JZ58P+v#Alvvg<@={gc1K_Y0GvgdWM`xWMPk@{J>qu=qntk2HPjwdnF zn9`{U?iUqunvTaLhp?ky2ifyZwZqFE>Ya20+S{azlj2toTj(U>IjfNemi64LhbZ(B;Wus`k&$MMp0}@l`?ZsZ zR0Zw3;ifn=aVd$oJ0J1eH;-_ll8^Y?qB=R@>Yqo5;C$rOgF`xrNJ4!=92(n8aX4M? zB;vWuOtF_&hjZ>|O$h<&+8FtH*!rFYsWGP#@c2iMXvAsvQ#4 zlxORWR|4$;9;$a9)z8s()gnkLS`pgx0vfq__2roszpjufToOr-Kyr*!7o{9}{S)m)IT zOKOuIE1j$_km&<_WyUN#h0<1BkaH6uZVWzbJUe%6B)$rU&s_Xtis6&D3VEAiD5AJr zyC{ZM2?;-eK%{v}x(`Yh9%GVESSyd)6v6?#vwcG$R02_a$7SbnOfsZ&8IuHQxgR<= zg|NkYwGBxMcGAna8<5qz<_@Xq&;VoJHFxlE@Io%TdQjPpox4*u^ERHZqHL1qBrgPH z+hBND02Kzq+A0G`>5iSBQ@V=tOG+nF4r27tzoyBDUP$r1Va5iwF$>S38?$Ldr3+2$ zLGYU$3f(g|HJZIfKc*P+*nRRg#Smm|B{Np}i(<^s28kx=VlQ2IREP#XcT)(x`m=O; zPzdEx6rZcb?^Xz1SD3MZEZr2stioGMPzZo&N-xwv2;MdKP|l6hr_Lcis1VNARG8@$ zqT+#*rw|gPmk(6iU^rO7f`%FZacDtebE%}DWL5}~K*@$dzPqo~$6?9vl0j(4#a9-Z zVnRzQqe2AtK6Ku)IrPjOy-x!}co*I5eVpArrfjmLeL-!?rkLB3ucB<$wZUa^$cP1t ziYo-+h!mZct`Zy!L>2^k+$P=}k%Dr|C&Lldz`uihcYis@dS|fWl1zcq?a!Fy=g@t7 zktyExHZ&lMcg-Cf(a;Gs9eU`F_R@L#XxH4)UIb(L|B2tB9)V|cI`^2pG?1CjUMhh} z>_r>6NaFx691N@pe48o*E&ziS8T1r5u)(0GLk)U5Gyv7kges8&CZw_tuDb=KK1}Xv zFzTTbM>!~Zur&1Gx&aR=&9f6o*)um_LdD!r7q^M@pt|&C{p$-9d>$j}qMMUY7ogdc zleo1E1waj2Imj&g#&-n?Y|S>J9L0>f$A&f2J2mE*1774 zDAEV-n`BcMmRCUc4dGhQICLU~2fK9fXpa$4#$s+wxI##-Jc2QzA)2q1Ui^0=I{-4>cLDQV~6CN&+e041G8Gu(_y_p zEyXGAHIz=nS7)6>II{aZS4o5xr(PjDVW)$FH6=sJQ-<6l3ci8A%;j9i)G@1Rzz`3o z-h0y}Wj9j)nyv1O=g6n~yPGQFiatFvRum=|M#ydrB8v=1?|4P@9~57T_hOdj)(IgU z)_Ys#+UPrb+W=yw`7jvhWEkdIB}k~IxrwLU_UIf&eF#0@H{H+kTEH~v{o8~q9GeZ%rz z>V6>Srg+KuYLVb(#8_AEdSu=H7LJO@kFDEGBpu6&T6!EWvnH*#MI0C~_RNC?xJ6e; zzH9Dixt$l(4jps@KoICY?i<`gH!7eow@YH5bc->ZI)0L$(Y;o6KIfMt{n%ver$k=C%)fE;=iP4;VX9uA@VGW?n{> z2|gFhb3*E5-f;+MGB59MDbvs^!j2Z+`6kQ6>)(Rw9;E}dU-53NwL<=Ywb;llSc~O5 zbKGBk;aymSZY+>?9+Fk7##+1PessSDZInjz%$-8 zcThi=pL3)8tUfphGRl(nwJfuKv?E7_c}S48U?d1Q<)pkaR~H_Qv4Kj?TOXqxvnn13 z4`(|EC5sy{YTf!66(U^rj?#>}H&M>$@y$o}p&Jdc4~&p6D#C2HAAAL^oR@$iV!+#e-wXpe+>FMRxdt%^?0d1dVNdm5qdQ+JKKN{ z?JRBF_G9R>`DRsxsN<9)S2bWpQ1L`;M~r4f+;`zjN8kkqtM>(FqXta|u=g}UaOx$)+^L643M~5@aiw#1J0kHw<%R=p# zn&P1+d!KbjZA{PnBUX;9I8pNDm5Z43j?#d)HE27)!CCXe;6;^1 zrNFvldR7t+6cJv`ShMiX3qwbDVQ8K+C_@NKW9NmTJyQp-41;q?@Po>59FVic zkL#P5Ng1?y!iGY6b%$1b*j%jLBC2!rD1%^GE27iPya*p-1NYichFVL+=MgpaDjS$t z51_58#8|yl7eQ+qc+|}+SakB74myS{+JXtt1Xr;hX~KTS=U?<%S#`|#^0LJvY}J%q z9$Jt$Hei)`>FcHEM@#20*Hs}Lr+tk(XtNpEIz4@|{;g(EY-}l>u@hK3Dr)pFfxs4Z z;H_JJMQ$5!%}_n2;{;3{#G@xgpD)166i|QoZ<>nRbYLYJG_`C~5xEg4m zh{9e&aoT_dAG@ktp+(H%*ubo2ZC8x!p_N9=B3A7f*|}~^nm_#M9iijUNp7r#2spRZaeFEe9N%9Kbc_ZXy0-pE1nsvdU-Y4wdZWU#;=% z+#$EXTifr2s49E*Ym=s=wZVWgNCg61k6rYt3#Ar_Pl>y9aq@5Xs4%Qap;qlqyQfZ| z>m*>?P>w~_31#opfN8EyqHFHp+@?;1YS-Msxj}WhYU+ZGE~|P(Fu8(Ofh5(DNd2M< zWz}(3*{3@9!$z}O@?2%^hOE)Bq=Cwd|ogcuVlf zm16sXIq1#ll6t(5UK3mLRYa95QS7p-lmud^OvOJH+86wMI|u37TTDZ^lI92A!$abw8M;@*we{jPcxOlUtyEC40WB@)2_LLzk*_Pm5fJ<(ThEu z9QHJ?T@)i1k=W;+gp<&Q3;rqYCvqb-N%!^8DTLJ&KJSJ2YS`1M3wye!5H;-S)QLTv z9QHIbB`8G1ZB3on)2_Kg&jt$NLdIjBq8EEQ$sM*Kc#A@4X`V6`yp7hdr`X=sg@>S{ zv-Bv0!=7eVCxsC8i(2La+1(yO*A-@L9N-AAI`#yrXM=yV&|Al#`o_|}+82wtaUo^rBe^xG0|?|_3omZl40Lz>r{u>wbDiHD@3bq(ZlJg z6B?>iRJf#Zd6^8;if#N!7!mze1Kt{LAjx)u-K?<1GBv=g2Q!5oi^*TYQ*nC-Gle)Z zHGrxIGezxhz)}xpin`uFV;;;DQ!;;@$9;T?Hqy8fFx!Yi{={!g3JavSEuv; znU6tVf|msAy80J|J-9livd|{$wr+(1@g@V}MN4%e>Jw@MvDlv0xup@=ietWbRV(>JwA<>KLK1%}2MYi*bYR4>cUA@wqE zg0Z8aR@l_!frJ%m@0vR}DdwtrK?V=ZXqaUUHWH>@JDs|zc z5U%d6JkBYEO&i3g5(q4A0m+UPLK_jK&_sFmGo{eq$oxneYdB3sMV5p@UT*pOcI>^O zhaOfKw#f(m1noX$YD7A+Iv+I8c>Q@#@1Y>V#rpe+&+ks=zUHcH9!O@xi6#G z0P$?mr-NO%Wh_Q#yu+u5Jq2Y{i#IOhY)DN>C>S<*G*3kYn;U7TI@p>hv>h68cb4f9 zP8D*R3*55I8iIB52!hJ=+iF$4)A6q?-{_EI65#i&pPV~Fo4`qDDf?<&*p_n%6>^%K z)T}tQ@(dC>DY}zne0S36x6U7-Op{K(R^N`V%$UWhK)b{K0Q$y-5>LKm{OsJJ44Ztn z_Sw1F-*n~NN4cHf_NtJ#sgPnBOTHpX;AoIW58Q-@7fj%$Ne;P~pz1bhF+KdFX|(Pf}1jcLM!-=EikDLd!uV!I!!m9O^)dSIqw#ja%O{W`&nU2}(e77TUKWuK!*VX+s?I6E+7Uc2yE z3|V>nG8>o?8;o-e%&4>M3v{z+#eS8624bv%8RsrA>u=ub+`;wF4TM_`E4y^Nxr1wfvUPO;50&jWMadUl+FPr^JA0J)zWnN?!lxIMs}61(tgnI z9?ZBKM$`b(>NT7c4hV8fqc-oplkjf${`)2~yF^Orj@^tP!qrKgM7U^CiKOWh;_73N>jXY_%^k`Is7?ymP5mu68#i0@!TY>zDwE}xa0V;Nu?BIR8_>P%fA!kM zG8RQ1$5N*O=DTa|P>z7dT}>Tl(Q^aum^nJ@Rg>jf#Y^NS4tDUBb9iI%f`4jhP}rBw zvM<0baadpH=yO4cO*vi~?cBhT>amzv@6Ie2kQAX-Ty)<0IO_$6<(yFgLI9o{(7a6n z)bkbXt1vgV$P4yD0bIqm@4gBJa31~0KhGk6rBkkwU2-z8J@NZ;K8 znq7C2zObZR^W4C+9!p;r6=rN8ocAFCs)>l;N`IKPfppA*S7fCq)vV~t7G!pAAOY{0 zIz+^|6HPgHP#wYz%AT$chu78y$~L>JEt|+JOuD*OKhPz+Yf@PUkr@Os*psiT`s}Fz z5p7bawQjLy7dR^xx(QcI?@(_-P@X$cm9yTwcsO+^YUfT=WzWq@#Rm57o~hB}izd+3oG295<G z<)Mt6Yw$_X?XtbTc-8>SHtE(Z)*C_t=a>bf_h23yLiB|G(!Pr8xo7T(_?jCi#JlE> zSylr@c-P#~$Ql5?yXFo?28D87ty7^~JgJDNsZf^Xz!2QmtDaL$l9z(Jp7e_R5BlX3wKv^{)U%|yjmp70}K50+zCCM z9rSchbK~`0b0_q)YwloiV4iE0@B0GhKJ+pB3K`!|o0pktVZ9DO_O=WFik_%0F!XKk zU1zYJlsRpFM68m~7j1uk2(~g~Ha>?n%~+b!O% z!Kki0tYB2s6qiI**mSHZnv|te6(J-qo%q{X;i|{>5!z#mKNM9Vc~d!69d@DkAJR**%`R^bo$5PAKl;pt!qc9wNum3B~Q2J4BA9 zaXsa#BVBWcU8to2pSx#n^yCY-vNZ61cg-Da65hh;&c6P+BuUw`pCmP%s99jzlh>SA zg`Tudohl%5%1<<92K-ahv*ZcT8~0|$i${f3%(z1Lvf_GEey3ZdrK|ND+kMRQXrV`l zpzRD0)|E^a9;Ed5i-*Egh>HHcWQ%5&@b{r|Tsi@nivwilnL~mZEy80TDgCZxG+psCvZXF81ElyxR~SMYXzR){J#BtV^AXxKrz~c41x{tgtlf$# zl{{%rtRdZ4e4qWvsbl2!t?(zOj)B`ZMW38H#BB)t-jsc5z@nSVC_zq?(XhZO6&Sf) z7`fDtm7ugMuP+qI{i4FRCZ(FnyBR@5SGwwcviOedBSfh0ax;R6yK@%b419zL%~>1~ zi*GJfX3R!v4YgG3?ip#^eq4Ne=-IiWWB1*YXXg%{eepetXXg%{3rN|!6F%QOt&r1F zf4!M487emMRo>VYL_(@S*t9{o2sdH5+8>EIsz=xCrxJx$x$yG{$(8ib!=yTia4zu? zBBTAcvDsLD{QT?R|5?EO@d}Q`r@s%)y@C7V7Ukk|!H4GF=ti1QR&_oL zdT4G(Hzlziz_u^+gF^|6udgcPW#d^KkTpBFl*9@N>qRlD0WhE2iwX=jW1zmJh8fgZ z_cQ1WY+W3%H9sDurD{@Oc^9yCallqTV-484_;6U^(x%wf6+4ImNX>$RxG4AR+`*eJ z-kCl-cg)tj*L!kqc<_=Z-kCi+cQ8n3Y*$@!Xf&M(*P^iAGIbZD$(0InL)9+q7|!^o zWFRltM^xF#KH?&*hAA2NvgDP|Y%9FlOvs_Gy~68#ut5O6KB`SB=X>@{$iU1cnZ8|J zn-NTM$3#7WYWm=flu#w1kfsZz`!3K2U+*+4lw_A@GV-=8vZG24M7U7eNrY3vM~Kks z!YvC#IIZj?!tw4ABB*d!JR>SIhC7#?l#y(e`r=n}-%QcLHZX|?G(~sX0HYnu6szdQ zJ(~wJh01nmU>Nsjiraci1F?88Q!G9j_{4*mqU<^^bz2mwq>ffWO)c<0?4_&5Ejxg| zFRTyUPhO~>x)LT{#CmneVQTlgEe%LY&Nu|dq)6Ijoj>&aH~_kgW8YDf3xEAjbGddm zN5wpAPIM(tmM?Kmx+98KDy{!~_F(mW8lC@J8px{_MT(8~YXlMZB1@M0Z-mQIOKeeK zb|9jw?_Y4@xUtye1Q&Jn z)5ksuH*iT!uf)k_1Ll)mhvJwHH8>Wxoe-y`HuV?ZfBxm&Pk(;@_s_ri=Id|1d42uj ztADcgVwvJLKtcD=kA7t_Hw5GiYF|J_kPq9%4V>FydZU*+OMJImeb5myFctdXOYJr} z(Cm_mPMT>?)?fJjh$GR&#D&vKC!T3>c&2Pq!FK=_P>AW$iD&AXJ9yzsC!VQm?%?z; z{yyXimp9e5JTDc|YyKB`LSD}wLE2XXCn8W8lU^Pp3ukL_U0Wxe3m3n~Q!y{=x|*EO|u(L2A?kUBcS z{*!VW>Y^70mYhh87yll)>+*;SclD6^Me#*Eqr|c>V*?$uD(*#Y>pHHh(7G#)xdHmQ zYwlpo5JXoQaHI>eqn-f7UERX4!w7Q;3R>fI_GQ z0*n1kn0G6Lt}D#gi7~pYcg%RE1W$&pZBU3#=g>2E==(q+x{8}ag>czrg_%wvEW7q= z7w3>G9zYo`hFt;>;G(yUMQ${V`L`c`_&+dW{MvP1*PxLUqH52slB%rX*h468ERflN zy@qQna#Tw$OxOhfC)1a7x>1^=;BfXm(p_^0-w%#DW9sB+%v~=JV9Zwg5J8K9 zNE)Mg-(+zF10CW3+FgPG(-C| ztr98woJ@}*jC4axTfqcd2nf?= z7#_H>QW*?`kCpk|fg{7%y|@3;*uZuYs~E0GOi^2q7`EOnwyRwz)}?Wipp#T3BTIa( z6;b{~U4^d=Ny%b@q&l%!7r}!a2Wg;!N)~itvAX7tuD275)irnUH!#Sj3$zA&ZqqQ2 zpIa?JG%Ocr;NnH31Pna9uwk$O^#GFTQbS^08bC0odi8QmWgUd+PaWN@dNpj)S?SrblHg=HFS}Fcb_*0MVrPv_+u;H4F6~ADG7&>-(9>l zAb447JH?yrs20VW-;Lc@CHIp{1FP30LZeMFqw78#*@{Bej_okGX>i$Pp!*9vs!kgK z!o#{?z2E}ctKe2rg09-BAdix44??W)uPG6#rY;TWRrX%`vg%`rgu3F=0At-Xci3u! zv|Zk}FYQA4T=(J;=H^?ek1kj^6%X;$u7j@y8{QaSgNOXHTxCR;Rd zb2EYn=VA9bQFVP@%6PsfGBY`{IFKE_U%?v;pVd_Gxv>a`8K+ zk5ESO9U9OTg9{?uZsj9HXx8dx1QA`4*8Sw-x5*wMg5oNOa6Y|L9L{tfAwuJmTNa3L zez%hdm#RKO1cf481Krj3a&%w(KEwS)=mQJb8i;Ue*2xK{%8w915#r(-*OeKw6LhfT z>MGGqvii3Fh$mr}ljYC(T>Q2OO<#kFIKPHJWWe6d~9SNPzIZ}3)Vww{>-Ul%iq z!i1_}@cW7nGSbC`3Q>-cTQQmG5=L$j=;itnvcZe5Z7b7n9U%8s;XHj}q(qT&*%#mT zs7)#di7tDL6ne`Up^=Ua4>Hnu^a@dqks1!tLDjrcVWb93v~qzd08k+)&#^r^Mrz0_ zrcaF2>>x~f?8F)xDeEZ71S8#)k1^6`>xYb7^L}EaaR7`QUI-oM%ah9Vj*(mOljQ_P z8iX}4(nZqRq=y=*>mWutfj`K|&R~666LVsuX(|{wy#UuxuG!ZTwKZoSsbJsI1t&&U z4DsTtq}rs%j1-?Is*t(nCs#@6bb}__jpQf){`uE`vV-^`Oh8D^fF2T( zK6XE3J0Vr!W%Ejfkykz$5b2^D|zo@V#o@^{B5YHo6qtaP`5El_U330!u5Yps^IE_S$HUmP2 z28z1U6UWV~|HUH|X)@wwJP#fn+s79FiwB61pG%JjFFWMq28kZs~>P4Vl9RfAeCA`$QluT=W zK~#(sx`5M3VaVGWXviEXu8Q3$Wg!&ixP^EbZwO-0!F8kVm9h<22 zK0%(bngDyi_=AjeA+ciBj*%8zQ45!%&Ouj?02ZRYw(eWYg^fe*=IIk7Yc|t>+cp?k zw;9KV#~9fFzHW?k$k)75(MVaUl-fuwLvDF(06;hA;{c#}dN9%upQUtKz)qf(iA#a=fP9Dudgoeyf(noSwAb(B<)lzq>mC9bGcwA5yv@1lL*Zo zi)FcBSMgstNpcv}Y!)F&id`8j&?T6i3v_u*g`C4uO3zXx2XL(cS+AY==BvXX?=Cgw zHl6t9>fC#mS|B(T?gspHIdUgIU8YdsXH#J`s}`23-$$Z}{0PQ%UGG!8y+F4kp-xZx z2)!T6n`I;BrDo?fyMa^9nyoiLmi{AXHVm~`;I(nj;azh_RcgRj@0vSgj#q!9V?`bA znmcIcwG$+J?cp~SxBj3_r$RaBT3KpS^K&(GwW~qlUSNMJ`nNA2=qi%JKVb}t{Ka2M z+)HhN-8v`RN&S;{tMx-+4lYBh@M9BwB~K0JfW)FO2Q1K$+quB>nEk-s6p!RM;_KzL z?l_BcenF0gD2*dH2v&#ykw*8#jmH1>>BrAMe)#JjKK}6j&D)>;{J(sJc22Cqv9CUU z|I6RrfB2kIkef?NtwSST$#{vkok{y%l|x7eL?kuzb$=+~9ORQGRoc)^Tg@`4zp^U; z?D)U*)o??EW@B~^*{WR2d@K!I&nJn4Oq@w`n(sE&8C=+2U2ZRP)`R5OagZMtoY_B9b+a3#EE2_(~n=SAz0{d*s)m{furuDP(%iazN zB!m6l(rSIJU%FPtzHhN#FOJ2y;m_>?KvdKAJw?&tvq?fv)?i=S{=2=cSI_-o9$WO; zusDjXe|u6SJO2B+enUnm(m9QrP;I0CY?n4E3N-z9Tc2&&C>#-@)eU4sTb2J{^bQ7a z9hC0Vpx4MCBYW5(Zo8U@JZT#VEfp8chC! z!pU9+19%O#9W~fC)L?5KY|W#sWz?6Vokr7<(YB>V(~;4xcNoncM$?hew0^V}(5Tro z{IRZiw9;p^zQJhK+Gxr@O6r%KwtW9IuAbZ6_GmgX>Ro;>qw#t)UXP~!qpf?iZMe}? ze>B;TCi~IWKiN7bTi>KMaGGp=li9*#>zZs`lj-=BZCI^vvT{C1Y&6SN881moykJnWIUV9drU^eWO_K6mQAK*liAZ`ufCp)r<3W> zWIUbC?ae0h*(#^m>ciQ1Gn>q3Zrav4L6OOPU|bf(r5ksV(VS> z`VG9wM*ZBP?);>0fx-7pR~FNi#ZK2Pru%ktIBqnz=bElB#uvRu`t3{50J|^xMRjOQ zI<%OCkH0ymZyJvm3jA&vq?QegYh-Cn}5^84H!3@P>6r} zth#eC8&<4&8n+C___l&e6$bDY;YFW&wY27HvHfcI3tcUVxtgx)_8@*|{J0uFuBQ7} zOKh%|6IkmAwWrc|)#KKutHpjRuaSmZo?`sEnkHY3KSgG!xf`dVfBy9T{o9WpQ-1gE z6Y{+DIW=-*iKjPjKmPRo5AXgRN+!KS{lB;w`wb4n{%*wo;?IEp#nA8Zzo$2AzL@`U zN(YQS$p1OLk%adRuJ8Wc8ULHIP!!#&H3hXsfRXzzzx?gzZ%?l;-vYdy@;X&Jb=;O# zC@0ng)AGzU1=Gw+etR+*nTSjxCXhA3RDw)PHQhuKAhW2dBDBjVbJpgo*Njx9wtlk7 zluq+v=IqRutwBtw&LK>mU}@f((5}Hs|C_F8{clR3+06P!X<0uhE$b&`rhYoDaYT7$ znq-Q!X3plSl}PU_9@^XFXGDEW9vst|6; z{t4$l?X&$gJp;r*$ISt3pY8Xib7xaC`+L$inj@LEWFY@F4YF5{qDZiL=&v$Q-;0K% z-U_6%X~g!|exJux1p2BBJm2)s zuvL7vbXFl;Z%>M%O5^rDllt~qHC`bd_}=Pf%-wIF)t-md)mT`}pG_OIp^kYhH5^u_ zl0WPERv$i?cGzd!x2Sv{>=uu~9LVNOD-BQfv{3%7qq?^5P9rpRE9{KoTKaxiH5V18<_L~F1_YqVs0D=?Mb z(KK}{G9KRtuVH*Z5q6dtLNDY zW?Qdm=4hHanudM{9s3sLvvJA7)oAJEX!^K)Hg1?78!dK?`Ll52G@4%qnBOqP;upLHFR`O(R=Y%(p|J}X}*)vD8ET4tZoCsq0<)3V9h zD3kfgt^HthuJIhh_#R=iH;At%$j$>Qr| zo^Vo)J8hp;118J2Ci94sY2x--HDGH}7-v-DPLoB<$^04rHHlbiwf%REY?C#_Ce?`3 z_Stx4nl+gpoAPJ<{cIXFn+DCMLH7AHnjVY&QQktEQc1 zi`27e)@+)!eOAqy&0o!?S=(pj-)z;u)~vDLnID@i!Jo}<&E~hZ&nlPM{MW4h>on&( zj}~apZ1HurR>y4GGOtOxY0GTdGMks0Ej6F5H)^dSWco&>`K{TsXSO^&w~#C^%b!iV zX3Nj4wRD;-($3Zb+geVlo!e*CB5pyM)Jz*^^M6~5%IGzJI9uLkEi1IJOd8gfoJ||8 zb#E8NI!R@o! zYW{3K%s!)yW^|dht_?W#0Be)YK7~fwIx3v9{B3QBt^duqWjd*&-<__B)7IM5H(sT- zmiqIpon;cRtSr8lWU+X-zKUag%f!~^QoUVo_P5s^pxvb_j@SFI7tyab_HUnc4ePz+ z>;323XO-M~P4#*m_V!tRf7;q=D*3IwX1}NQn$d6ZaJ`MwuKYZ$SAMQ{Kdu)`+9ig# z*3F({-fO)JaQpAZ2WwNUH@2394%4vpy14a@taz1@-S2~{@&+kyO+DkHX~KHx zzN2+;qJ1uVh^MWGsLNd8!}QmZn`{27MzLa04MKTZp_D5UaQkcDw^Szg zAWfLtXLS=R1SpT2TQFP%S~jXQE6`y3Z2ZXo-PWc3sngYh+}h*p{rlbNJ2V^LfA}G_ z6i-(Pk-i!Fr+0sS|1;X1?|=UI%ct+(|NL@QIiKGA;r$OkzWeRRzkiFC&8zH#B%XYS z#^sMc{ETjgbaK{~gN52*P4U;=A}ds8a$kz zp6oB*eSY`T$G@U?3-Ym3E%nXm%^&~${RiN!e*F01Tcz*KfBzr<^X0=YKmDZt=M@k5 z<1e3o`tgITRQ(E|-k*N?UK+ruA-wJO3ohdQhhP8KfBhBM@$S>V{r{`vlg z7yRlys4NLhk2ONS{Ph0a=Z~N4RYo)1C_LCJHWglRW#}v3Qj5>%1OMsM#~*(A{{8yB z=}Y|%;-h{a-<$9%q-C-HkKZHa$?x%%*Af4H_!@uDm`fgs)qnNw^ZWns)qlo~FEGp3 z8#d)}`078t4*&T2`j5YI1poch`@f*S3XQjS`V-2~Yf#-s)gV^hk&!kFYUVN5n`!q_!MUq1$!3OK-zq49A`S*IVv_g<5E zg)!*?gfYoc!kAQ%VNB|XFeaNkp-g(@u>VQ8iK@oG#7&`(PSD@A13@(de7z983q==2T{^`(J&0UhG)p; zYB?X;S^QhcCd%&(au6eoL3txBz$GBKl;0bnSUi^M!|*-XEDU1;atUJ~hJGuZpzuAZ z?ZcSVePK*CzRR(R>|=aIQ-hv62|zgfR=Oi$OzPt>CRI=zOMT383^)Vg)pSc0X87J~ z3g}_%ocelUY)G|s7#ma46vm|66vt8y7sjO8EXNRiNe@s=l8yuO5d0(>sL~}5^GU}q zj7d+!k0E}@yFC3Ef`Y)5$}xl;;`2hj9kd9j!~Yf*gP<6Bfc<{rGr}+N8HEJ#54jHU z9&wO(g)6~%zLEKd>t}dAftZGMNcJDbqyjI;a2$l5i~VzY2KMHO2T0wCSAe$iZ?7qx z3(u98$%iqyeZL&Ly)v(E(r*gilfA|`#=i45unpb>uoZqQRc#oP<3VBUMz(N%y`_$6 z@jbvCNe=*lOci1H-Z`bXVN8GuVNB||Ft()5Ru~gdSsWvueMVf3GQw_b>fn^W#nvo; zkL89pNv2+G_^p7d!q}9$4`J+@`Ws=a!e?w8Mmxt2FU2Tir7>T_#*KjP%4gv8P1Nx- zFpTsJY?wvAcE%=Kv;{y=DW}0$>UxCd-cl#B90RtIXaO#f_<}GkbJ2q#UR?#`80M4vcEVUCR@`3M|J?)t zUjFtb0Ov3^QT~D~n`|Eup7al00G9dfmiCgvGvw@O7?Un?F@|d*DQ5*ngm?=42*nC` zNs2uf<8=T^6zPKor5%hw3)>NHUnHLmtP1HVa42LSXoIA^uksnF8|k^IO{2a5|H6F1 z`Gn|q2h@$xX3&43+!nYPvIWo_dkO#-a9jX3hI9=T1lbX8J0SlD^2mO11qInJZk-_e z#TiA4jTlQi-6c;)*82f4k7$<&-Be?vJSTldB~JQ`V@c#AfDIxa3u#b}gf0W+T&Qp; zR~}GblAfY_7yV>nAFT}=`NWr54i%KV0tTMu!AL*5Tp&IinWjCsR!qxcK) zR-St!9}Aok+Z#eH*$m2fvMp@B(mEEdnUIF17IL|crDAXBg3{Vh*Ya<|Mx9*nmy~<&RFjmp$tK2OUzIS6CzrC`K z-zs`_o2lMMrb7J}pwrS$dHLL%90~|yviBCouFU(}jbbR=ANfvr1FA34;2_<=@ha-| zp*cc2iHx84fwP6Qj=g)_JQtXLadeZA=XB{2fmqQloHSQTZCF#FPvxaR|sXi4}oPcUvS=>emk*m zLbgWn5-4fv6-)rSN87>}%NOMl@dc$7trzA&dO!32IYKSv0zhOlE$F=x@8?(6HJr(& zb-*2ve9=ZCc>t`-&yeH7r5*rW%g>+~ir52TmU@ulOv0P{`LJVy|5uJ7wcwlv2z091 z(WEy)8lEIk8YM)C(} zEd~DJzzFwgaKxWt4|av9_l2thV$P7dG^|&6O&qNk`;xRalm^5Dw1;>dc;iBpInE&S zZ!eUKPB2UQEz&jO3tCmgQ^ZUDt(;LRb>k-YzK1cv#D_7ilVPgl6Vc5kUf~1*(Tr0D z#Cx1Lpd1O&hhGALeRjCqe^ zbWtY}7ASw70oRLqijyAH*F$+kbp?ju} z1;2(&fc*iO8hs+74D|qT{)KXWY;#imi*q%E@j^z(HiLdK(+2=YqGv}UOA>L3HT7!i|MalsdtSQ9@R6;NI3IUt;W0^K8*2`@K@14;{*WX$k34?y+<}#SsOqJQD0DaM;pW` zy68`lAff3&zh!^5;9xO7L(cRTHi(jm^$N*K^rtwfM>QuZ7pgyS(t>RP31IXk;2!yG zlw}oK7-P6VQOVxs3)?U7wzLj7nCP3ZYfrV+0>Q-?1+)s~G=ROb4PN9D&yvp<&QF&L z-UrX1o+Z3E)nGWeNd6vQBY%%pGvy4pqKj%Ul*v^8CO9zhuTsMxdUBh|_3z2vbYc=qI`urH99vOTh^}VrP zIU!m;7suI{X2xIuHb?z-oQI{pJkmePsgZ@T4xyD6pNoh`HjUIV`f)VZ&g8>jmgK`O z*#C`w1CqK*K7?wEY6xsIQLPJ0p!f?nMD;H^xluQ; zEyP$WT)7wHCBDaf3qbtIPXfWhv|wW+`Uvb`P~Qxt0p)c-BUNaTyDPj-rmZZBTR59c z@eQty@(9pEc^Iw{q<%ZjGP8UU_hX)oG$Q&E(8v39m(;lkF&=K0!j>V$+H^!Q`YW^@DYr#fpcsm%6@4)RE&1Iv#_L5to9qY;ju=01l_S;X z$a1I$0H_e#7K(!yqfjxi-$0O}@1dniw4_8L$`Xle^yAoGjj;!40ml8~gc#)lfbX)N z!l+3P;CN#^M@7ee4U8fE173>!AKqR|>qSqRWCWAuG44wN*~7jVkSyXKLMZVM&{bO7 zl`*M6nNwbZ)A;fH3@jgw)>3Y$-l!HwLy&vx=yFkS9oyYhGvSyL>kInX#H$;c^(8Gh zslaL$4d*wK~Ofea6I*q*>boCggk5&fR0wCaox5Zl~BA;=n2oDZx zLxoMg7`stan*xqbxh+mUkdFnFj%*8K=ni+T#!!k~DBHWI}noPHzS1=N6IPg3!y zr?_5$d?I$NDW+f-mSPItVMjg@FD7F7;;c-x8NAPj$Iu#yF*$AfMSp-JaV$5)TK=9~ z7+b_-bSznJmDq@rWMtFGRLK9KGL15V{hni<2wO!1wbZqAODNOc9a>Bv8W%av!`s9wNHeaf>@rchh}T$FO)c!2wt>9;7dc}#AYDfOxnYg0KGbCnbpcpZ!v#V$#OKDqI( zd@kZIuY>nVfZd`T7<=ke>n4mB=@3eLq8XwjzChW?zu+MumZ2yEVx_bNz?&Gmia1DE z5{yw!nCy*g|Hi#dWRnyJuSgyFx7_yuG9c=t92pJk#mN!M(bLJa_*{(1OJ}_-F}B3~ z9ubAk`~ZkZd`@FA{$fln950>$3{dnr=Y$^$I)n{5>H(y&nA>8Ea55O9{aWnS64n%5 zOt~wppbuj)r^ff>5})#Wsd-)M5Rwh*=OFsd(VwQVxZj8|I**O(cIDL?#dDEMMSlg3 z(s>+=0Z38OmrldR7>_Zz=H5R8yUB8sZ!w1Lt+;=VXi2?)j1h(uAY{Vs<6Nb@%C39{ z3f5rfh-Gy43uCpIN9V2Zy~^DzP^-unq`R@FfJ5MNJ7z&2U>Py@#`maZ#~5L22i)8d zZ3|=6lff9BiNhGWC_$F!`b0g2^2v?KCC%7`47P>uQN4hJ$kfZg7-60;hQc<|f@Kg- zks;6+K$Scuw=v<~j0QGu6ik!d$oPLv+o|Ml>1w-T&*P#hf z8T}f@S;Q*L%2C?*G4!?p&~f*dpW7aV%x zvvaRF=S6%$yEEuLn#vQ^YRLYm@BIpFK=85Yh*Qkh5`rq~IK~+718+dNE!qc^C*uAM z;sL@8)wKy09_0qaBJH7}-5z5Fj&Ct85}6O}@1q4zy&D|WqTV4w9__0k0gOHj9cj63 z)ccZj9E@xWJBw7~U{{j%K5^4Q>}g?p3kRu!{U%sn)aP_nNt7?loG?2$c}V>Tq`;&@ zNbI6t1LCft8)(4LbJ2Vtnt_Q4aRKuoNX50KqK?M+tZIS@MmxgQW6Wpdr=k8xN9U;5 z3}^+}3{LIPe%SzQN?aRUC)om$R_Zqmm@vu>+D!7mk#wpD(FLLY0n#SwA!EmZ;sVTr zbYnn^BJv)!75^4n+mU~G9Ut{Yffl7bCERL7eKSZS=Jz-OSULNTFi7-O&g~%Cqu7I_ zi+l+JA?;5iz)>#)!HoQPx=<_XB%C(Y`=EsUGn_=MIZ;3`o(2($Fq-H*knZBg#Al?y zv{#8v6|W6=m1u+5or!r)>JpN^Af=}L1yntR>BWgD<{xUSkV~c0B-8^Pf$@*N1RKEQ zPjOC;bP^j5=tnl1EP+*Lv}>*07PGOXaQz-E#MZmOdmH@r|~ zOkO-z#1x!oqPU7xke^K3jnP)YDe6UH_l@L>W2xj1U`4T(L|3_T9s=O=$g2t9vgqsZ zQ;J(ak;OV7MP!QI$a2VU;513BiNO?rSfV`8UW>j25NpzV++a#EIUNn6b)W#I^rPdQAP1O zP!LAmrjM(idP&DW?Hml=KBRB-46R`!wnrZsg_p zP=e9gaG;&Xu;QS*=wniROIzji+llXtgSRI?ge?b(QMl%bVjk3mVlA?q%5QPON~Adf zb7_pQrV@^#Z%2y6vIMj-+BwoD+KWL4is~6u;uJrC`llF$$5QSHtQGk%ypEH67_e64 z!_cXsoE5L`qkgo*Nn z<1`(`b3jPRuc6P+^1u;^7(Eud>C*PD`Y%z5jH=iyr><$N!t&2|NvW9WY)D zkuIN2Z@oCZNiTv(AMr@}_!Zu8@|)Z8^?CU1m($nt7hmEZ38($#@C7p6^A|9|+wGrD z?XRRaVBk%{U;gj+-~Zdszx?gx%{SMtmoJvrFTeT%fU9r5`YHjq(b5A#`0Fp`^H*bf c{lw3o-+lTluX0Eg%{-m{;UB*K<2R@O2bT`SL;wH) literal 126196 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 S0JE|IgFFf~wTR3^l>ZNX-HmYo From 22390f20a9a2029e1281d33dce17f701d2910f3a Mon Sep 17 00:00:00 2001 From: epernod Date: Wed, 5 Oct 2022 23:06:54 +0200 Subject: [PATCH 32/60] Backup work on scenes --- examples/3instruments_collis.scn | 2 +- examples/SingleBeam.scn | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/3instruments_collis.scn b/examples/3instruments_collis.scn index 4a5511faa..7d0d64491 100644 --- a/examples/3instruments_collis.scn +++ b/examples/3instruments_collis.scn @@ -83,7 +83,7 @@ - diff --git a/examples/SingleBeam.scn b/examples/SingleBeam.scn index 8899cf388..4f9d73e1c 100644 --- a/examples/SingleBeam.scn +++ b/examples/SingleBeam.scn @@ -6,7 +6,9 @@ + + @@ -15,8 +17,8 @@ - - + + From a423836734bf2f340c8bd321ce9d946eccbd1668 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 20 Oct 2022 00:30:53 +0200 Subject: [PATCH 33/60] [IRCtrl] skip onKey event and comment partially onAnimationBeginEvent to use only the BeamActionController events. --- .../InterventionalRadiologyController.inl | 105 +++++++++--------- 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 1a6026511..4f186d184 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -248,6 +248,9 @@ void InterventionalRadiologyController::onMouseEvent(MouseEvent * mev template void InterventionalRadiologyController::onKeyPressedEvent(KeypressedEvent *kev) { + + return; + /// Control keys for interventonal Radiology simulations: switch(kev->getKey()) { @@ -308,56 +311,58 @@ template void InterventionalRadiologyController::onBeginAnimationStep(const double dt) { SOFA_UNUSED(dt); - - BaseContext* context = getContext(); - auto xInstrTip = sofa::helper::getWriteOnlyAccessor(d_xTip); - if(m_FF || m_RW) - { - int id = d_controlledInstrument.getValue(); - if (id >= (int)xInstrTip.size()) - { - msg_warning()<<"Controlled Instument num "<getDt(); - else - { - unsigned int newSensorData = m_currentSensorData + 1; - - while( m_sensorMotionData[newSensorData][0] < context->getTime() ) - { - m_currentSensorData = newSensorData; - newSensorData++; - } - if(newSensorData >= m_sensorMotionData.size()) - { - xInstrTip[id] = 0; - } - else - { - xInstrTip[id] += m_sensorMotionData[m_currentSensorData][1]; - } - } - } - if (m_RW) - { - xInstrTip[id] -= d_speed.getValue()* context->getDt(); - // verif min x : - if ( xInstrTip[id] < 0.0) - { - xInstrTip[id] = 0.0; - m_RW = false; - } - } - } - - /// The tip of the instrument can not be further than its total length - for (unsigned int i=0; i m_instrumentsList[i]->getRestTotalLength() ) - xInstrTip[i] = m_instrumentsList[i]->getRestTotalLength(); + + cptFwd = 0; + + //BaseContext* context = getContext(); + //auto xInstrTip = sofa::helper::getWriteOnlyAccessor(d_xTip); + //if(m_FF || m_RW) + //{ + // int id = d_controlledInstrument.getValue(); + // if (id >= (int)xInstrTip.size()) + // { + // msg_warning()<<"Controlled Instument num "<getDt(); + // else + // { + // unsigned int newSensorData = m_currentSensorData + 1; + + // while( m_sensorMotionData[newSensorData][0] < context->getTime() ) + // { + // m_currentSensorData = newSensorData; + // newSensorData++; + // } + // if(newSensorData >= m_sensorMotionData.size()) + // { + // xInstrTip[id] = 0; + // } + // else + // { + // xInstrTip[id] += m_sensorMotionData[m_currentSensorData][1]; + // } + // } + // } + // if (m_RW) + // { + // xInstrTip[id] -= d_speed.getValue()* context->getDt(); + // // verif min x : + // if ( xInstrTip[id] < 0.0) + // { + // xInstrTip[id] = 0.0; + // m_RW = false; + // } + // } + //} + + ///// The tip of the instrument can not be further than its total length + //for (unsigned int i=0; i m_instrumentsList[i]->getRestTotalLength() ) + // xInstrTip[i] = m_instrumentsList[i]->getRestTotalLength(); applyInterventionalRadiologyController(); } From 26c939948fa351a6a73037c2ba14779fc25feb04 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 13 Nov 2022 22:16:40 +0100 Subject: [PATCH 34/60] [IRCtrl] some small cleaning --- .../controller/InterventionalRadiologyController.inl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 4f186d184..8ccbb5ab7 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -312,9 +312,7 @@ void InterventionalRadiologyController::onBeginAnimationStep(const do { SOFA_UNUSED(dt); - cptFwd = 0; - - //BaseContext* context = getContext(); + //BaseContext* context = getContext(); //auto xInstrTip = sofa::helper::getWriteOnlyAccessor(d_xTip); //if(m_FF || m_RW) //{ From 20673f9857281128bdd865674c240be6f34fe4c1 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 28 Sep 2022 13:38:40 +0900 Subject: [PATCH 35/60] add option to force adaptivemapping to not compute applyj/jt (useful for visual mapping) --- src/BeamAdapter/component/mapping/AdaptiveBeamMapping.h | 2 ++ src/BeamAdapter/component/mapping/AdaptiveBeamMapping.inl | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.h b/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.h index ac681e6b8..d2a0b910f 100644 --- a/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.h +++ b/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.h @@ -154,6 +154,8 @@ class AdaptiveBeamMapping : public Mapping Data> d_segmentsCurvAbs; /*!< (output) the abscissa of each created point on the collision model */ Data d_parallelMapping; /*!< flag to enable parallel internal computation of apply/applyJ */ + Data d_onlyVisual; + SingleLink, BInterpolation, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> l_adaptativebeamInterpolation; diff --git a/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.inl b/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.inl index 8a9029c12..f4df8bdd9 100644 --- a/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.inl +++ b/src/BeamAdapter/component/mapping/AdaptiveBeamMapping.inl @@ -77,6 +77,7 @@ AdaptiveBeamMapping::AdaptiveBeamMapping(State< In >* from, State< Out , d_nbPointsPerBeam(initData(&d_nbPointsPerBeam, 0.0, "nbPointsPerBeam", "if non zero, we will adapt the points depending on the discretization, with this num of points per beam (compatible with useCurvAbs)")) , d_segmentsCurvAbs(initData(&d_segmentsCurvAbs, "segmentsCurvAbs", "the abscissa of each point on the collision model", true, true)) , d_parallelMapping(initData(&d_parallelMapping, false, "parallelMapping", "flag to enable parallel internal computation")) + , d_onlyVisual(initData(&d_onlyVisual, (bool)false, "onlyVisual", "Really not mechanical mapping")) , l_adaptativebeamInterpolation(initLink("interpolation", "Path to the Interpolation component on scene"), interpolation) , m_inputMapping(nullptr) , m_isSubMapping(isSubMapping) @@ -292,6 +293,9 @@ void AdaptiveBeamMapping< TIn, TOut>::apply(const MechanicalParams* mparams, Dat template void AdaptiveBeamMapping< TIn, TOut>::applyJ(const core::MechanicalParams* mparams, Data& dOut, const Data& dIn) { + if (d_onlyVisual.getValue()) + return; + SOFA_UNUSED(mparams); ScopedAdvancedTimer timer("AdaptiveBeamMapping_applyJ"); @@ -377,6 +381,9 @@ void AdaptiveBeamMapping< TIn, TOut>::applyJ(const core::MechanicalParams* mpara template void AdaptiveBeamMapping< TIn, TOut>::applyJT(const core::MechanicalParams* mparams, Data& dOut, const Data& dIn) { + if (d_onlyVisual.getValue()) + return; + SOFA_UNUSED(mparams); ScopedAdvancedTimer timer("AdaptiveBeamMapping_applyJT"); From 255d72c58a1ed556feb8768dad98d0a10f2fd922 Mon Sep 17 00:00:00 2001 From: epernod Date: Wed, 24 May 2023 11:50:26 +0200 Subject: [PATCH 36/60] [src] Fix AdaptiveBeamController potential segfault on MouseEvent if number of device is null --- .../controller/AdaptiveBeamController.inl | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/BeamAdapter/component/controller/AdaptiveBeamController.inl b/src/BeamAdapter/component/controller/AdaptiveBeamController.inl index e7fa7513d..95ef1caba 100644 --- a/src/BeamAdapter/component/controller/AdaptiveBeamController.inl +++ b/src/BeamAdapter/component/controller/AdaptiveBeamController.inl @@ -124,24 +124,21 @@ void AdaptiveBeamController::onMouseEvent(MouseEvent *mev) /// Translation input Real PosYcorr = 0.0; - int idy = d_controlledInstrument.getValue(); + auto id = d_controlledInstrument.getValue(); auto x_instr_tip = sofa::helper::getWriteOnlyAccessor(d_xtip); - if (idy >= (int)x_instr_tip.size()){ - msg_warning() << "The instrument number "<= (int)(x_instr_tip.size())){ + msg_warning() << "The instrument number " << id << " do not exist (size =" << x_instr_tip.size() << ") exiting mouse event."; + return; } - PosYcorr = -PosY*0.2; - x_instr_tip[idy] += PosYcorr; - /// Rotation input - Real PosXcorr = 0.0; + PosYcorr = -PosY * 0.2; + x_instr_tip[id] += PosYcorr; - //TODO(dmarchal@cduriez) why is this the same as idy but with a different name? - int idx = d_controlledInstrument.getValue(); + /// Rotation input auto rot_instrument = sofa::helper::getWriteOnlyAccessor(d_rotationInstrument); - PosXcorr = PosX*0.015; - rot_instrument[idx] += PosXcorr; + Real PosXcorr = PosX * 0.015; + rot_instrument[id] += PosXcorr; } //TODO(dmarchal 2017-05-17) Christian & Eulalie, how can user know which key-mouse behavior he From 69b2d59735b95a5568bc626cd85bc1854cbf52ed Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 26 Jun 2023 15:58:10 +0200 Subject: [PATCH 37/60] [BeamInterpolation] Update getNodeIndices method signature --- src/BeamAdapter/component/BeamInterpolation.h | 4 +++- .../component/BeamInterpolation.inl | 23 +++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index 04e58b06e..bdcef2b20 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -89,6 +89,7 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject using Transform = typename sofa::defaulttype::SolidTypes::Transform; using SpatialVector = typename sofa::defaulttype::SolidTypes::SpatialVector; + using PointID = BaseMeshTopology::PointID; using ElementID = BaseMeshTopology::EdgeID; using VecElementID = type::vector; using VecEdges = type::vector; @@ -164,7 +165,8 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject void getTangent(Vec3& t, const Real& baryCoord, const Transform &global_H_local0, const Transform &global_H_local1,const Real &L); - int getNodeIndices(unsigned int edgeInList, unsigned int &node0Idx, unsigned int &node1Idx ); + /// Given @param beamId will return the 2 PointID forming the given edge from the list @sa d_edgeList. Return true if found otherwise false. + bool getNodeIndices(const ElementID beamID, PointID &node0Idx, PointID &node1Idx) const; void getInterpolationParam(unsigned int edgeInList, Real &_L, Real &_A, Real &_Iy , Real &_Iz, Real &_Asy, Real &_Asz, Real &J); diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index c19392a3d..adf1184da 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -649,7 +649,7 @@ int BeamInterpolation::computeTransform(unsigned int edgeInList, { /// 1. Get the indices of element and nodes unsigned int node0Idx, node1Idx; - if (getNodeIndices( edgeInList, node0Idx, node1Idx ) == -1) + if (getNodeIndices( edgeInList, node0Idx, node1Idx ) == false) { dmsg_error() << "[computeTransform2] Error in getNodeIndices(). (Aborting)" ; return -1; @@ -699,7 +699,7 @@ int BeamInterpolation::computeTransform2(unsigned int edgeInList, { /// 1. Get the indices of element and nodes unsigned int node0Idx, node1Idx; - if ( getNodeIndices( edgeInList, node0Idx, node1Idx ) == -1) + if ( getNodeIndices( edgeInList, node0Idx, node1Idx ) == false) { dmsg_error() << "[computeTransform2] Error in getNodeIndices(). (Aborting)" ; return -1; @@ -798,23 +798,28 @@ void BeamInterpolation::getSplineRestTransform(unsigned int edgeInLis template -int BeamInterpolation::getNodeIndices(unsigned int edgeInList, - unsigned int &node0Idx, - unsigned int &node1Idx ) +bool BeamInterpolation::getNodeIndices(const ElementID beamID, PointID& node0Idx, PointID& node1Idx) const { - if ( m_topologyEdges == nullptr) + if (m_topologyEdges == nullptr) { msg_error() <<"This object does not have edge topology defined (computation halted). " ; - return -1; + return false; + } + + const VecElementID& edges = d_edgeList.getValue(); + if (beamID >= edges.size()) + { + msg_error() << "Given beamID: " << beamID << " in getNodeIndices is out of bounds: " << edges.size(); + return false; } /// 1. Get the indices of element and nodes - const ElementID& e = d_edgeList.getValue()[edgeInList] ; + const ElementID& e = edges[beamID] ; const BaseMeshTopology::Edge& edge= (*m_topologyEdges)[e]; node0Idx = edge[0]; node1Idx = edge[1]; - return 1; + return true; } From d9982b408061a24dca94fed526a5c893533daf8f Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 11:44:54 +0200 Subject: [PATCH 38/60] [BeamInterpolation] Rename method conputeTransform2 into computeTransform --- src/BeamAdapter/component/BeamInterpolation.h | 8 +- .../component/BeamInterpolation.inl | 79 ++++--------------- 2 files changed, 16 insertions(+), 71 deletions(-) diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index bdcef2b20..254666bd6 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -155,12 +155,8 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject void getDOFtoLocalTransform(unsigned int edgeInList,Transform &DOF0_H_local0, Transform &DOF1_H_local1); void getDOFtoLocalTransformInGlobalFrame(unsigned int edgeInList, Transform &DOF0Global_H_local0, Transform &DOF1Global_H_local1, const VecCoord &x); - - int computeTransform(unsigned int edgeInList, Transform &global_H0_local, Transform &global_H1_local, - Transform &local0_H_local1, Quat& local_R_local0, const VecCoord &x); - - int computeTransform2(unsigned int edgeInList, - Transform &global_H_local0, Transform &global_H_local1, const VecCoord &x); + + int computeTransform(ElementID edgeInList, Transform &global_H_local0, Transform &global_H_local1, const VecCoord &x); void getTangent(Vec3& t, const Real& baryCoord, const Transform &global_H_local0, const Transform &global_H_local1,const Real &L); diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index adf1184da..0b9253b93 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -315,7 +315,7 @@ void BeamInterpolation::bwdInit() // this transforamtion is given by global_H_local0 for node 0 (and dof0) // and global_H_local1 for node 1 (and dof1) Transform global_H_local0, global_H_local1; - computeTransform2(i, global_H_local0, global_H_local1, statePos.ref()) ; + computeTransform(i, global_H_local0, global_H_local1, statePos.ref()) ; Vec3 beam_segment = global_H_local1.getOrigin() - global_H_local0.getOrigin(); lengthList.push_back(beam_segment.norm()); @@ -639,69 +639,18 @@ void BeamInterpolation::getDOFtoLocalTransformInGlobalFrame(unsigned } -template -int BeamInterpolation::computeTransform(unsigned int edgeInList, - Transform &global_H0_local, - Transform &global_H1_local, - Transform &local0_H_local1, - Quat &local_R_local0, - const VecCoord &x) -{ - /// 1. Get the indices of element and nodes - unsigned int node0Idx, node1Idx; - if (getNodeIndices( edgeInList, node0Idx, node1Idx ) == false) - { - dmsg_error() << "[computeTransform2] Error in getNodeIndices(). (Aborting)" ; - return -1; - } - - /// 2. Computes the optional rigid transformation of DOF0_Transform_node0 and DOF1_Transform_node1 - Transform DOF0_H_local0, DOF1_H_local1; - getDOFtoLocalTransform(edgeInList, DOF0_H_local0, DOF1_H_local1); - - - /// 3. Computes the transformation global To local for both nodes - Transform global_H_DOF0(x[node0Idx].getCenter(), x[node0Idx].getOrientation()); - Transform global_H_DOF1(x[node1Idx].getCenter(), x[node1Idx].getOrientation()); - - /// - add a optional transformation - Transform global_H_local0 = global_H_DOF0*DOF0_H_local0; - Transform global_H_local1 = global_H_DOF1*DOF1_H_local1; - - - /// 4. Compute the local frame - /// SIMPLIFICATION: local = local0: - local_R_local0.clear(); - - global_H_DOF0.set(Vec3(0,0,0), x[node0Idx].getOrientation()); - global_H_DOF1.set(Vec3(0,0,0), x[node1Idx].getOrientation()); - - /// - rotation due to the optional transformation - global_H_local0 = global_H_DOF0*DOF0_H_local0; - global_H_local1 = global_H_DOF1*DOF1_H_local1; - - global_H0_local = global_H_local0; - Quat local0_R_local1 = local0_H_local1.getOrientation(); - Transform local0_HR_local1(Vec3(0,0,0), local0_R_local1); - - global_H1_local = global_H_local1 * local0_HR_local1.inversed(); - - return 1; - -} - template -int BeamInterpolation::computeTransform2(unsigned int edgeInList, - Transform &global_H_local0, - Transform &global_H_local1, - const VecCoord &x) +int BeamInterpolation::computeTransform(ElementID edgeInList, + Transform &global_H_local0, + Transform &global_H_local1, + const VecCoord &x) { /// 1. Get the indices of element and nodes unsigned int node0Idx, node1Idx; if ( getNodeIndices( edgeInList, node0Idx, node1Idx ) == false) { - dmsg_error() << "[computeTransform2] Error in getNodeIndices(). (Aborting)" ; + dmsg_error() << "[computeTransform] Error in getNodeIndices(). (Aborting)" ; return -1; } @@ -844,9 +793,9 @@ template void BeamInterpolation::getSplinePoints(unsigned int edgeInList, const VecCoord &x, Vec3& P0, Vec3& P1, Vec3& P2, Vec3 &P3) { Transform global_H_local0, global_H_local1; - if (computeTransform2(edgeInList, global_H_local0, global_H_local1, x) == -1) + if (computeTransform(edgeInList, global_H_local0, global_H_local1, x) == -1) { - dmsg_error() << "[getSplinePoints] error with computeTransform2. (Aborting)" ; + dmsg_error() << "[getSplinePoints] error with computeTransform. (Aborting)" ; return; } @@ -1013,9 +962,9 @@ void BeamInterpolation::interpolatePointUsingSpline(unsigned int edge } else { - /// \todo remove call to computeTransform2 => make something faster ! + /// \todo remove call to computeTransform => make something faster ! Transform global_H_local0, global_H_local1; - computeTransform2(edgeInList, global_H_local0, global_H_local1, x); + computeTransform(edgeInList, global_H_local0, global_H_local1, x); Vec3 DP=global_H_local0.getOrigin() - global_H_local1.getOrigin(); if( DP.norm()< _L*0.01 ) @@ -1128,7 +1077,7 @@ void BeamInterpolation::updateBezierPoints( const VecCoord &x,unsigne /// \todo remove call to /// nsform2 => make something faster ! Transform global_H_local0, global_H_local1; - computeTransform2(index, global_H_local0, global_H_local1, x); + computeTransform(index, global_H_local0, global_H_local1, x); ///Mechanical Object to stock Bezier points bezierPosVec[index*4] =global_H_local0.getOrigin(); //P0 @@ -1197,7 +1146,7 @@ void BeamInterpolation::updateInterpolation(){ /// convert position (RigidTypes) in Transform Transform global_H_local0, global_H_local1; - computeTransform2(numBeam, global_H_local0, global_H_local1, x->getValue() ); + computeTransform(numBeam, global_H_local0, global_H_local1, x->getValue() ); /// compute the length of the spline Vec3 P0,P1,P2,P3; @@ -1354,9 +1303,9 @@ void BeamInterpolation::InterpolateTransformUsingSpline(unsigned int Transform &global_H_localInterpol) { Transform global_H_local0, global_H_local1; - if (computeTransform2(edgeInList, global_H_local0, global_H_local1, x) == -1) + if (computeTransform(edgeInList, global_H_local0, global_H_local1, x) == -1) { - msg_error() << "[InterpolateTransformUsingSpline] error with computeTransform2. (Aborting). " ; + msg_error() << "[InterpolateTransformUsingSpline] error with computeTransform. (Aborting). " ; return; } From 14e0510d24a66c8a108f5639f4fa92bd2bd16c61 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 27 Jun 2023 14:56:07 +0200 Subject: [PATCH 39/60] [BeamInterpolation] Rename method conputeTransform2 into computeTransform --- .../component/WireBeamInterpolation.inl | 4 ++-- .../constraint/AdaptiveBeamLengthConstraint.inl | 12 ++++++------ .../constraint/AdaptiveBeamSlidingConstraint.inl | 2 +- .../component/controller/SutureController.inl | 14 +++++++------- .../forcefield/AdaptiveBeamForceFieldAndMass.inl | 4 ++-- .../AdaptiveInflatableBeamForceField.inl | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/BeamAdapter/component/WireBeamInterpolation.inl b/src/BeamAdapter/component/WireBeamInterpolation.inl index 2a9745c59..48c45b9c5 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.inl +++ b/src/BeamAdapter/component/WireBeamInterpolation.inl @@ -219,7 +219,7 @@ bool WireBeamInterpolation::getApproximateCurvAbs(const Vec3& x_input // Initialize with the first vertex Transform globalHlocal0, globalHlocal1; - this->computeTransform2(0, globalHlocal0, globalHlocal1, x); + this->computeTransform(0, globalHlocal0, globalHlocal1, x); Real closestDist = (x_input-globalHlocal0.getOrigin()).norm2(); Real beamBary = 0.0; bool projected = false; @@ -230,7 +230,7 @@ bool WireBeamInterpolation::getApproximateCurvAbs(const Vec3& x_input unsigned int nb = this->getNumBeams(); for(unsigned int i=0; icomputeTransform2(i, globalHlocal0, globalHlocal1, x); + this->computeTransform(i, globalHlocal0, globalHlocal1, x); Vec3 A = globalHlocal0.getOrigin(), B = globalHlocal1.getOrigin(); Real r = ((x_input-A) * (B-A)) / (B-A).norm2(); diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl b/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl index ea38e9301..8724472a7 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl @@ -121,7 +121,7 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x /// 2. compute the bending angle Transform Tnode0, Tnode1; - interpolation->computeTransform2(b,Tnode0,Tnode1,x); + interpolation->computeTransform(b,Tnode0,Tnode1,x); Real angleBeam = interpolation->ComputeTotalBendingRotationAngle(rest_length/10.0, Tnode0, Tnode1,rest_length , 0.0, 1.0); /// 3. treatment of the different case.. @@ -164,7 +164,7 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x interpolation->getSplinePoints(b,xfree,P0,P1,P2,P3); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform2(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); intervalDef.posFreeEnd = global_H_local0_free.getOrigin(); /// store the free position intervalDef.rest_length=rest_length_interval; /// store the rest_length @@ -231,10 +231,10 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x interpolation->getDOFtoLocalTransform(b, DOF0_H_local0, DOF1_H_local1); Transform global_H_local0, global_H_local1; - interpolation->computeTransform2(b, global_H_local0, global_H_local1, x); + interpolation->computeTransform(b, global_H_local0, global_H_local1, x); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform2(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); intervalDef.dof_H_begin = DOF0_H_local0; intervalDef.IdxBegin = n0; @@ -262,11 +262,11 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x Transform global_H_local0, global_H_local1; - interpolation->computeTransform2(b, global_H_local0, global_H_local1, x); + interpolation->computeTransform(b, global_H_local0, global_H_local1, x); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform2(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); intervalDef.dof_H_end = DOF1_H_local1; diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl index a65c2a4db..ea0d0d538 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl @@ -170,7 +170,7 @@ void AdaptiveBeamSlidingConstraint::buildConstraintMatrix(const Const // Position and frame on the curve interpolation->getBeamAtCurvAbs(m_previousPositions[i], beam, baryCoord); - interpolation->computeTransform2(beam, Tnode0, Tnode1, x1free.ref()); + interpolation->computeTransform(beam, Tnode0, Tnode1, x1free.ref()); interpolation->InterpolateTransformUsingSpline(Tresult, baryCoord, Tnode0, Tnode1, interpolation->getLength(beam)); Pos p = Tresult.getOrigin(); Pos dir0, dir1, dir2; diff --git a/src/BeamAdapter/component/controller/SutureController.inl b/src/BeamAdapter/component/controller/SutureController.inl index e5dc20ee1..6e44c88a8 100644 --- a/src/BeamAdapter/component/controller/SutureController.inl +++ b/src/BeamAdapter/component/controller/SutureController.inl @@ -554,7 +554,7 @@ typename SutureController::Real SutureController::computeB l_adaptiveInterpolation->getBeamAtCurvAbs(xmin, idBeamMin, baryCoordMin); l_adaptiveInterpolation->getBeamAtCurvAbs(xmax, idBeamMax, baryCoordMax); - l_adaptiveInterpolation->computeTransform2(idBeamMin,Tnode0,Tnode1, Pos); + l_adaptiveInterpolation->computeTransform(idBeamMin,Tnode0,Tnode1, Pos); if (idBeamMin==idBeamMax) return l_adaptiveInterpolation->ComputeTotalBendingRotationAngle(dx_comput, Tnode0, Tnode1, l_adaptiveInterpolation->getLength(idBeamMin), baryCoordMin, baryCoordMax); @@ -571,12 +571,12 @@ typename SutureController::Real SutureController::computeB unsigned int b=idBeamMin+1; while(bcomputeTransform2(b,Tnode0,Tnode1,Pos); + l_adaptiveInterpolation->computeTransform(b,Tnode0,Tnode1,Pos); angle += l_adaptiveInterpolation->ComputeTotalBendingRotationAngle(dx_comput, Tnode0, Tnode1, l_adaptiveInterpolation->getLength(b), 0.0, 1.0); b++; } - l_adaptiveInterpolation->computeTransform2(idBeamMax,Tnode0,Tnode1,Pos); + l_adaptiveInterpolation->computeTransform(idBeamMax,Tnode0,Tnode1,Pos); angle += l_adaptiveInterpolation->ComputeTotalBendingRotationAngle(dx_comput, Tnode0, Tnode1, l_adaptiveInterpolation->getLength(idBeamMax), 0.0, baryCoordMax); return angle; @@ -596,7 +596,7 @@ void SutureController::computeTangentOnDiscretePoints(type::vectorcomputeTransform2(0,Tnode0,Tnode1, Pos); + l_adaptiveInterpolation->computeTransform(0,Tnode0,Tnode1, Pos); Vec3 t = Tnode0.getOrientation().rotate(Vec3(1.0,0.0,0.0)); TangTable.push_back(t); xTable.push_back(0.0); @@ -604,7 +604,7 @@ void SutureController::computeTangentOnDiscretePoints(type::vectorgetBeamAtCurvAbs(x, beam, baryCoord); - l_adaptiveInterpolation->computeTransform2(beam,Tnode0,Tnode1, Pos); + l_adaptiveInterpolation->computeTransform(beam,Tnode0,Tnode1, Pos); l_adaptiveInterpolation->getTangent(t, baryCoord, Tnode0,Tnode1,l_adaptiveInterpolation->getLength(beam) ); TangTable.push_back(t); @@ -954,7 +954,7 @@ void SutureController::computeSampling(type::vector &newCurvAbs Real beamLength = l_adaptiveInterpolation->getLength(b); l_adaptiveInterpolation->getAbsCurvXFromBeam(b, curvatureList[b][0]); Transform Tnode0, Tnode1; - l_adaptiveInterpolation->computeTransform2(b, Tnode0, Tnode1, x); + l_adaptiveInterpolation->computeTransform(b, Tnode0, Tnode1, x); curvatureList[b][1] = beamsCurvature[b] = l_adaptiveInterpolation->ComputeTotalBendingRotationAngle(beamLength / 5, Tnode0, Tnode1, beamLength, 0.0, 1.0); } @@ -1176,7 +1176,7 @@ void SutureController::updateControlPointsPositions() const VecCoord& x = getMechanicalState()->write(sofa::core::VecCoordId::position())->getValue(); for (unsigned int b = 0; b < numBeams; b++) { - l_adaptiveInterpolation->computeTransform2(b, global_H0_local, global_H1_local, x); + l_adaptiveInterpolation->computeTransform(b, global_H0_local, global_H1_local, x); Coord pt; pt.getCenter() = global_H0_local.getOrigin(); pt.getOrientation() = global_H0_local.getOrientation(); diff --git a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl index ffda0e956..5078bccab 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl @@ -470,7 +470,7 @@ void AdaptiveBeamForceFieldAndMass::addForce (const MechanicalParams* Transform global_H_local0, global_H_local1; /// 1. get the current transform of the beam: - l_interpolation->computeTransform2(beamId, global_H_local0, global_H_local1, x); + l_interpolation->computeTransform(beamId, global_H_local0, global_H_local1, x); /// 2. Computes the frame of the beam based on the spline interpolation: Transform global_H_local; @@ -707,7 +707,7 @@ void AdaptiveBeamForceFieldAndMass::draw(const VisualParams *vparams) { Transform globalH0Local, globalH1Local; - l_interpolation->computeTransform2(b, globalH0Local, globalH1Local, x.ref()); + l_interpolation->computeTransform(b, globalH0Local, globalH1Local, x.ref()); unsigned int node0Idx, node1Idx; l_interpolation->getNodeIndices( b, node0Idx, node1Idx ); diff --git a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl index 95e65ba08..a5f36974e 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl @@ -558,7 +558,7 @@ void AdaptiveInflatableBeamForceField::addForce (const MechanicalPara /// 1. get the current transform of the beam: dmsg_info() << "in addForce"; - l_interpolation->computeTransform2(b, global_H_local0, global_H_local1, x); + l_interpolation->computeTransform(b, global_H_local0, global_H_local1, x); /// 2. Computes the frame of the beam based on the spline interpolation: Transform global_H_local; @@ -768,7 +768,7 @@ void AdaptiveInflatableBeamForceField::draw(const VisualParams *vpara { Transform globalH0Local, globalH1Local; - l_interpolation->computeTransform2(b, globalH0Local, globalH1Local, x.ref()); + l_interpolation->computeTransform(b, globalH0Local, globalH1Local, x.ref()); unsigned int node0Idx, node1Idx; l_interpolation->getNodeIndices( b, node0Idx, node1Idx ); From b045c9130d008f2cccb4444cd3a6750a56ed5de4 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 2 Jul 2023 00:27:36 +0200 Subject: [PATCH 40/60] [interpolation] Move ProjectionSearch into Slidingconstraint as it is only used by this component --- .../component/WireBeamInterpolation.h | 58 ---- .../component/WireBeamInterpolation.inl | 252 ----------------- .../AdaptiveBeamSlidingConstraint.h | 63 +++++ .../AdaptiveBeamSlidingConstraint.inl | 265 +++++++++++++++++- 4 files changed, 326 insertions(+), 312 deletions(-) diff --git a/src/BeamAdapter/component/WireBeamInterpolation.h b/src/BeamAdapter/component/WireBeamInterpolation.h index 74e69705c..1ee42d99a 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.h +++ b/src/BeamAdapter/component/WireBeamInterpolation.h @@ -141,7 +141,6 @@ class WireBeamInterpolation : public virtual BeamInterpolation void getCurvAbsAtBeam(const unsigned int &edgeInList_input, const Real& baryCoord_input, Real& x_output); bool getApproximateCurvAbs(const Vec3& x_input, const VecCoord& x, Real& x_output); // Project a point on the segments, return false if cant project - bool getCurvAbsOfProjection(const Vec3& x_input, const VecCoord& x, Real& x_output, const Real& tolerance); bool breaksInTwo(const Real &x_min_out, Real &x_break, int &numBeamsNotUnderControlled ); @@ -184,63 +183,6 @@ class WireBeamInterpolation : public virtual BeamInterpolation static typename T::SPtr create(T* tObj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) ; }; -/*! When the Newton method doesn't converge when searching for the closest projection on the curve, - * we will start a dichotomic search, for now a unoptimized brute force approach. - */ -template -class ProjectionSearch -{ -public: - typedef typename DataTypes::VecCoord VecCoord; - typedef typename DataTypes::Coord Coord; - typedef typename Coord::value_type Real; - - typedef Vec<3, Real> Vec3; - - /** - * @brief Default Constructor. - */ - ProjectionSearch(WireBeamInterpolation* inter, const Vec3& x_input, const VecCoord& vecX, Real& xcurv_output, const Real& tol) - : m_interpolation(inter), - m_x(vecX), - m_target(x_input), - m_found(false), - m_tolerance(tol), - m_totalIterations(0), - m_dichotomicIterations(0), - m_searchDirection(0), - m_e(xcurv_output) - {} - - WireBeamInterpolation *m_interpolation; ///< The interpolation using this class - const VecCoord& m_x; ///< The positions of the beams we are working on*/ - Vec3 m_target; ///< The point to be projected on the curve*/ - bool m_found; ///< True when the estimation is acceptable for the given tolerance*/ - Real m_tolerance; ///< Tolerance for the end of the search (projection of the estimation on the tangent is < than tolerance)*/ - unsigned int m_beamIndex; ///< The current beam for the search - unsigned int m_totalIterations; ///< # of iterations (including beam changes) - unsigned int m_dichotomicIterations; ///< # of iterations for the current beam - int m_searchDirection; ///< When we change beam, which direction is it ? - Real m_e; - Real m_le; - Real m_de; ///< Current estimation of the projection, its value in the current beam ([0,1]), and its distance to the target - Real m_beamStart, m_beamEnd; ///< Abscissa of the current beam extremities - Real m_segStart, m_segEnd; ///< Abscissa of the current search segment extremities - Real range, rangeSampling; ///< The length of the current search segment, and the distance between 2 sampling points - Vec3 P0,P1,P2,P3; ///< Current beam control points - - //TODO(dmarchal 2017-05-17) Je ne suis pas sur du tout de la robustesse de ce code. - //Pourquoi s_sampling n'est pas une constexpr ? - static const unsigned int s_sampling {10} ; ///< How many points do we consider each step ? (at least > 3 or it will never converge) - Real m_distTab[s_sampling+1]; ///< Array of distances - - bool doSearch(Real& result); - void initSearch(Real curvAbs); - void newtonMethod(); - bool changeCurrentBeam(int index); - Real computeDistAtCurvAbs(Real curvAbs); - bool testForProjection(Real curvAbs); -}; #if !defined(SOFA_PLUGIN_BEAMADAPTER_WIREBEAMINTERPOLATION_CPP) extern template class SOFA_BEAMADAPTER_API WireBeamInterpolation; diff --git a/src/BeamAdapter/component/WireBeamInterpolation.inl b/src/BeamAdapter/component/WireBeamInterpolation.inl index 48c45b9c5..83488ca75 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.inl +++ b/src/BeamAdapter/component/WireBeamInterpolation.inl @@ -273,13 +273,6 @@ bool WireBeamInterpolation::getApproximateCurvAbs(const Vec3& x_input return projected; } -template -bool WireBeamInterpolation::getCurvAbsOfProjection(const Vec3& x_input, const VecCoord& vecX, Real& xcurv_output, const Real& tolerance) -{ - // We have put all the code in a new class, because it uses a lot of custom functions and data - ProjectionSearch ps(this, x_input, vecX, xcurv_output, tolerance) ; - return ps.doSearch(xcurv_output) ; -} template bool WireBeamInterpolation::breaksInTwo(const Real &x_min_out, Real &x_break, int &numBeamsNotUnderControlled ) @@ -394,251 +387,6 @@ typename T::SPtr WireBeamInterpolation::create(T* tObj, core::object return obj; } -template -bool ProjectionSearch::doSearch(Real& result) -{ - initSearch(m_e); - - // Do one pass of the newton method - newtonMethod(); - - Real dist = computeDistAtCurvAbs(m_e); - - // If the new estimate is good, go with it - if(m_found) - { - result = m_e; - return testForProjection(result); - } - - // Look if the new estimate is closer to the target than the previous estimate - if(dist < m_de) - { - // If it is, continue with the newton method, it should converge fast - while(m_totalIterations < m_interpolation->getNumBeams()+1) - { - m_de = dist; - newtonMethod(); - m_totalIterations++; - - if(m_found) - { - // Go back to global curv abs - result = m_beamStart + (m_beamEnd - m_beamStart) * m_le; - return testForProjection(result); - } - - dist = computeDistAtCurvAbs(m_e); - if(dist > m_de) // Diverging - break; - - if(m_le < 0 || m_le > 1) // We have to change beam, use the dichotomic method instead - break; - } - } - - // If the estimate is outside the beam, or is further than the previous one, change beam - // and use a dichotomic search until we find a solution - if(!m_found) - { - m_totalIterations = 0; - - while(m_totalIterations < m_interpolation->getNumBeams() + 10 && m_dichotomicIterations < 10) - { - m_totalIterations++; - m_dichotomicIterations++; - - // We will compute 10 samples - range = m_segEnd - m_segStart; - rangeSampling = range / s_sampling; - for(unsigned int i=0; i<=s_sampling; i++) - { - Real curvAbs = m_segStart + rangeSampling * (Real)i; - m_distTab[i] = computeDistAtCurvAbs(curvAbs); - } - unsigned int minIndex = std::min_element(m_distTab, m_distTab + s_sampling + 1) - m_distTab; // Where is the minimum - m_e = m_segStart + rangeSampling * minIndex; - if(testForProjection(m_e)) - { - result = m_e; - return true; - } - - // If the minium is at one extremity, change beam - if(minIndex == 0) - changeCurrentBeam(m_beamIndex - 1); - else if(minIndex == s_sampling) - changeCurrentBeam(m_beamIndex + 1); - else - { // We continue the search with a smaller interval (keeping only 3 points) - m_segStart = m_e - rangeSampling; - m_segEnd = m_e + rangeSampling; - } - } - } - - result = m_e; - return testForProjection(result); -} - -template -void ProjectionSearch::initSearch(Real curvAbs) -{ - m_e = curvAbs; - if(m_e < 0) - { - m_beamIndex = 0; - m_le = 0; - } - else if(m_e > m_interpolation->getRestTotalLength()) - { - m_beamIndex = m_interpolation->getNumBeams()-1; - m_le = 1; - } - else - m_interpolation->getBeamAtCurvAbs(m_e, m_beamIndex, m_le); - - m_searchDirection = 0; - m_interpolation->getAbsCurvXFromBeam(m_beamIndex, m_beamStart, m_beamEnd); - m_segStart = m_beamStart; - m_segEnd = m_beamEnd; - m_interpolation->getSplinePoints(m_beamIndex, m_x, P0, P1, P2, P3); - m_de = computeDistAtCurvAbs(m_e); -} - -template -void ProjectionSearch::newtonMethod() -{ - Real bx = m_le, bx2 = bx*bx, bx3 = bx2*bx; - Real obx = 1-bx, obx2 = obx*obx, obx3 = obx2*obx; - Vec3 P = P0*obx3 + P1*3*bx*obx2 + P2*3*bx2*obx + P3*bx3; - Vec3 dP = P0*(-3*obx2) + P1*(3-12*bx+9*bx2) + P2*(6*bx-9*bx2) + P3*(3*bx2); - Real f_x = dot( (m_target - P) , dP ) ; - - if (f_x==0.0 || fabs(f_x)/dP.norm() < m_tolerance) // reach convergence - { - m_interpolation->getCurvAbsAtBeam(m_beamIndex, m_le, m_e); - m_found = true; - return; - } - Vec3 d2P = P0*6*(1-bx) + P1*(-12 + 18*bx) + P2*(6-18*bx) + P3*6*bx; - - Real df_x = dot(-dP,dP) + dot((m_target-P), d2P); - - if (fabs(df_x) < 1e-5*m_tolerance) - { - return; - } - - Real d_bx = -f_x/df_x; - m_le += d_bx; - - m_e = m_beamStart + (m_beamEnd - m_beamStart) * m_le; - - // NOTE : bx+d_bx-1.0 ne donne pas une estimation correcte de la position dans l'autre beam, puisque sa longueur peut �tre diff�rente ! -} - -template -bool ProjectionSearch::changeCurrentBeam(int index) -{ - // If at the end of the thread - if(index < 0) - { - m_segEnd = m_segStart + rangeSampling; - return false; - } - else if(index > static_cast(m_interpolation->getNumBeams())-1) - { - m_segStart = m_segEnd - rangeSampling; - return false; - } - - int dir = index - m_beamIndex; - if(m_searchDirection * dir < 0) - { // Changing the direction of search means we are looking for a point near an extremity - // We know we are looking for a point inside the interval [0.9;1.1] - // but the ranges for each beam can be different - Real nStart, nEnd; - m_interpolation->getAbsCurvXFromBeam(index, nStart, nEnd); - Real nRangeSampling = (nEnd - nStart) / s_sampling; - - if(dir < 0) - { - m_segStart = m_beamStart - nRangeSampling; - m_segEnd = m_beamStart + rangeSampling; - } - else - { - m_segStart = m_beamEnd - rangeSampling; - m_segEnd = m_beamEnd + nRangeSampling; - } - return false; - } - - - if(dir < 0) - m_searchDirection = -1; - else if(dir > 0) - m_searchDirection = 1; - - // Really changing beam - m_beamIndex = index; - m_interpolation->getAbsCurvXFromBeam(m_beamIndex, m_beamStart, m_beamEnd); - m_segStart = m_beamStart; - m_segEnd = m_beamEnd; - m_interpolation->getSplinePoints(m_beamIndex, m_x, P0, P1, P2, P3); - m_dichotomicIterations = 0; - - return true; -} - -template -typename ProjectionSearch::Real ProjectionSearch::computeDistAtCurvAbs(Real curvAbs) -{ - if(curvAbs >= m_beamStart && curvAbs <= m_beamEnd) - { // We can use the control points we saved - Real bx = (curvAbs - m_beamStart) / (m_beamEnd - m_beamStart), bx2 = bx*bx, bx3 = bx2*bx; - Real obx = 1-bx, obx2 = obx*obx, obx3 = obx2*obx; - Vec3 P = P0*obx3 + P1*3*bx*obx2 + P2*3*bx2*obx + P3*bx3; - - return (m_target-P).norm(); - } - else - { - // TODO(dmarchal 2017-05-17) Please specify who/when this will be done - // TODO : save all the control points so we don't have to compute them again - Real bx; - unsigned int index; - Vec3 tP0, tP1, tP2, tP3; - m_interpolation->getBeamAtCurvAbs(curvAbs, index, bx); - m_interpolation->getSplinePoints(index, m_x, tP0, tP1, tP2, tP3); - Real bx2 = bx*bx, bx3 = bx2*bx; - Real obx = 1-bx, obx2 = obx*obx, obx3 = obx2*obx; - Vec3 P = tP0*obx3 + tP1*3*bx*obx2 + tP2*3*bx2*obx + tP3*bx3; - - return (m_target-P).norm(); - } -} - -template -bool ProjectionSearch::testForProjection(Real curvAbs) -{ - Real bx; - unsigned int index; - Vec3 tP0, tP1, tP2, tP3; - m_interpolation->getBeamAtCurvAbs(curvAbs, index, bx); - m_interpolation->getSplinePoints(index, m_x, tP0, tP1, tP2, tP3); - Real bx2 = bx*bx, bx3 = bx2*bx; - Real obx = 1-bx, obx2 = obx*obx, obx3 = obx2*obx; - Vec3 P = tP0*obx3 + tP1*3*bx*obx2 + tP2*3*bx2*obx + tP3*bx3; - Vec3 dP = tP0*(-3*obx2) + tP1*(3-12*bx+9*bx2) + tP2*(6*bx-9*bx2) + tP3*(3*bx2); - Real f_x = dot( (m_target - P) , dP ) ; - - if (fabs(f_x)/dP.norm() < m_tolerance) - return true; - - return false; -} } // namespace _wirebeaminterpolation_ diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.h b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.h index ec3bb672d..5a214b1f4 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.h +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.h @@ -114,6 +114,8 @@ class SOFA_BEAMADAPTER_API AdaptiveBeamSlidingConstraint : public PairInteractio private: void internalInit(); + bool getCurvAbsOfProjection(const Vec3& x_input, const VecCoord& x, Real& x_output, const Real& tolerance); + unsigned int m_cid; int m_nbConstraints; /*!< number of constraints created */ type::vector m_violations; @@ -137,6 +139,67 @@ class SOFA_BEAMADAPTER_API AdaptiveBeamSlidingConstraint : public PairInteractio //////////////////////////////////////////////////////////////////////////// }; + + +/*! When the Newton method doesn't converge when searching for the closest projection on the curve, + * we will start a dichotomic search, for now a unoptimized brute force approach. + */ +template +class ProjectionSearch +{ +public: + typedef typename DataTypes::VecCoord VecCoord; + typedef typename DataTypes::Coord Coord; + typedef typename Coord::value_type Real; + + typedef Vec<3, Real> Vec3; + + /** + * @brief Default Constructor. + */ + ProjectionSearch(WireBeamInterpolation* inter, const Vec3& x_input, const VecCoord& vecX, Real& xcurv_output, const Real& tol) + : m_interpolation(inter), + m_x(vecX), + m_target(x_input), + m_found(false), + m_tolerance(tol), + m_totalIterations(0), + m_dichotomicIterations(0), + m_searchDirection(0), + m_e(xcurv_output) + {} + + WireBeamInterpolation* m_interpolation; ///< The interpolation using this class + const VecCoord& m_x; ///< The positions of the beams we are working on*/ + Vec3 m_target; ///< The point to be projected on the curve*/ + bool m_found; ///< True when the estimation is acceptable for the given tolerance*/ + Real m_tolerance; ///< Tolerance for the end of the search (projection of the estimation on the tangent is < than tolerance)*/ + unsigned int m_beamIndex; ///< The current beam for the search + unsigned int m_totalIterations; ///< # of iterations (including beam changes) + unsigned int m_dichotomicIterations; ///< # of iterations for the current beam + int m_searchDirection; ///< When we change beam, which direction is it ? + Real m_e; + Real m_le; + Real m_de; ///< Current estimation of the projection, its value in the current beam ([0,1]), and its distance to the target + Real m_beamStart, m_beamEnd; ///< Abscissa of the current beam extremities + Real m_segStart, m_segEnd; ///< Abscissa of the current search segment extremities + Real range, rangeSampling; ///< The length of the current search segment, and the distance between 2 sampling points + Vec3 P0, P1, P2, P3; ///< Current beam control points + + //TODO(dmarchal 2017-05-17) Je ne suis pas sur du tout de la robustesse de ce code. + //Pourquoi s_sampling n'est pas une constexpr ? + static const unsigned int s_sampling{ 10 }; ///< How many points do we consider each step ? (at least > 3 or it will never converge) + Real m_distTab[s_sampling + 1]; ///< Array of distances + + bool doSearch(Real& result); + void initSearch(Real curvAbs); + void newtonMethod(); + bool changeCurrentBeam(int index); + Real computeDistAtCurvAbs(Real curvAbs); + bool testForProjection(Real curvAbs); +}; + + #if !defined(SOFA_PLUGIN_BEAMADAPTER_ADAPTIVEBEAMSLIDINGCONSTRAINT_CPP) extern template class SOFA_BEAMADAPTER_API AdaptiveBeamSlidingConstraint; #endif diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl index ea0d0d538..c6a4cca5f 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl @@ -1,4 +1,4 @@ -/****************************************************************************** +/****************************************************************************** * BeamAdapter plugin * * (c) 2006 Inria, University of Lille, CNRS * * * @@ -128,6 +128,18 @@ void AdaptiveBeamSlidingConstraint::internalInit() } } + +template +bool AdaptiveBeamSlidingConstraint::getCurvAbsOfProjection(const Vec3& x_input, const VecCoord& vecX, Real& xcurv_output, const Real& tolerance) +{ + WireBeamInterpolation* interpolation = m_interpolation.get(); + + // We have put all the code in a new class, because it uses a lot of custom functions and data + ProjectionSearch ps(interpolation, x_input, vecX, xcurv_output, tolerance); + return ps.doSearch(xcurv_output); +} + + template void AdaptiveBeamSlidingConstraint::buildConstraintMatrix(const ConstraintParams * cParams, DataMatrixDeriv &c1_d, DataMatrixDeriv &c2_d, @@ -162,7 +174,7 @@ void AdaptiveBeamSlidingConstraint::buildConstraintMatrix(const Const // Get new projection on the curve m_previousPositions[i] += (Real) m_displacements[i]; - if(!interpolation->getCurvAbsOfProjection(x2[i].getCenter(), x1, m_previousPositions[i], 1e-5)) + if(!this->getCurvAbsOfProjection(x2[i].getCenter(), x1, m_previousPositions[i], 1e-5)) { m_projected[i] = false; continue; @@ -286,6 +298,255 @@ void AdaptiveBeamSlidingConstraint::draw(const VisualParams* vparams) vparams->drawTool()->restoreLastState(); } + +template +bool ProjectionSearch::doSearch(Real& result) +{ + initSearch(m_e); + + // Do one pass of the newton method + newtonMethod(); + + Real dist = computeDistAtCurvAbs(m_e); + + // If the new estimate is good, go with it + if (m_found) + { + result = m_e; + return testForProjection(result); + } + + // Look if the new estimate is closer to the target than the previous estimate + if (dist < m_de) + { + // If it is, continue with the newton method, it should converge fast + while (m_totalIterations < m_interpolation->getNumBeams() + 1) + { + m_de = dist; + newtonMethod(); + m_totalIterations++; + + if (m_found) + { + // Go back to global curv abs + result = m_beamStart + (m_beamEnd - m_beamStart) * m_le; + return testForProjection(result); + } + + dist = computeDistAtCurvAbs(m_e); + if (dist > m_de) // Diverging + break; + + if (m_le < 0 || m_le > 1) // We have to change beam, use the dichotomic method instead + break; + } + } + + // If the estimate is outside the beam, or is further than the previous one, change beam + // and use a dichotomic search until we find a solution + if (!m_found) + { + m_totalIterations = 0; + + while (m_totalIterations < m_interpolation->getNumBeams() + 10 && m_dichotomicIterations < 10) + { + m_totalIterations++; + m_dichotomicIterations++; + + // We will compute 10 samples + range = m_segEnd - m_segStart; + rangeSampling = range / s_sampling; + for (unsigned int i = 0; i <= s_sampling; i++) + { + Real curvAbs = m_segStart + rangeSampling * (Real)i; + m_distTab[i] = computeDistAtCurvAbs(curvAbs); + } + unsigned int minIndex = std::min_element(m_distTab, m_distTab + s_sampling + 1) - m_distTab; // Where is the minimum + m_e = m_segStart + rangeSampling * minIndex; + if (testForProjection(m_e)) + { + result = m_e; + return true; + } + + // If the minium is at one extremity, change beam + if (minIndex == 0) + changeCurrentBeam(m_beamIndex - 1); + else if (minIndex == s_sampling) + changeCurrentBeam(m_beamIndex + 1); + else + { // We continue the search with a smaller interval (keeping only 3 points) + m_segStart = m_e - rangeSampling; + m_segEnd = m_e + rangeSampling; + } + } + } + + result = m_e; + return testForProjection(result); +} + +template +void ProjectionSearch::initSearch(Real curvAbs) +{ + m_e = curvAbs; + if (m_e < 0) + { + m_beamIndex = 0; + m_le = 0; + } + else if (m_e > m_interpolation->getRestTotalLength()) + { + m_beamIndex = m_interpolation->getNumBeams() - 1; + m_le = 1; + } + else + m_interpolation->getBeamAtCurvAbs(m_e, m_beamIndex, m_le); + + m_searchDirection = 0; + m_interpolation->getAbsCurvXFromBeam(m_beamIndex, m_beamStart, m_beamEnd); + m_segStart = m_beamStart; + m_segEnd = m_beamEnd; + m_interpolation->getSplinePoints(m_beamIndex, m_x, P0, P1, P2, P3); + m_de = computeDistAtCurvAbs(m_e); +} + +template +void ProjectionSearch::newtonMethod() +{ + Real bx = m_le, bx2 = bx * bx, bx3 = bx2 * bx; + Real obx = 1 - bx, obx2 = obx * obx, obx3 = obx2 * obx; + Vec3 P = P0 * obx3 + P1 * 3 * bx * obx2 + P2 * 3 * bx2 * obx + P3 * bx3; + Vec3 dP = P0 * (-3 * obx2) + P1 * (3 - 12 * bx + 9 * bx2) + P2 * (6 * bx - 9 * bx2) + P3 * (3 * bx2); + Real f_x = dot((m_target - P), dP); + + if (f_x == 0.0 || fabs(f_x) / dP.norm() < m_tolerance) // reach convergence + { + m_interpolation->getCurvAbsAtBeam(m_beamIndex, m_le, m_e); + m_found = true; + return; + } + Vec3 d2P = P0 * 6 * (1 - bx) + P1 * (-12 + 18 * bx) + P2 * (6 - 18 * bx) + P3 * 6 * bx; + + Real df_x = dot(-dP, dP) + dot((m_target - P), d2P); + + if (fabs(df_x) < 1e-5 * m_tolerance) + { + return; + } + + Real d_bx = -f_x / df_x; + m_le += d_bx; + + m_e = m_beamStart + (m_beamEnd - m_beamStart) * m_le; + + // NOTE : bx+d_bx-1.0 ne donne pas une estimation correcte de la position dans l'autre beam, puisque sa longueur peut �tre diff�rente ! +} + +template +bool ProjectionSearch::changeCurrentBeam(int index) +{ + // If at the end of the thread + if (index < 0) + { + m_segEnd = m_segStart + rangeSampling; + return false; + } + else if (index > static_cast(m_interpolation->getNumBeams()) - 1) + { + m_segStart = m_segEnd - rangeSampling; + return false; + } + + int dir = index - m_beamIndex; + if (m_searchDirection * dir < 0) + { // Changing the direction of search means we are looking for a point near an extremity + // We know we are looking for a point inside the interval [0.9;1.1] + // but the ranges for each beam can be different + Real nStart, nEnd; + m_interpolation->getAbsCurvXFromBeam(index, nStart, nEnd); + Real nRangeSampling = (nEnd - nStart) / s_sampling; + + if (dir < 0) + { + m_segStart = m_beamStart - nRangeSampling; + m_segEnd = m_beamStart + rangeSampling; + } + else + { + m_segStart = m_beamEnd - rangeSampling; + m_segEnd = m_beamEnd + nRangeSampling; + } + return false; + } + + + if (dir < 0) + m_searchDirection = -1; + else if (dir > 0) + m_searchDirection = 1; + + // Really changing beam + m_beamIndex = index; + m_interpolation->getAbsCurvXFromBeam(m_beamIndex, m_beamStart, m_beamEnd); + m_segStart = m_beamStart; + m_segEnd = m_beamEnd; + m_interpolation->getSplinePoints(m_beamIndex, m_x, P0, P1, P2, P3); + m_dichotomicIterations = 0; + + return true; +} + +template +typename ProjectionSearch::Real ProjectionSearch::computeDistAtCurvAbs(Real curvAbs) +{ + if (curvAbs >= m_beamStart && curvAbs <= m_beamEnd) + { // We can use the control points we saved + Real bx = (curvAbs - m_beamStart) / (m_beamEnd - m_beamStart), bx2 = bx * bx, bx3 = bx2 * bx; + Real obx = 1 - bx, obx2 = obx * obx, obx3 = obx2 * obx; + Vec3 P = P0 * obx3 + P1 * 3 * bx * obx2 + P2 * 3 * bx2 * obx + P3 * bx3; + + return (m_target - P).norm(); + } + else + { + // TODO(dmarchal 2017-05-17) Please specify who/when this will be done + // TODO : save all the control points so we don't have to compute them again + Real bx; + unsigned int index; + Vec3 tP0, tP1, tP2, tP3; + m_interpolation->getBeamAtCurvAbs(curvAbs, index, bx); + m_interpolation->getSplinePoints(index, m_x, tP0, tP1, tP2, tP3); + Real bx2 = bx * bx, bx3 = bx2 * bx; + Real obx = 1 - bx, obx2 = obx * obx, obx3 = obx2 * obx; + Vec3 P = tP0 * obx3 + tP1 * 3 * bx * obx2 + tP2 * 3 * bx2 * obx + tP3 * bx3; + + return (m_target - P).norm(); + } +} + +template +bool ProjectionSearch::testForProjection(Real curvAbs) +{ + Real bx; + unsigned int index; + Vec3 tP0, tP1, tP2, tP3; + m_interpolation->getBeamAtCurvAbs(curvAbs, index, bx); + m_interpolation->getSplinePoints(index, m_x, tP0, tP1, tP2, tP3); + Real bx2 = bx * bx, bx3 = bx2 * bx; + Real obx = 1 - bx, obx2 = obx * obx, obx3 = obx2 * obx; + Vec3 P = tP0 * obx3 + tP1 * 3 * bx * obx2 + tP2 * 3 * bx2 * obx + tP3 * bx3; + Vec3 dP = tP0 * (-3 * obx2) + tP1 * (3 - 12 * bx + 9 * bx2) + tP2 * (6 * bx - 9 * bx2) + tP3 * (3 * bx2); + Real f_x = dot((m_target - P), dP); + + if (fabs(f_x) / dP.norm() < m_tolerance) + return true; + + return false; +} + + + } // namespace _adaptiveBeamSlidingConstraint_ } // namespace sofa::component::constraintset From f717e24264547c07863c2304c4d9ffbd25fd9761 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 2 Jul 2023 00:39:05 +0200 Subject: [PATCH 41/60] Remove canCreate and Create method form interpolation component --- src/BeamAdapter/component/BeamInterpolation.h | 19 --------- .../component/BeamInterpolation.inl | 9 ----- .../component/WireBeamInterpolation.h | 10 ----- .../component/WireBeamInterpolation.inl | 39 ------------------- 4 files changed, 77 deletions(-) diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index 254666bd6..b90e55b23 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -100,29 +100,10 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject BeamInterpolation() ; virtual ~BeamInterpolation() override = default; - //////////////////////////////////// Exposing this object in the factory /////////////////////// - /// Pre-construction check method called by ObjectFactory. - /// Check that DataTypes matches the MechanicalState. - template - static bool canCreate(T* obj, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) - { - if (dynamic_cast*>(context->getMechanicalState()) == nullptr) - { - arg->logError(std::string("No mechanical state with the datatype '") + DataTypes::Name() + - "' found in the context node."); - return false; - } - return BaseObject::canCreate(obj, context, arg); - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////// Inherited from Base /////////////////////////////////////// void init() override ; void bwdInit() override ; void reinit() override ; - void reset() override ; //TODO(dmarchal@cduriez) Ca me semble détourner l'API pour faire des choses par surprise. A mon avis la bonne solution //est d'implémenter un vrai binding Python pour BeamInterpolation. Avec une fonction updateInterpolation diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index 0b9253b93..fd86c5522 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -362,15 +362,6 @@ void BeamInterpolation::storeResetState() updateInterpolation(); } -template -void BeamInterpolation::reset() -{ - if(d_componentState.getValue()==ComponentState::Invalid) - return ; - - bwdInit(); - m_numBeamsNotUnderControl=0; -} template bool BeamInterpolation::interpolationIsAlreadyInitialized() diff --git a/src/BeamAdapter/component/WireBeamInterpolation.h b/src/BeamAdapter/component/WireBeamInterpolation.h index 1ee42d99a..39ce38476 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.h +++ b/src/BeamAdapter/component/WireBeamInterpolation.h @@ -171,16 +171,6 @@ class WireBeamInterpolation : public virtual BeamInterpolation using BeamInterpolation::m_componentstate ; //////////////////////////////////////////////////////////////////////////// -public: - - template - static bool canCreate(T* obj, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) - { - return Inherited::canCreate(obj,context,arg); - } - - template - static typename T::SPtr create(T* tObj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) ; }; diff --git a/src/BeamAdapter/component/WireBeamInterpolation.inl b/src/BeamAdapter/component/WireBeamInterpolation.inl index 83488ca75..9dc3c7482 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.inl +++ b/src/BeamAdapter/component/WireBeamInterpolation.inl @@ -349,45 +349,6 @@ bool WireBeamInterpolation::breaksInTwo(const Real &x_min_out, Real return true; } -template -template -typename T::SPtr WireBeamInterpolation::create(T* tObj, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg) -{ - WireRestShape* _restShape = nullptr; - std::string _restShapePath; - bool pathOK = false; - - if(arg) - { - if (arg->getAttribute("WireRestShape",nullptr) != nullptr) - { - _restShapePath = arg->getAttribute("WireRestShape"); - context->findLinkDest(_restShape, _restShapePath, nullptr); - - if(_restShape == nullptr) - msg_warning(context) << " ("<< tObj->getClassName() <<") : WireRestShape attribute not set correctly, WireBeamInterpolation will be constructed with a default WireRestShape" ; - else - pathOK = true; - } - else - msg_error(context) << " (" << tObj->getClassName() <<") : WireRestShape attribute not used, WireBeamInterpolation will be constructed with a default WireRestShape" ; - - - if (!pathOK) - { - _restShapePath=" "; - _restShape = new WireRestShape(); - } - } - - typename T::SPtr obj = sofa::core::objectmodel::New(_restShape); - obj->setPathToRestShape(_restShapePath); - if (context) context->addObject(obj); - if (arg) obj->parse(arg); - return obj; -} - - } // namespace _wirebeaminterpolation_ } // namespace sofa::component::fem From c5f36efc05d00f8a8549cdb0493ce53affa4b2d3 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 2 Jul 2023 01:36:20 +0200 Subject: [PATCH 42/60] Remove code linked to brokenIn2 --- src/BeamAdapter/component/BeamInterpolation.h | 12 +- .../component/BeamInterpolation.inl | 23 +--- .../component/WireBeamInterpolation.h | 15 ++- .../component/WireBeamInterpolation.inl | 123 +----------------- 4 files changed, 30 insertions(+), 143 deletions(-) diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index b90e55b23..f98fce3d7 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -120,7 +120,6 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject bool verifyTopology(); void computeCrossSectionInertiaMatrix(); - unsigned int getNumBeamsNotUnderControl(){return this->m_numBeamsNotUnderControl;} unsigned int getNumBeams(){return this->d_edgeList.getValue().size();} void getAbsCurvXFromBeam(int beam, Real& x_curv); @@ -256,6 +255,15 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject void addCollisionOnBeam(unsigned int b) ; void clearCollisionOnBeam() ; + /// Vector or links to the Wire section material. The order of the linked material will define the WireShape structure. + //Link, BaseRodSectionMaterial, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_sectionMaterial; + + /////////////////////////// Deprecated Methods ////////////////////////////////////////// + unsigned int getNumBeamsNotUnderControl() { + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + return 0; + } + protected : /// DATA INPUT (that could change in real-time) using StateDataTypes = sofa::defaulttype::StdVectorTypes< sofa::type::Vec, sofa::type::Vec, Real >; @@ -303,8 +311,6 @@ protected : /// this->brokenInTwo = if true, the wire is in two separate parts bool m_isControlled {false} ; - bool m_brokenInTwo {false} ; - unsigned int m_numBeamsNotUnderControl {0} ; }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_BEAMINTERPOLATION_CPP) diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index fd86c5522..94039f7fe 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -135,9 +135,7 @@ BeamInterpolation::BeamInterpolation() : , m_topology(nullptr) , m_mstate(nullptr) { - m_brokenInTwo=false; m_isControlled=false; - m_numBeamsNotUnderControl = 0; m_StateNodes->setName("bezierNodes"); addSlave(m_StateNodes); } @@ -417,22 +415,11 @@ void BeamInterpolation::clear() auto DOF1TransformNode1 = sofa::helper::getWriteOnlyAccessor(d_DOF1TransformNode1); auto curvAbsList = sofa::helper::getWriteOnlyAccessor(d_curvAbsList); - if(m_brokenInTwo) - { - edgeList.resize(m_numBeamsNotUnderControl); - lengthList.resize(m_numBeamsNotUnderControl); - DOF0TransformNode0.resize(m_numBeamsNotUnderControl); - DOF1TransformNode1.resize(m_numBeamsNotUnderControl); - curvAbsList.resize(m_numBeamsNotUnderControl); - } - else - { - edgeList.clear(); - lengthList.clear(); - DOF0TransformNode0.clear(); - DOF1TransformNode1.clear(); - curvAbsList.clear(); - } + edgeList.clear(); + lengthList.clear(); + DOF0TransformNode0.clear(); + DOF1TransformNode1.clear(); + curvAbsList.clear(); } diff --git a/src/BeamAdapter/component/WireBeamInterpolation.h b/src/BeamAdapter/component/WireBeamInterpolation.h index 39ce38476..da3c01aa8 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.h +++ b/src/BeamAdapter/component/WireBeamInterpolation.h @@ -137,12 +137,11 @@ class WireBeamInterpolation : public virtual BeamInterpolation virtual void getRestTransform(unsigned int edgeInList, Transform &local0_H_local1_rest); void getSplineRestTransform(unsigned int edgeInList, Transform &local_H_local0_rest, Transform &local_H_local1_rest) override; - void getBeamAtCurvAbs(const Real& x_input, unsigned int &edgeInList_output, Real& baryCoord_output, unsigned int start=0) override; void getCurvAbsAtBeam(const unsigned int &edgeInList_input, const Real& baryCoord_input, Real& x_output); bool getApproximateCurvAbs(const Vec3& x_input, const VecCoord& x, Real& x_output); // Project a point on the segments, return false if cant project - bool breaksInTwo(const Real &x_min_out, Real &x_break, int &numBeamsNotUnderControlled ); + void setPathToRestShape(const std::string &o){m_restShape.setPath(o);} @@ -171,6 +170,18 @@ class WireBeamInterpolation : public virtual BeamInterpolation using BeamInterpolation::m_componentstate ; //////////////////////////////////////////////////////////////////////////// + + + /////////////////////////// Deprecated Methods ////////////////////////////////////////// + + /// For coils: a part of the coil instrument can be brokenIn2 (by default the point of release is the end of the straight length) + bool breaksInTwo(const Real& x_min_out, Real& x_break, int& numBeamsNotUnderControlled) { + SOFA_UNUSED(x_min_out); + SOFA_UNUSED(x_break); + SOFA_UNUSED(numBeamsNotUnderControlled); + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + return 0.0; + } }; diff --git a/src/BeamAdapter/component/WireBeamInterpolation.inl b/src/BeamAdapter/component/WireBeamInterpolation.inl index 9dc3c7482..370366223 100644 --- a/src/BeamAdapter/component/WireBeamInterpolation.inl +++ b/src/BeamAdapter/component/WireBeamInterpolation.inl @@ -62,7 +62,7 @@ void WireBeamInterpolation::init() if( m_restShape.get() == nullptr ) { msg_error() << "Missing WireRestShape. The component is thus de-activated" ; - this->d_componentState = sofa::core::objectmodel::ComponentState::Invalid ; + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); return; } @@ -70,6 +70,8 @@ void WireBeamInterpolation::init() type::vector< int> nbP_density; m_restShape.get()->getSamplingParameters(xP_noticeable, nbP_density); + + this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid); } @@ -152,50 +154,6 @@ void WireBeamInterpolation::getSplineRestTransform(unsigned int edgeI } - -template -void WireBeamInterpolation::getBeamAtCurvAbs(const Real& x_input, unsigned int &edgeInList_output, - Real& baryCoord_output, unsigned int start) -{ - if(this->m_brokenInTwo ) - { - Real x_abs_broken = this->m_restShape.get()->getReleaseCurvAbs(); - - ////////// case 1.a : broken part !! - if (x_input > x_abs_broken) - { - - /// x_i = curv_abs from the begining of the broken part - Real x_i = x_input-x_abs_broken; - Real x=0.0; - - for (unsigned int e=0; em_numBeamsNotUnderControl; e++) - { - x += this->getLength(e); - if(x > x_i) - { - edgeInList_output = e; - Real x0 = x - this->getLength(e); - baryCoord_output =(x_i-x0) / this->getLength(e); - return; - } - } - - edgeInList_output = this->m_numBeamsNotUnderControl-1; - baryCoord_output = 1.0; - return; - - } - ////////// case 1.b : controlled part !! - else - { - start = this->m_numBeamsNotUnderControl; - } - } - - Inherited::getBeamAtCurvAbs(x_input, edgeInList_output, baryCoord_output, start); -} - template void WireBeamInterpolation::getCurvAbsAtBeam(const unsigned int &edgeInList_input, const Real& baryCoord_input, Real& x_output) { @@ -274,81 +232,6 @@ bool WireBeamInterpolation::getApproximateCurvAbs(const Vec3& x_input } -template -bool WireBeamInterpolation::breaksInTwo(const Real &x_min_out, Real &x_break, int &numBeamsNotUnderControlled ) -{ - const Real eps = 0.0000000001; - - if (this->m_brokenInTwo) - { - msg_error() << "Already broken" ; - return false; - } - - if (!this->isControlled() || this->m_restShape == nullptr || x_min_out <= eps) - { - msg_error() << "Problem with function breaksInTwo "; - return false; - } - - // if the release point is not "out" (x_min_out> x_break), then the break is not possible - x_break = m_restShape.get()->getReleaseCurvAbs(); - if (x_min_out > x_break) - return false; - - // put the info of the "released" part of the beam in the beginning of the beams; - this->m_numBeamsNotUnderControl=0; - unsigned int duplicatePoint=0; - - // browse the curvilinear abscissa to find the point that needs to be duplicate - // put the info of the second part of the wire at the begining - unsigned int i=0; - - auto edgeList = sofa::helper::getWriteOnlyAccessor(this->d_edgeList); - auto lengthList = sofa::helper::getWriteOnlyAccessor(this->d_lengthList); - auto DOF0TransformNode0 = sofa::helper::getWriteOnlyAccessor(this->d_DOF0TransformNode0); - auto DOF1TransformNode1 = sofa::helper::getWriteOnlyAccessor(this->d_DOF1TransformNode1); - auto curvAbsList = sofa::helper::getWriteOnlyAccessor(this->d_curvAbsList); - - const unsigned int curvAbsListSize = curvAbsList.size(); - - for (unsigned int e = 1; e < curvAbsListSize; e++) - { - if (fabs(curvAbsList[e].x() - x_break) < eps) - { - duplicatePoint = e; - this->m_numBeamsNotUnderControl = curvAbsListSize - e; - } - - if (curvAbsList[e].x() > (x_break - eps)) - { - edgeList[i] = edgeList[e]; - lengthList[i] = lengthList[e]; - curvAbsList[i] = curvAbsList[e]; - - // When the instrument are rotated we apply a transformation between DOF and beam node - // (should always be the case and dofsAndBeamsAligned should be false) - if (!this->d_dofsAndBeamsAligned.getValue()) - { - DOF0TransformNode0[i] = DOF0TransformNode0[e]; - DOF1TransformNode1[i] = DOF1TransformNode1[e]; - } - - i++; - } - } - - if (duplicatePoint == 0) - msg_error() << " Problem no point were found at the x_break position ! getReleaseCurvAbs() should provide a <> point" ; - - m_restShape.get()->releaseWirePart(); - numBeamsNotUnderControlled = this->m_numBeamsNotUnderControl; - - this->m_brokenInTwo = true; - - return true; -} - } // namespace _wirebeaminterpolation_ } // namespace sofa::component::fem From 3781efa184d1aa90d5e8a137ca560c315768b780 Mon Sep 17 00:00:00 2001 From: epernod Date: Sun, 2 Jul 2023 01:36:42 +0200 Subject: [PATCH 43/60] Turn method into const --- src/BeamAdapter/component/engine/WireRestShape.h | 4 ++-- src/BeamAdapter/component/engine/WireRestShape.inl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BeamAdapter/component/engine/WireRestShape.h b/src/BeamAdapter/component/engine/WireRestShape.h index 2ab349ce9..f1fba7d0d 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.h +++ b/src/BeamAdapter/component/engine/WireRestShape.h @@ -108,9 +108,9 @@ class WireRestShape : public core::objectmodel::BaseObject void computeOrientation(const Vec3& AB, const Quat& Q, Quat &result); - Real getLength() ; + const Real& getLength() const; void getCollisionSampling(Real &dx, const Real &x_curv); - void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines) ; + void getNumberOfCollisionSegment(Real &dx, unsigned int &numLines); diff --git a/src/BeamAdapter/component/engine/WireRestShape.inl b/src/BeamAdapter/component/engine/WireRestShape.inl index 1ae3484e6..9fce08840 100644 --- a/src/BeamAdapter/component/engine/WireRestShape.inl +++ b/src/BeamAdapter/component/engine/WireRestShape.inl @@ -305,7 +305,7 @@ void WireRestShape::getInterpolationParam(const Real& x_curv, Real &_ template -typename WireRestShape::Real WireRestShape::getLength() +const typename WireRestShape::Real& WireRestShape::getLength() const { return d_keyPoints.getValue().back(); } From b6326c9ef1aca8a68fda0dafcc15bd9a3a3efa3e Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 3 Jul 2023 11:57:27 +0200 Subject: [PATCH 44/60] revert [IRCtrl] skip onKey event and comment partially onAnimationBeginEvent to use only the BeamActionController events. --- .../InterventionalRadiologyController.inl | 103 +++++++++--------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 8ccbb5ab7..1a6026511 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -248,9 +248,6 @@ void InterventionalRadiologyController::onMouseEvent(MouseEvent * mev template void InterventionalRadiologyController::onKeyPressedEvent(KeypressedEvent *kev) { - - return; - /// Control keys for interventonal Radiology simulations: switch(kev->getKey()) { @@ -311,56 +308,56 @@ template void InterventionalRadiologyController::onBeginAnimationStep(const double dt) { SOFA_UNUSED(dt); - - //BaseContext* context = getContext(); - //auto xInstrTip = sofa::helper::getWriteOnlyAccessor(d_xTip); - //if(m_FF || m_RW) - //{ - // int id = d_controlledInstrument.getValue(); - // if (id >= (int)xInstrTip.size()) - // { - // msg_warning()<<"Controlled Instument num "<getDt(); - // else - // { - // unsigned int newSensorData = m_currentSensorData + 1; - - // while( m_sensorMotionData[newSensorData][0] < context->getTime() ) - // { - // m_currentSensorData = newSensorData; - // newSensorData++; - // } - // if(newSensorData >= m_sensorMotionData.size()) - // { - // xInstrTip[id] = 0; - // } - // else - // { - // xInstrTip[id] += m_sensorMotionData[m_currentSensorData][1]; - // } - // } - // } - // if (m_RW) - // { - // xInstrTip[id] -= d_speed.getValue()* context->getDt(); - // // verif min x : - // if ( xInstrTip[id] < 0.0) - // { - // xInstrTip[id] = 0.0; - // m_RW = false; - // } - // } - //} - - ///// The tip of the instrument can not be further than its total length - //for (unsigned int i=0; i m_instrumentsList[i]->getRestTotalLength() ) - // xInstrTip[i] = m_instrumentsList[i]->getRestTotalLength(); + + BaseContext* context = getContext(); + auto xInstrTip = sofa::helper::getWriteOnlyAccessor(d_xTip); + if(m_FF || m_RW) + { + int id = d_controlledInstrument.getValue(); + if (id >= (int)xInstrTip.size()) + { + msg_warning()<<"Controlled Instument num "<getDt(); + else + { + unsigned int newSensorData = m_currentSensorData + 1; + + while( m_sensorMotionData[newSensorData][0] < context->getTime() ) + { + m_currentSensorData = newSensorData; + newSensorData++; + } + if(newSensorData >= m_sensorMotionData.size()) + { + xInstrTip[id] = 0; + } + else + { + xInstrTip[id] += m_sensorMotionData[m_currentSensorData][1]; + } + } + } + if (m_RW) + { + xInstrTip[id] -= d_speed.getValue()* context->getDt(); + // verif min x : + if ( xInstrTip[id] < 0.0) + { + xInstrTip[id] = 0.0; + m_RW = false; + } + } + } + + /// The tip of the instrument can not be further than its total length + for (unsigned int i=0; i m_instrumentsList[i]->getRestTotalLength() ) + xInstrTip[i] = m_instrumentsList[i]->getRestTotalLength(); applyInterventionalRadiologyController(); } From f95f070ca938c0a39e37cccf789dfbfc261c7455 Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 3 Jul 2023 12:16:53 +0200 Subject: [PATCH 45/60] [BeamInterpolation] Add method computeTransform with node indices as parameters to avoid multiple call of GetNodeIndices when they are already known --- src/BeamAdapter/component/BeamInterpolation.h | 5 ++++- .../component/BeamInterpolation.inl | 22 +++++++++++++------ .../AdaptiveBeamLengthConstraint.inl | 17 +++++++------- .../AdaptiveBeamSlidingConstraint.inl | 7 +++--- .../AdaptiveBeamForceFieldAndMass.inl | 10 ++++----- .../AdaptiveInflatableBeamForceField.inl | 10 ++++----- 6 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/BeamAdapter/component/BeamInterpolation.h b/src/BeamAdapter/component/BeamInterpolation.h index f98fce3d7..9b3838e5d 100644 --- a/src/BeamAdapter/component/BeamInterpolation.h +++ b/src/BeamAdapter/component/BeamInterpolation.h @@ -136,7 +136,10 @@ class BeamInterpolation : public virtual sofa::core::objectmodel::BaseObject void getDOFtoLocalTransformInGlobalFrame(unsigned int edgeInList, Transform &DOF0Global_H_local0, Transform &DOF1Global_H_local1, const VecCoord &x); - int computeTransform(ElementID edgeInList, Transform &global_H_local0, Transform &global_H_local1, const VecCoord &x); + int computeTransform(const ElementID edgeInList, Transform &global_H_local0, Transform &global_H_local1, const VecCoord &x); + int computeTransform(const ElementID edgeInList, const PointID node0Idx, const PointID node1Idx, Transform& global_H_local0, Transform& global_H_local1, const VecCoord& x); + + void getTangent(Vec3& t, const Real& baryCoord, const Transform &global_H_local0, const Transform &global_H_local1,const Real &L); diff --git a/src/BeamAdapter/component/BeamInterpolation.inl b/src/BeamAdapter/component/BeamInterpolation.inl index 94039f7fe..c11dd06a5 100644 --- a/src/BeamAdapter/component/BeamInterpolation.inl +++ b/src/BeamAdapter/component/BeamInterpolation.inl @@ -313,7 +313,7 @@ void BeamInterpolation::bwdInit() // this transforamtion is given by global_H_local0 for node 0 (and dof0) // and global_H_local1 for node 1 (and dof1) Transform global_H_local0, global_H_local1; - computeTransform(i, global_H_local0, global_H_local1, statePos.ref()) ; + computeTransform(i, nd0Id, nd1Id, global_H_local0, global_H_local1, statePos.ref()); Vec3 beam_segment = global_H_local1.getOrigin() - global_H_local0.getOrigin(); lengthList.push_back(beam_segment.norm()); @@ -619,7 +619,7 @@ void BeamInterpolation::getDOFtoLocalTransformInGlobalFrame(unsigned template -int BeamInterpolation::computeTransform(ElementID edgeInList, +int BeamInterpolation::computeTransform(const ElementID edgeInList, Transform &global_H_local0, Transform &global_H_local1, const VecCoord &x) @@ -632,16 +632,24 @@ int BeamInterpolation::computeTransform(ElementID edgeInList, return -1; } + return computeTransform(edgeInList, node0Idx, node1Idx, global_H_local0, global_H_local1, x); +} + + +template +int BeamInterpolation::computeTransform(const ElementID edgeInList, const PointID node0Idx, const PointID node1Idx, Transform& global_H_local0, Transform& global_H_local1, const VecCoord& x) +{ + /// 2. Computes the optional rigid transformation of DOF0_Transform_node0 and DOF1_Transform_node1 Transform DOF0_H_local0, DOF1_H_local1; - getDOFtoLocalTransform(edgeInList, DOF0_H_local0, DOF1_H_local1); + getDOFtoLocalTransform(edgeInList, DOF0_H_local0, DOF1_H_local1); /// 3. Computes the transformation global To local for both nodes - Transform global_H_DOF0(x[node0Idx].getCenter(),x[node0Idx].getOrientation()); - Transform global_H_DOF1(x[node1Idx].getCenter(),x[node1Idx].getOrientation()); + Transform global_H_DOF0(x[node0Idx].getCenter(), x[node0Idx].getOrientation()); + Transform global_H_DOF1(x[node1Idx].getCenter(), x[node1Idx].getOrientation()); /// - add a optional transformation - global_H_local0 = global_H_DOF0*DOF0_H_local0; - global_H_local1 = global_H_DOF1*DOF1_H_local1; + global_H_local0 = global_H_DOF0 * DOF0_H_local0; + global_H_local1 = global_H_DOF1 * DOF1_H_local1; return 1; /// no error } diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl b/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl index 8724472a7..9d875919b 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamLengthConstraint.inl @@ -119,14 +119,15 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x length=(P0-P3).norm(); rest_length = interpolation->getLength(b); + unsigned n0, n1; + interpolation->getNodeIndices(b, n0, n1); + /// 2. compute the bending angle Transform Tnode0, Tnode1; - interpolation->computeTransform(b,Tnode0,Tnode1,x); + interpolation->computeTransform(b, n0, n1, Tnode0,Tnode1,x); Real angleBeam = interpolation->ComputeTotalBendingRotationAngle(rest_length/10.0, Tnode0, Tnode1,rest_length , 0.0, 1.0); /// 3. treatment of the different case.. - unsigned n0, n1; - interpolation->getNodeIndices(b, n0, n1); bool case1a = (n0==n1); if(prev_stretch) @@ -164,7 +165,7 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x interpolation->getSplinePoints(b,xfree,P0,P1,P2,P3); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, n0, n1, global_H_local0_free, global_H_local1_free, xfree); intervalDef.posFreeEnd = global_H_local0_free.getOrigin(); /// store the free position intervalDef.rest_length=rest_length_interval; /// store the rest_length @@ -231,10 +232,10 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x interpolation->getDOFtoLocalTransform(b, DOF0_H_local0, DOF1_H_local1); Transform global_H_local0, global_H_local1; - interpolation->computeTransform(b, global_H_local0, global_H_local1, x); + interpolation->computeTransform(b, n0, n1, global_H_local0, global_H_local1, x); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, n0, n1, global_H_local0_free, global_H_local1_free, xfree); intervalDef.dof_H_begin = DOF0_H_local0; intervalDef.IdxBegin = n0; @@ -262,11 +263,11 @@ void AdaptiveBeamLengthConstraint::detectElongation(const VecCoord& x Transform global_H_local0, global_H_local1; - interpolation->computeTransform(b, global_H_local0, global_H_local1, x); + interpolation->computeTransform(b, n0, n1, global_H_local0, global_H_local1, x); Transform global_H_local0_free, global_H_local1_free; - interpolation->computeTransform(b, global_H_local0_free, global_H_local1_free, xfree); + interpolation->computeTransform(b, n0, n1, global_H_local0_free, global_H_local1_free, xfree); intervalDef.dof_H_end = DOF1_H_local1; diff --git a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl index c6a4cca5f..1c7d84cdb 100644 --- a/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl +++ b/src/BeamAdapter/component/constraint/AdaptiveBeamSlidingConstraint.inl @@ -180,9 +180,12 @@ void AdaptiveBeamSlidingConstraint::buildConstraintMatrix(const Const continue; } + unsigned int node0, node1; + interpolation->getNodeIndices(beam, node0, node1); + // Position and frame on the curve interpolation->getBeamAtCurvAbs(m_previousPositions[i], beam, baryCoord); - interpolation->computeTransform(beam, Tnode0, Tnode1, x1free.ref()); + interpolation->computeTransform(beam, node0, node1, Tnode0, Tnode1, x1free.ref()); interpolation->InterpolateTransformUsingSpline(Tresult, baryCoord, Tnode0, Tnode1, interpolation->getLength(beam)); Pos p = Tresult.getOrigin(); Pos dir0, dir1, dir2; @@ -198,10 +201,8 @@ void AdaptiveBeamSlidingConstraint::buildConstraintMatrix(const Const m_violations.push_back(violation * dir0); // Define the constraint - unsigned int node0, node1; SpatialVector sv0, sv1; Vec3 nullRot(0,0,0); - interpolation->getNodeIndices(beam, node0, node1); MatrixDerivRowIterator c1_it = c1.wref().writeLine(m_cid + m_nbConstraints); MatrixDerivRowIterator c2_it = c2.wref().writeLine(m_cid + m_nbConstraints); diff --git a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl index 5078bccab..6f828f3e6 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveBeamForceFieldAndMass.inl @@ -460,8 +460,8 @@ void AdaptiveBeamForceFieldAndMass::addForce (const MechanicalParams* for (unsigned int beamId=0; beamId getNodeIndices(beamId, node0Idx, node1Idx ); + sofa::Index node0Idx, node1Idx; + l_interpolation->getNodeIndices(beamId, node0Idx, node1Idx); ///find the beamMatrices: BeamLocalMatrices& beamMatrices = m_localBeamMatrices[beamId]; @@ -470,7 +470,7 @@ void AdaptiveBeamForceFieldAndMass::addForce (const MechanicalParams* Transform global_H_local0, global_H_local1; /// 1. get the current transform of the beam: - l_interpolation->computeTransform(beamId, global_H_local0, global_H_local1, x); + l_interpolation->computeTransform(beamId, node0Idx, node1Idx, global_H_local0, global_H_local1, x); /// 2. Computes the frame of the beam based on the spline interpolation: Transform global_H_local; @@ -707,9 +707,9 @@ void AdaptiveBeamForceFieldAndMass::draw(const VisualParams *vparams) { Transform globalH0Local, globalH1Local; - l_interpolation->computeTransform(b, globalH0Local, globalH1Local, x.ref()); unsigned int node0Idx, node1Idx; - l_interpolation->getNodeIndices( b, node0Idx, node1Idx ); + l_interpolation->getNodeIndices(b, node0Idx, node1Idx); + l_interpolation->computeTransform(b, node0Idx, node1Idx, globalH0Local, globalH1Local, x.ref()); if (vparams->displayFlags().getShowBehaviorModels() && node0Idx!=node1Idx) drawElement(vparams, b, globalH0Local, globalH1Local); diff --git a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl index a5f36974e..01c47b353 100644 --- a/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl +++ b/src/BeamAdapter/component/forcefield/AdaptiveInflatableBeamForceField.inl @@ -547,8 +547,8 @@ void AdaptiveInflatableBeamForceField::addForce (const MechanicalPara for (unsigned int b=0; bgetNodeIndices( b, node0Idx, node1Idx ); + sofa::Index node0Idx, node1Idx; + l_interpolation->getNodeIndices(b, node0Idx, node1Idx); ///find the beamMatrices: BeamLocalMatrices *beamMatrices = &m_localBeamMatrices[b] ;//new BeamLocalMatrices(); @@ -558,7 +558,7 @@ void AdaptiveInflatableBeamForceField::addForce (const MechanicalPara /// 1. get the current transform of the beam: dmsg_info() << "in addForce"; - l_interpolation->computeTransform(b, global_H_local0, global_H_local1, x); + l_interpolation->computeTransform(b, node0Idx, node1Idx, global_H_local0, global_H_local1, x); /// 2. Computes the frame of the beam based on the spline interpolation: Transform global_H_local; @@ -768,9 +768,9 @@ void AdaptiveInflatableBeamForceField::draw(const VisualParams *vpara { Transform globalH0Local, globalH1Local; - l_interpolation->computeTransform(b, globalH0Local, globalH1Local, x.ref()); unsigned int node0Idx, node1Idx; - l_interpolation->getNodeIndices( b, node0Idx, node1Idx ); + l_interpolation->getNodeIndices(b, node0Idx, node1Idx); + l_interpolation->computeTransform(b, node0Idx, node1Idx, globalH0Local, globalH1Local, x.ref()); if (vparams->displayFlags().getShowBehaviorModels() && node0Idx!=node1Idx) drawElement(vparams, b, globalH0Local, globalH1Local); From 3983008f387158b33572ccaec27caf4801c385b7 Mon Sep 17 00:00:00 2001 From: epernod Date: Mon, 24 Jul 2023 17:06:49 +0200 Subject: [PATCH 46/60] [scenes] Fix scenes regression --- examples/3instruments_collis.scn | 4 ++-- examples/SingleBeamDeployment.scn | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/3instruments_collis.scn b/examples/3instruments_collis.scn index 7c30267b6..f0ec7c7ba 100644 --- a/examples/3instruments_collis.scn +++ b/examples/3instruments_collis.scn @@ -38,8 +38,8 @@ - - + + diff --git a/examples/SingleBeamDeployment.scn b/examples/SingleBeamDeployment.scn index 6b6287acc..f29e61142 100644 --- a/examples/SingleBeamDeployment.scn +++ b/examples/SingleBeamDeployment.scn @@ -15,8 +15,8 @@ - - + + From a34459be5c9f27733684d7db6d40134f6232ce47 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 25 Jul 2023 10:28:00 +0200 Subject: [PATCH 47/60] Add action to export the actions, otherwise it was done when the next action is done --- .../component/controller/BeamAdapterActionController.inl | 2 +- src/BeamAdapter/utils/BeamActions.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/BeamAdapter/component/controller/BeamAdapterActionController.inl b/src/BeamAdapter/component/controller/BeamAdapterActionController.inl index 312550be8..bf920475e 100644 --- a/src/BeamAdapter/component/controller/BeamAdapterActionController.inl +++ b/src/BeamAdapter/component/controller/BeamAdapterActionController.inl @@ -67,7 +67,7 @@ void BeamAdapterActionController::onKeyPressedEvent(core::objectmodel switch (kev->getKey()) { case 'E': - m_currAction = BeamAdapterAction::NO_ACTION; + m_currAction = BeamAdapterAction::EXPORT_ACTION; m_exportActions = !m_exportActions; break; case 'D': diff --git a/src/BeamAdapter/utils/BeamActions.h b/src/BeamAdapter/utils/BeamActions.h index ea91418de..c82477857 100644 --- a/src/BeamAdapter/utils/BeamActions.h +++ b/src/BeamAdapter/utils/BeamActions.h @@ -38,6 +38,7 @@ namespace sofa::beamadapter USE_TOOL_0, USE_TOOL_1, USE_TOOL_2, + EXPORT_ACTION }; /// \brief map of action as string keyword instead of int for better clarity in scene scripting From be65e4bcada9058385ce1360b6972ba327d64c49 Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 25 Jul 2023 10:28:18 +0200 Subject: [PATCH 48/60] backup logs for debug --- .../InterventionalRadiologyController.inl | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 1a6026511..aefa835aa 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -777,7 +777,7 @@ template void InterventionalRadiologyController::applyInterventionalRadiologyController() { const Real& threshold = d_threshold.getValue(); - + std::cout << "------- applyInterventionalRadiologyController ------" << std::endl; /// Create vectors with the CurvAbs of the noticiable points and the id of the corresponding instrument type::vector newCurvAbs; @@ -785,9 +785,6 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC unsigned int previousNumControlledNodes = m_numControlledNodes; unsigned int seg_remove = 0; - if (m_dropCall) - processDrop(previousNumControlledNodes, seg_remove); - /// STEP 1 /// Find the total length of the COMBINED INSTRUMENTS and the one for which xtip > 0 (so the one which are simulated) Real xend; @@ -797,7 +794,10 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC for (unsigned int i=0; igetRestTotalLength(); + std::cout << "instru: " << i << " | m_instrumentsList[i]->getRestTotalLength(): " << m_instrumentsList[i]->getRestTotalLength() << std::endl; xbegin.push_back(xb); if (xend> totalLengthCombined) @@ -815,6 +815,8 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC } } + std::cout << "totalLengthCombined: " << totalLengthCombined << std::endl; + /// Some verif of step 1 // if the totalLength is 0, move the first instrument if (totalLengthCombined < std::numeric_limits::epsilon()) @@ -827,6 +829,8 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC helper::AdvancedTimer::stepEnd("step1"); + + /// STEP 2: /// get the noticeable points that need to be simulated // Fill=> newCurvAbs which provides a vector with curvilinear abscissa of each simulated node @@ -837,6 +841,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC interventionalRadiologyComputeSampling(newCurvAbs, idInstrumentTable, xbegin, totalLengthCombined); helper::AdvancedTimer::stepEnd("step2"); + std::cout << "newCurvAbs: " << newCurvAbs << std::endl; /// STEP 3 /// Re-interpolate the positions and the velocities @@ -850,10 +855,12 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const sofa::Size nbrCurvAbs = newCurvAbs.size(); // number of simulated nodes const sofa::Size prev_nbrCurvAbs = m_nodeCurvAbs.size(); // previous number of simulated nodes; const Real prev_maxCurvAbs = m_nodeCurvAbs.back(); + std::cout << "m_nodeCurvAbs: " << m_nodeCurvAbs << std::endl; // Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) type::vector modifiedCurvAbs; totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); + std::cout << "modifiedCurvAbs: " << modifiedCurvAbs << std::endl; sofa::Size nbrUnactiveNode = m_numControlledNodes - nbrCurvAbs; // m_numControlledNodes == nbr Dof | nbr of CurvAbs > 0 sofa::Size prev_nbrUnactiveNode = previousNumControlledNodes - prev_nbrCurvAbs; @@ -863,11 +870,16 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const sofa::Index globalNodeId = nbrUnactiveNode + xId; const Real xCurvAbs = modifiedCurvAbs[xId]; + //std::cout << "xCurvAbs - eps: " << (xCurvAbs - std::numeric_limits::epsilon()) << " | prev_maxCurvAbs + threshold: " << prev_maxCurvAbs + threshold << std::endl; + // 2 cases: TODO : remove first case //1. the abs curv is further than the previous state of the instrument //2. this is not the case and the node position can be interpolated using previous step positions if ((xCurvAbs - std::numeric_limits::epsilon()) > prev_maxCurvAbs + threshold) { + //std::cout << "xCurvAbs - eps: " << (xCurvAbs - std::numeric_limits::epsilon()) << std::endl; + //std::cout << "prev_maxCurvAbs + threshold: " << prev_maxCurvAbs + threshold << std::endl; + msg_error() << "Case 1 should never happen ==> avoid using totalLengthIsChanging! xCurvAbs = " << xCurvAbs << " > prev_maxCurvAbs = " << prev_maxCurvAbs << " + threshold: " << threshold << "\n" << "\n | newCurvAbs: " << newCurvAbs From c0341fff66ff24ae922d7f41d0465b2c97d6de8a Mon Sep 17 00:00:00 2001 From: epernod Date: Tue, 25 Jul 2023 12:03:57 +0200 Subject: [PATCH 49/60] Remove code related to drop action, not anymore supported --- .../InterventionalRadiologyController.h | 13 ++- .../InterventionalRadiologyController.inl | 80 +------------------ 2 files changed, 11 insertions(+), 82 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h index 0eeabc68d..e5aa50813 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h @@ -114,6 +114,16 @@ class InterventionalRadiologyController : public MechanicalStateController& getCurrentCurvAbscisses() const { return m_nodeCurvAbs; } + + /////////////////////////// Deprecated Methods ////////////////////////////////////////// + void processDrop(unsigned int& previousNumControlledNodes, unsigned int& seg_remove) + { + SOFA_UNUSED(previousNumControlledNodes); + SOFA_UNUSED(seg_remove); + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; + } + + public: using Inherit1::f_printLog; @@ -131,7 +141,6 @@ class InterventionalRadiologyController : public MechanicalStateController &newCurvAbs, type::vector< type::vector > &id_instrument_table, const type::vector &xBegin, const Real& xEnd); /// Sort the curv Abs in the ascending order and avoid doubloon void sortCurvAbs(type::vector &CurvAbs, type::vector< type::vector >& id_instrument_table); @@ -156,13 +165,11 @@ class InterventionalRadiologyController : public MechanicalStateController * m_fixedConstraint; - type::vector m_droppedInstruments; type::vector m_sensorMotionData; unsigned int m_currentSensorData; type::vector m_nodeCurvAbs; type::vector< type::vector > m_idInstrumentCurvAbsTable; unsigned int m_numControlledNodes; // Excluding the nodes that are "dropped" - bool m_dropCall; }; #if !defined(SOFA_PLUGIN_BEAMADAPTER_INTERVENTIONALRADIOCONTROLLER_CPP) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index aefa835aa..00beee481 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -74,7 +74,6 @@ InterventionalRadiologyController::InterventionalRadiologyController( , d_indexFirstNode(initData(&d_indexFirstNode, (unsigned int) 0, "indexFirstNode", "first node (should be fixed with restshape)")) { m_fixedConstraint = nullptr; - m_dropCall = false; m_sensored =false; } @@ -141,10 +140,6 @@ void InterventionalRadiologyController::init() if(m_fixedConstraint==nullptr) msg_error()<<"No fixedConstraint found."; - /// List of the instrument for which a "DROPPED" was proceeed TODO - m_droppedInstruments.clear(); - - // the controller must listen to the event (in particular BeginAnimationStep event) if (!f_listening.isSet()) { @@ -440,82 +435,9 @@ void InterventionalRadiologyController::applyAction(sofa::beamadapter } case BeamAdapterAction::DROP_TOOL: { - m_dropCall = true; - } + msg_warning() << "Releasing catheter or brokenIn2 mode is not anymore supported. Feature has been removed after release v23.06"; } -} - - -template -void InterventionalRadiologyController::processDrop(unsigned int &previousNumControlledNodes, - unsigned int &segRemove) -{ - int ci = int(d_controlledInstrument.getValue()); - Real xMinOutLocal= 0.0; - - Real xBegin=0.0; - - // Quelque soit le resultat du process, le drop call est traite ici - m_dropCall = false; - - // Step1 : quel est l'abscisse curviligne ou l'instrument controllé est seul ? - for (unsigned int i=0; igetRestTotalLength(); - xMinOutLocal = m_nodeCurvAbs[i] - xBegin; - break; - } - else - { - msg_error()<<" The control instrument is not out, drop is impossible."; - return; - } - } - } - - if(xMinOutLocal<=0.0) - { - msg_error()<<" x_min_out_local <= 0.0 The control instrument is not out, drop is impossible."; - return; - } - - // Step2 : on verifie que cette abscisse curviligne est compatible avec celle de l'instrument - // (on ne peut pas casser un instrument s'il est à l'intérieur d'un autre instrument) - int numBeamsNotUnderControlled = 0; - Real xBreak; - if( m_instrumentsList[ci]->breaksInTwo(xMinOutLocal, xBreak, numBeamsNotUnderControlled) ) - { - msg_error()<<"Breaks in two process activated."; - - // for now, we simply suppress one more beam ! - m_numControlledNodes -= (numBeamsNotUnderControlled + 1); - - auto xEnds = sofa::helper::getWriteOnlyAccessor(d_xTip); - xEnds[ci] = xBegin + xBreak; - } - else - return; - - // Step3 : on remet à jour les abscisse curviligne des noeuds en virant toutes celles qui correspondent à la partie - // cassée - Real eps=d_threshold.getValue(); - for (unsigned int i=0; i (xBegin + xBreak + eps) ) - { - type::removeIndex(m_nodeCurvAbs,i); - type::removeIndex(m_idInstrumentCurvAbsTable, i); - i--; - } } - segRemove = 1; - previousNumControlledNodes =m_numControlledNodes; } From 57b24265e996422225ce33164657daa861be570d Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 12:15:01 +0200 Subject: [PATCH 50/60] [IRC] Clean unused method --- .../InterventionalRadiologyController.h | 12 +++++------- .../InterventionalRadiologyController.inl | 15 --------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h index e5aa50813..17c97f2eb 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h @@ -88,20 +88,18 @@ class InterventionalRadiologyController : public MechanicalStateController &x_point_list, type::vector &id_instrument_list, type::vector &removeEdge); diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 00beee481..001f30c03 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -230,16 +230,6 @@ void InterventionalRadiologyController::bwdInit() } -/*! - * \todo fix the mouse event with better controls - */ -template -void InterventionalRadiologyController::onMouseEvent(MouseEvent * mev) -{ - SOFA_UNUSED(mev); -} - - template void InterventionalRadiologyController::onKeyPressedEvent(KeypressedEvent *kev) { @@ -1060,11 +1050,6 @@ void InterventionalRadiologyController::fixFirstNodesWithUntil(unsign d_indexFirstNode = firstSimulatedNode-1 ; } -template -bool InterventionalRadiologyController::modifyTopology(void) -{ - return false; -} template void InterventionalRadiologyController::getInstrumentList(type::vector*>& list) From e52bfe0b0b5127b98213c511e3dc21f62893f530 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 12:29:17 +0200 Subject: [PATCH 51/60] [IRCtrl] rename method IRComputeSampling into ComputeInstrumentsCurvAbs and split method sortCurvAbs into sortCurvAbs and fillInstrumentCurvAbsMap methods --- .../InterventionalRadiologyController.h | 20 ++++- .../InterventionalRadiologyController.inl | 79 ++++++++++--------- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h index 17c97f2eb..9dd6f49c8 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h @@ -138,10 +138,24 @@ class InterventionalRadiologyController : public MechanicalStateController + /// Compute the sambling curv abscisses using each instrument sampling and key points parameters + /// Will call @sa sortCurvAbs to sort the curv abs and remove doubloon + /// + /// + /// + /// + /// + void computeInstrumentsCurvAbs(type::vector& newCurvAbs, const type::vector& tools_xBegin, const Real& totalLength); + + /// Method to sort the curv Abs in the ascending order and avoid doubloon + void sortCurvAbs(type::vector& curvAbs); + + void fillInstrumentCurvAbsMap(const type::vector& curvAbs, const type::vector& tools_xBegin, const type::vector& tools_xEnd, type::vector< type::vector >& id_instrument_table); - void interventionalRadiologyComputeSampling(type::vector &newCurvAbs, type::vector< type::vector > &id_instrument_table, const type::vector &xBegin, const Real& xEnd); - /// Sort the curv Abs in the ascending order and avoid doubloon - void sortCurvAbs(type::vector &CurvAbs, type::vector< type::vector >& id_instrument_table); +public: void totalLengthIsChanging(const type::vector& newNodeCurvAbs, type::vector& modifiedNodeCurvAbs, const type::vector< type::vector >& newTable); void fixFirstNodesWithUntil(unsigned int first_simulated_Node); void activateBeamListForCollision( type::vector &curv_abs, type::vector< type::vector > &id_instrument_table); diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 001f30c03..80beefabc 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -432,11 +432,9 @@ void InterventionalRadiologyController::applyAction(sofa::beamadapter template -void InterventionalRadiologyController::interventionalRadiologyComputeSampling(type::vector &newCurvAbs, - type::vector< type::vector > &idInstrumentTable, - const type::vector &xBegin, - const Real& xend) - +void InterventionalRadiologyController::computeInstrumentsCurvAbs(type::vector &newCurvAbs, + const type::vector& tools_xBegin, + const Real& totalLength) { // Step 1 => put the noticeable Nodes // Step 2 => add the beams given the sampling parameters @@ -446,7 +444,7 @@ void InterventionalRadiologyController::interventionalRadiologyComput { type::vector xP_noticeable_I; type::vector< int > density_I; - m_instrumentsList[i]->getSamplingParameters(xP_noticeable_I, density_I); + m_instrumentsList[i]->getSamplingParameters(xP_noticeable_I, density_I); // sampling of the different section of this instrument // check each interval of noticeable point to see if they go out (>0) and use corresponding density to sample the interval. for (int j=0; j<(int)(xP_noticeable_I.size()-1); j++) @@ -454,13 +452,14 @@ void InterventionalRadiologyController::interventionalRadiologyComput const Real xP = xP_noticeable_I[j]; const Real nxP = xP_noticeable_I[j + 1]; - //compute the corresponding abs curv of this "noticeable point" on the combined intrument - const Real curvAbs_xP = xBegin[i] + xP; - const Real curvAbs_nxP = xBegin[i] + nxP; + //compute the corresponding abs curv of this "noticeable point" on the combined intrument deployed. + const Real curvAbs_xP = tools_xBegin[i] + xP; // xBegin = xend - instrument Total Length + const Real curvAbs_nxP = tools_xBegin[i] + nxP; // In any case, the key points are added as soon as they are deployed - if (curvAbs_xP > 0) + if (curvAbs_xP > 0) { newCurvAbs.push_back(curvAbs_xP); + } // compute interval between next point and previous one (0 for the first iter) const Real curvAbs_interval = (curvAbs_nxP - xSampling); @@ -471,7 +470,7 @@ void InterventionalRadiologyController::interventionalRadiologyComput Real ratio = Real(density_I[j]) / (nxP - xP); int numNewNodes = int(floor(curvAbs_interval * ratio)); // if density == 0, no sampling (numNewNodes == 0) - // Add the new points in reverse order + // Add the new points using reverse order iterator as they are computed deduce to next noticeable point for (int k = numNewNodes; k>0; k--) { auto value = curvAbs_nxP - (k / ratio); @@ -485,9 +484,10 @@ void InterventionalRadiologyController::interventionalRadiologyComput // After the end of the for loop above, we just have to process the // instrument last key point const Real lastxP = xP_noticeable_I[xP_noticeable_I.size()-1]; - const Real curvAbs_lastxP = xBegin[i] + lastxP; - if (curvAbs_lastxP > 0) + const Real curvAbs_lastxP = tools_xBegin[i] + lastxP; + if (curvAbs_lastxP > 0) { newCurvAbs.push_back(curvAbs_lastxP); + } } @@ -504,7 +504,7 @@ void InterventionalRadiologyController::interventionalRadiologyComput { Real abs; abs = *it++; - if (abs::interventionalRadiologyComput } } - sortCurvAbs(newCurvAbs, idInstrumentTable); + sortCurvAbs(newCurvAbs); } @@ -699,32 +699,29 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC /// STEP 1 /// Find the total length of the COMBINED INSTRUMENTS and the one for which xtip > 0 (so the one which are simulated) - Real xend; helper::AdvancedTimer::stepBegin("step1"); Real totalLengthCombined=0.0; - type::vector xbegin; + type::vector tools_xBegin; + type::vector tools_xEnd; for (unsigned int i=0; igetRestTotalLength(); - std::cout << "instru: " << i << " | m_instrumentsList[i]->getRestTotalLength(): " << m_instrumentsList[i]->getRestTotalLength() << std::endl; - xbegin.push_back(xb); - + const Real& xend= d_xTip.getValue()[i]; + tools_xEnd.push_back(xend); + tools_xBegin.push_back(xend - m_instrumentsList[i]->getRestTotalLength()); + if (xend> totalLengthCombined) { - totalLengthCombined=xend; + totalLengthCombined = xend; } - // clear the present interpolation of the beams - m_instrumentsList[i]->clear(); - if( xend > 0.0) { // create the first node (on x=0) newCurvAbs.push_back(0.0); } + + // clear the present interpolation of the beams + m_instrumentsList[i]->clear(); } std::cout << "totalLengthCombined: " << totalLengthCombined << std::endl; @@ -741,6 +738,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC helper::AdvancedTimer::stepEnd("step1"); + computeInstrumentsCurvAbs(newCurvAbs, tools_xBegin, totalLengthCombined); /// STEP 2: @@ -750,7 +748,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC // => xbegin (theoritical curv abs of the beginning point of the instrument (could be negative) xbegin= xtip - intrumentLength) helper::AdvancedTimer::stepBegin("step2"); type::vector> idInstrumentTable; - interventionalRadiologyComputeSampling(newCurvAbs, idInstrumentTable, xbegin, totalLengthCombined); + fillInstrumentCurvAbsMap(newCurvAbs, tools_xBegin, tools_xEnd, idInstrumentTable); helper::AdvancedTimer::stepEnd("step2"); std::cout << "newCurvAbs: " << newCurvAbs << std::endl; @@ -878,8 +876,8 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC Real x1 = newCurvAbs[b+1]; for (unsigned int i=0; i(xmin- threshold) && x0<(xmax+ threshold) && x1>(xmin- threshold) && x1<(xmax+ threshold)) { @@ -986,32 +984,39 @@ void InterventionalRadiologyController::totalLengthIsChanging(const t } } + template -void InterventionalRadiologyController::sortCurvAbs(type::vector &curvAbs, - type::vector >& idInstrumentTable) +void InterventionalRadiologyController::sortCurvAbs(type::vector &curvAbs) { // here we sort CurvAbs std::sort(curvAbs.begin(), curvAbs.end()); - // a threshold is used to remove the values that are "too" close... const auto threshold = d_threshold.getValue(); auto it = std::unique(curvAbs.begin(), curvAbs.end(), [threshold](const Real v1, const Real v2) { return fabs(v1 - v2) < threshold; }); curvAbs.erase(it, curvAbs.end()); +} + +template +void InterventionalRadiologyController::fillInstrumentCurvAbsMap(const type::vector& curvAbs, + const type::vector& tools_xBegin, + const type::vector& tools_xEnd, + type::vector< type::vector >& idInstrumentTable) +{ // here we build a table that provides the list of each instrument for each dof in the list of curvAbs // dofs can be shared by several instruments idInstrumentTable.clear(); idInstrumentTable.resize(curvAbs.size()); - const auto& xTip = d_xTip.getValue(); + const auto threshold = d_threshold.getValue(); for (unsigned int id = 0; id < m_instrumentsList.size(); id++) { // Get instrument absciss range - Real xEnd = xTip[id]; - Real xBegin = xEnd - m_instrumentsList[id]->getRestTotalLength(); + Real xEnd = tools_xEnd[id]; + Real xBegin = tools_xBegin[id]; // enlarge range to ensure to considere borders in absisses comparisons xBegin -= threshold; From 2163599654b76f21c923de1eb7bacc3b99665390 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 12:33:42 +0200 Subject: [PATCH 52/60] [IRCtrl] Update code comments --- .../InterventionalRadiologyController.inl | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 80beefabc..241365f6e 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -697,8 +697,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC unsigned int previousNumControlledNodes = m_numControlledNodes; unsigned int seg_remove = 0; - /// STEP 1 - /// Find the total length of the COMBINED INSTRUMENTS and the one for which xtip > 0 (so the one which are simulated) + // ## STEP 1: Find the total length of the COMBINED INSTRUMENTS and the one for which xtip > 0 (so the one which are simulated) helper::AdvancedTimer::stepBegin("step1"); Real totalLengthCombined=0.0; type::vector tools_xBegin; @@ -738,26 +737,23 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC helper::AdvancedTimer::stepEnd("step1"); - computeInstrumentsCurvAbs(newCurvAbs, tools_xBegin, totalLengthCombined); - - - /// STEP 2: - /// get the noticeable points that need to be simulated - // Fill=> newCurvAbs which provides a vector with curvilinear abscissa of each simulated node - // => id_instrument_table which provides for each simulated node, the id of all instruments which belong this node + // ## STEP 2: Get the noticeable points that need to be simulated + // => Fill newCurvAbs which provides a vector with curvilinear abscissa of each simulated node // => xbegin (theoritical curv abs of the beginning point of the instrument (could be negative) xbegin= xtip - intrumentLength) helper::AdvancedTimer::stepBegin("step2"); type::vector> idInstrumentTable; + computeInstrumentsCurvAbs(newCurvAbs, tools_xBegin, totalLengthCombined); + + // => id_instrument_table which provides for each simulated node, the id of all instruments which belong this node fillInstrumentCurvAbsMap(newCurvAbs, tools_xBegin, tools_xEnd, idInstrumentTable); helper::AdvancedTimer::stepEnd("step2"); std::cout << "newCurvAbs: " << newCurvAbs << std::endl; - /// STEP 3 - /// Re-interpolate the positions and the velocities + // ## STEP 3: Re-interpolate the positions and the velocities helper::AdvancedTimer::stepBegin("step3"); - // Get write access to current nodes/dofs + // => Get write access to current nodes/dofs Data* datax = this->getMechanicalState()->write(core::VecCoordId::position()); auto x = sofa::helper::getWriteOnlyAccessor(*datax); VecCoord xbuf = x.ref(); @@ -767,7 +763,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const Real prev_maxCurvAbs = m_nodeCurvAbs.back(); std::cout << "m_nodeCurvAbs: " << m_nodeCurvAbs << std::endl; - // Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) + // => Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) type::vector modifiedCurvAbs; totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); std::cout << "modifiedCurvAbs: " << modifiedCurvAbs << std::endl; @@ -777,7 +773,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC for (sofa::Index xId = 0; xId < nbrCurvAbs; xId++) { - const sofa::Index globalNodeId = nbrUnactiveNode + xId; + const sofa::Index globalNodeId = nbrUnactiveNode + xId; // fill the end of the dof buffer const Real xCurvAbs = modifiedCurvAbs[xId]; //std::cout << "xCurvAbs - eps: " << (xCurvAbs - std::numeric_limits::epsilon()) << " | prev_maxCurvAbs + threshold: " << prev_maxCurvAbs + threshold << std::endl; @@ -815,7 +811,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC if (fabs(prev_xCurvAbs - xCurvAbs) < threshold) { - x[globalNodeId] = xbuf[prev_globalNodeId]; + x[globalNodeId] = xbuf[prev_globalNodeId]; // xBuf all initialised at start with d_startingPos } else { @@ -853,8 +849,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC helper::AdvancedTimer::stepEnd("step3"); - /// STEP 4 - /// Assign the beams + // ## STEP 4: Assign the beams helper::AdvancedTimer::stepBegin("step4"); sofa::Size nbrBeam = newCurvAbs.size() - 1; // number of simulated beams unsigned int numEdges= m_numControlledNodes-1; @@ -896,16 +891,15 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC } helper::AdvancedTimer::stepEnd("step4"); - /// STEP 5 - /// Fix the not simulated nodes + + // ## STEP 5: Fix the not simulated nodes helper::AdvancedTimer::stepBegin("step5"); unsigned int firstSimulatedNode = m_numControlledNodes - nbrBeam; - //1. Fix the nodes (beginning of the instruments) that are not "out" + // => 1. Fix the nodes (beginning of the instruments) that are not "out" fixFirstNodesWithUntil(firstSimulatedNode); - //2. Fix the node that are "fixed" - // When there are rigid segments, # of dofs is different than # of edges and beams + // => 2. Fix the node that are "fixed". When there are rigid segments, # of dofs is different than # of edges and beams const std::vector< Real > *rigidCurvAbs = &d_rigidCurvAbs.getValue(); bool rigid=false; @@ -942,14 +936,14 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC } } + helper::AdvancedTimer::stepEnd("step5"); - /// STEP 6 - /// Activate Beam List for collision of each instrument + // ## STEP 6: Activate Beam List for collision of each instrument activateBeamListForCollision(newCurvAbs,idInstrumentTable); + // ## STEP 7: Save new computed Data m_nodeCurvAbs = newCurvAbs; m_idInstrumentCurvAbsTable = idInstrumentTable; - helper::AdvancedTimer::stepEnd("step5"); } template From 725e5006aa944593d9bdca6ee568b38b014df262 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 15:49:03 +0200 Subject: [PATCH 53/60] [IRCtrl] Rewrite totalLengthIsChanging --- .../InterventionalRadiologyController.inl | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 241365f6e..9925e32b2 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -752,6 +752,9 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC // ## STEP 3: Re-interpolate the positions and the velocities helper::AdvancedTimer::stepBegin("step3"); + // => Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) + type::vector modifiedCurvAbs; + totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); // => Get write access to current nodes/dofs Data* datax = this->getMechanicalState()->write(core::VecCoordId::position()); @@ -763,10 +766,6 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const Real prev_maxCurvAbs = m_nodeCurvAbs.back(); std::cout << "m_nodeCurvAbs: " << m_nodeCurvAbs << std::endl; - // => Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) - type::vector modifiedCurvAbs; - totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); - std::cout << "modifiedCurvAbs: " << modifiedCurvAbs << std::endl; sofa::Size nbrUnactiveNode = m_numControlledNodes - nbrCurvAbs; // m_numControlledNodes == nbr Dof | nbr of CurvAbs > 0 sofa::Size prev_nbrUnactiveNode = previousNumControlledNodes - prev_nbrCurvAbs; @@ -961,21 +960,18 @@ void InterventionalRadiologyController::totalLengthIsChanging(const t modifiedNodeCurvAbs = newNodeCurvAbs; // we look for the last value in the CurvAbs - if(fabs(dLength) > d_threshold.getValue()) + if (fabs(dLength) < d_threshold.getValue()) + return; + + for (unsigned int i = newTable.size() - 1; i > 0; --i) { - unsigned int i=newTable.size()-1; - while (i>0 && newTable[i].size()==1) + if (newTable[i].size() == 1) { modifiedNodeCurvAbs[i] -= dLength; - - if (modifiedNodeCurvAbs[i] < modifiedNodeCurvAbs[i - 1]) - { - modifiedNodeCurvAbs[i] = modifiedNodeCurvAbs[i - 1]; - } - - i--; } } + + sortCurvAbs(modifiedNodeCurvAbs); } From 623d8e49e0daaab8ef905fca43ac0c128f03f233 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 17:11:43 +0200 Subject: [PATCH 54/60] [IRCtrl] Rewrite totalLengthIsChanging. Not sure sorting is a good thing --- .../component/controller/InterventionalRadiologyController.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 9925e32b2..28b2668e1 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -971,7 +971,7 @@ void InterventionalRadiologyController::totalLengthIsChanging(const t } } - sortCurvAbs(modifiedNodeCurvAbs); + //sortCurvAbs(modifiedNodeCurvAbs); } From 6ca98dd21fc52d1fda0d7a24310e0be4a6d5b6ab Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 17:15:28 +0200 Subject: [PATCH 55/60] [IRCtrl] VArious small cleanup --- .../InterventionalRadiologyController.inl | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 28b2668e1..67b342053 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -690,18 +690,15 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC { const Real& threshold = d_threshold.getValue(); std::cout << "------- applyInterventionalRadiologyController ------" << std::endl; - /// Create vectors with the CurvAbs of the noticiable points and the id of the corresponding instrument + + // Create vectors with the CurvAbs of the noticiable points and the id of the corresponding instrument type::vector newCurvAbs; - - /// In case of drop: - unsigned int previousNumControlledNodes = m_numControlledNodes; - unsigned int seg_remove = 0; + type::vector> idInstrumentTable; // ## STEP 1: Find the total length of the COMBINED INSTRUMENTS and the one for which xtip > 0 (so the one which are simulated) helper::AdvancedTimer::stepBegin("step1"); Real totalLengthCombined=0.0; - type::vector tools_xBegin; - type::vector tools_xEnd; + type::vector tools_xBegin, tools_xEnd; for (unsigned int i=0; i::applyInterventionalRadiologyC m_instrumentsList[i]->clear(); } - std::cout << "totalLengthCombined: " << totalLengthCombined << std::endl; /// Some verif of step 1 // if the totalLength is 0, move the first instrument @@ -741,15 +737,12 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC // => Fill newCurvAbs which provides a vector with curvilinear abscissa of each simulated node // => xbegin (theoritical curv abs of the beginning point of the instrument (could be negative) xbegin= xtip - intrumentLength) helper::AdvancedTimer::stepBegin("step2"); - type::vector> idInstrumentTable; computeInstrumentsCurvAbs(newCurvAbs, tools_xBegin, totalLengthCombined); // => id_instrument_table which provides for each simulated node, the id of all instruments which belong this node fillInstrumentCurvAbsMap(newCurvAbs, tools_xBegin, tools_xEnd, idInstrumentTable); helper::AdvancedTimer::stepEnd("step2"); - std::cout << "newCurvAbs: " << newCurvAbs << std::endl; - // ## STEP 3: Re-interpolate the positions and the velocities helper::AdvancedTimer::stepBegin("step3"); // => Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) @@ -764,18 +757,15 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const sofa::Size nbrCurvAbs = newCurvAbs.size(); // number of simulated nodes const sofa::Size prev_nbrCurvAbs = m_nodeCurvAbs.size(); // previous number of simulated nodes; const Real prev_maxCurvAbs = m_nodeCurvAbs.back(); - std::cout << "m_nodeCurvAbs: " << m_nodeCurvAbs << std::endl; - + sofa::Size nbrUnactiveNode = m_numControlledNodes - nbrCurvAbs; // m_numControlledNodes == nbr Dof | nbr of CurvAbs > 0 - sofa::Size prev_nbrUnactiveNode = previousNumControlledNodes - prev_nbrCurvAbs; + sofa::Size prev_nbrUnactiveNode = m_numControlledNodes - prev_nbrCurvAbs; for (sofa::Index xId = 0; xId < nbrCurvAbs; xId++) { - const sofa::Index globalNodeId = nbrUnactiveNode + xId; // fill the end of the dof buffer + const sofa::Index globalNodeId = nbrUnactiveNode + xId; // position of the curvAbs in the dof buffer filled by the end const Real xCurvAbs = modifiedCurvAbs[xId]; - - //std::cout << "xCurvAbs - eps: " << (xCurvAbs - std::numeric_limits::epsilon()) << " | prev_maxCurvAbs + threshold: " << prev_maxCurvAbs + threshold << std::endl; // 2 cases: TODO : remove first case //1. the abs curv is further than the previous state of the instrument @@ -931,9 +921,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC if(rigid) m_fixedConstraint->addConstraint(firstSimulatedNode+i); } - } - } helper::AdvancedTimer::stepEnd("step5"); @@ -945,6 +933,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC m_idInstrumentCurvAbsTable = idInstrumentTable; } + template void InterventionalRadiologyController::totalLengthIsChanging(const type::vector& newNodeCurvAbs, type::vector& modifiedNodeCurvAbs, From 048c620b985bd4cb3017afb3ece2854b756f5007 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 17:16:08 +0200 Subject: [PATCH 56/60] [IRCtrl] Small fix: avoid adding 0 curvAbs per device deployed --- .../controller/InterventionalRadiologyController.inl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 67b342053..8af25e102 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -710,16 +710,16 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC totalLengthCombined = xend; } - if( xend > 0.0) - { - // create the first node (on x=0) - newCurvAbs.push_back(0.0); - } - // clear the present interpolation of the beams m_instrumentsList[i]->clear(); } + // create the first node (on x=0) + if (totalLengthCombined > 0.0) + { + newCurvAbs.push_back(0.0); + } + /// Some verif of step 1 // if the totalLength is 0, move the first instrument From 7ae05b09caf9e8e4e99c2ab1d15c28827baa9816 Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 17:16:57 +0200 Subject: [PATCH 57/60] [IRCtrl] Small fix: update warning message if number of edges is not enough --- .../controller/InterventionalRadiologyController.inl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 8af25e102..5dae1e079 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -841,15 +841,11 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC // ## STEP 4: Assign the beams helper::AdvancedTimer::stepBegin("step4"); sofa::Size nbrBeam = newCurvAbs.size() - 1; // number of simulated beams - unsigned int numEdges= m_numControlledNodes-1; - - // verify that there is a sufficient number of Edge in the topology : TODO if not, modify topo ! - if (numEdges Date: Thu, 27 Jul 2023 17:19:04 +0200 Subject: [PATCH 58/60] [IRCtrl] Update turn the check of wrong abscisse curv from error to warning. It should not happened anymore with the new version of totalLengthChanged and if happening will use last id of buffer ensuring no crash. --- .../InterventionalRadiologyController.inl | 96 +++++++++---------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 5dae1e079..2ab849e36 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -767,71 +767,63 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const sofa::Index globalNodeId = nbrUnactiveNode + xId; // position of the curvAbs in the dof buffer filled by the end const Real xCurvAbs = modifiedCurvAbs[xId]; - // 2 cases: TODO : remove first case - //1. the abs curv is further than the previous state of the instrument - //2. this is not the case and the node position can be interpolated using previous step positions if ((xCurvAbs - std::numeric_limits::epsilon()) > prev_maxCurvAbs + threshold) { - //std::cout << "xCurvAbs - eps: " << (xCurvAbs - std::numeric_limits::epsilon()) << std::endl; - //std::cout << "prev_maxCurvAbs + threshold: " << prev_maxCurvAbs + threshold << std::endl; - - msg_error() << "Case 1 should never happen ==> avoid using totalLengthIsChanging! xCurvAbs = " << xCurvAbs + msg_warning() << "Case 1 should never happen while using totalLengthIsChanging. xCurvAbs = " << xCurvAbs << " > prev_maxCurvAbs = " << prev_maxCurvAbs << " + threshold: " << threshold << "\n" << "\n | newCurvAbs: " << newCurvAbs << "\n | modifiedCurvAbs: " << modifiedCurvAbs << "\n | previous nodeCurvAbs: " << m_nodeCurvAbs; - // case 1 (the abs curv is further than the previous state of the instrument) - // verifier qu'il s'agit bien d'un instrument qu'on est en train de controller - // interpoler toutes les positions "sorties" de l'instrument en supprimant l'ajout de dx qu'on vient de faire } - else + + // The node position is not further than previous state, it can be interpolated straightfully using previous step positions + sofa::Index prev_xId = 0; + for (prev_xId = 0; prev_xId < m_nodeCurvAbs.size(); prev_xId++) { - // case 2 (the node position can be interpolated straightfully using previous step positions) - sofa::Index prev_xId = 0; - while (prev_xId < m_nodeCurvAbs.size()) // check which prev_curvAbs is above current curvAbs using threshold value - { - if ((m_nodeCurvAbs[prev_xId] + threshold) > xCurvAbs) - break; - prev_xId++; - } + // if old_curvAbs[id] + threshold > current xabs, use this id to interpolate new curvAbs + if ((m_nodeCurvAbs[prev_xId] + threshold) > xCurvAbs) + break; + } - sofa::Index prev_globalNodeId = prev_nbrUnactiveNode + seg_remove + prev_xId; - const Real prev_xCurvAbs = m_nodeCurvAbs[prev_xId]; + sofa::Index prev_globalNodeId = prev_nbrUnactiveNode + prev_xId; + const Real prev_xCurvAbs = m_nodeCurvAbs[prev_xId]; - if (fabs(prev_xCurvAbs - xCurvAbs) < threshold) - { - x[globalNodeId] = xbuf[prev_globalNodeId]; // xBuf all initialised at start with d_startingPos - } + if (fabs(prev_xCurvAbs - xCurvAbs) < threshold) + { + x[globalNodeId] = xbuf[prev_globalNodeId]; // xBuf all initialised at start with d_startingPos + } + else + { + // the node must be interpolated using beam interpolation + //find the instrument + int id = m_idInstrumentCurvAbsTable[prev_xId][0]; + //find the good beam (TODO: do not work if xbegin of one instrument >0) + int b = prev_xId - 1; + + std::cout << xId << " | else interpolation: prev_xId: " << prev_xId << " | id " << id << std::endl; + + // test to avoid wrong indices + if (b < 0) + x[globalNodeId] = d_startingPos.getValue(); else { - // the node must be interpolated using beam interpolation - //find the instrument - int id = m_idInstrumentCurvAbsTable[prev_xId][0]; - //find the good beam (TODO: do not work if xbegin of one instrument >0) - int b = prev_xId - 1; - // test to avoid wrong indices - if (b < 0) - x[globalNodeId] = d_startingPos.getValue(); - else - { - Transform global_H_interpol; - const Real L = prev_xCurvAbs - m_nodeCurvAbs[b]; - Real baryCoef = 1.0; - if (L < std::numeric_limits::epsilon()) { - msg_error() << "Two consecutives curvAbs with the same position. Length is null. Using barycenter coefficient: baryCoef = 1"; - } - else { - baryCoef = (xCurvAbs - m_nodeCurvAbs[b]) / L; - } - - Transform Global_H_local0(xbuf[prev_globalNodeId - 1].getCenter(), xbuf[prev_globalNodeId - 1].getOrientation()); - Transform Global_H_local1(xbuf[prev_globalNodeId].getCenter(), xbuf[prev_globalNodeId].getOrientation()); - - m_instrumentsList[id]->InterpolateTransformUsingSpline(global_H_interpol, baryCoef, Global_H_local0, Global_H_local1, L); - - x[globalNodeId].getCenter() = global_H_interpol.getOrigin(); - x[globalNodeId].getOrientation() = global_H_interpol.getOrientation(); + Transform global_H_interpol; + const Real L = prev_xCurvAbs - m_nodeCurvAbs[b]; + Real baryCoef = 1.0; + if (L < std::numeric_limits::epsilon()) { + msg_error() << "Two consecutives curvAbs with the same position. Length is null. Using barycenter coefficient: baryCoef = 1"; + } + else { + baryCoef = (xCurvAbs - m_nodeCurvAbs[b]) / L; } + + Transform Global_H_local0(xbuf[prev_globalNodeId - 1].getCenter(), xbuf[prev_globalNodeId - 1].getOrientation()); + Transform Global_H_local1(xbuf[prev_globalNodeId].getCenter(), xbuf[prev_globalNodeId].getOrientation()); + + m_instrumentsList[id]->InterpolateTransformUsingSpline(global_H_interpol, baryCoef, Global_H_local0, Global_H_local1, L); + + x[globalNodeId].getCenter() = global_H_interpol.getOrigin(); + x[globalNodeId].getOrientation() = global_H_interpol.getOrientation(); } } } From 50c76b9659aedd4ca17ab32273e8e72de4a260ec Mon Sep 17 00:00:00 2001 From: epernod Date: Thu, 27 Jul 2023 17:36:32 +0200 Subject: [PATCH 59/60] [IRCtrl] Some constifying and cleanup --- .../InterventionalRadiologyController.inl | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 2ab849e36..2eddd290f 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -689,7 +689,7 @@ template void InterventionalRadiologyController::applyInterventionalRadiologyController() { const Real& threshold = d_threshold.getValue(); - std::cout << "------- applyInterventionalRadiologyController ------" << std::endl; + //std::cout << std::endl << std::endl << "------- applyInterventionalRadiologyController ------" << std::endl; // Create vectors with the CurvAbs of the noticiable points and the id of the corresponding instrument type::vector newCurvAbs; @@ -746,8 +746,8 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC // ## STEP 3: Re-interpolate the positions and the velocities helper::AdvancedTimer::stepBegin("step3"); // => Change curv if totalLength has changed: modifiedCurvAbs = newCurvAbs - current motion (Length between new and old tip curvAbs) - type::vector modifiedCurvAbs; - totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); + type::vector modifiedCurvAbs; // This buffer will contain all deployed curvAbs minus current motion to mimic previous curvAbs (with 2 points with nearly the same abs at start) + totalLengthIsChanging(newCurvAbs, modifiedCurvAbs, idInstrumentTable); // => Get write access to current nodes/dofs Data* datax = this->getMechanicalState()->write(core::VecCoordId::position()); @@ -756,21 +756,19 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC const sofa::Size nbrCurvAbs = newCurvAbs.size(); // number of simulated nodes const sofa::Size prev_nbrCurvAbs = m_nodeCurvAbs.size(); // previous number of simulated nodes; - const Real prev_maxCurvAbs = m_nodeCurvAbs.back(); - - sofa::Size nbrUnactiveNode = m_numControlledNodes - nbrCurvAbs; // m_numControlledNodes == nbr Dof | nbr of CurvAbs > 0 - sofa::Size prev_nbrUnactiveNode = m_numControlledNodes - prev_nbrCurvAbs; + const sofa::Size nbrUnactiveNode = m_numControlledNodes - nbrCurvAbs; // m_numControlledNodes == nbr Dof | nbr of CurvAbs > 0 + const sofa::Size prev_nbrUnactiveNode = m_numControlledNodes - prev_nbrCurvAbs; for (sofa::Index xId = 0; xId < nbrCurvAbs; xId++) { const sofa::Index globalNodeId = nbrUnactiveNode + xId; // position of the curvAbs in the dof buffer filled by the end const Real xCurvAbs = modifiedCurvAbs[xId]; - if ((xCurvAbs - std::numeric_limits::epsilon()) > prev_maxCurvAbs + threshold) + if ((xCurvAbs - std::numeric_limits::epsilon()) > m_nodeCurvAbs.back() + threshold) { msg_warning() << "Case 1 should never happen while using totalLengthIsChanging. xCurvAbs = " << xCurvAbs - << " > prev_maxCurvAbs = " << prev_maxCurvAbs << " + threshold: " << threshold << "\n" + << " > m_nodeCurvAbs.back() = " << m_nodeCurvAbs.back() << " + threshold: " << threshold << "\n" << "\n | newCurvAbs: " << newCurvAbs << "\n | modifiedCurvAbs: " << modifiedCurvAbs << "\n | previous nodeCurvAbs: " << m_nodeCurvAbs; @@ -799,9 +797,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC int id = m_idInstrumentCurvAbsTable[prev_xId][0]; //find the good beam (TODO: do not work if xbegin of one instrument >0) int b = prev_xId - 1; - - std::cout << xId << " | else interpolation: prev_xId: " << prev_xId << " | id " << id << std::endl; - + // test to avoid wrong indices if (b < 0) x[globalNodeId] = d_startingPos.getValue(); @@ -842,10 +838,12 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC } + const type::vector& rotInstruments = d_rotationInstrument.getValue(); for (unsigned int b=0; b< nbrBeam; b++) { - Real x0 = newCurvAbs[b]; - Real x1 = newCurvAbs[b+1]; + const Real& x0 = newCurvAbs[b]; + const Real& x1 = newCurvAbs[b+1]; + for (unsigned int i=0; i::applyInterventionalRadiologyC if (x0>(xmin- threshold) && x0<(xmax+ threshold) && x1>(xmin- threshold) && x1<(xmax+ threshold)) { - BaseMeshTopology::EdgeID eID = (BaseMeshTopology::EdgeID)(numEdges- nbrBeam + b ); + BaseMeshTopology::EdgeID eID = (BaseMeshTopology::EdgeID)(numEdges - nbrBeam + b); Real length = x1 - x0; Real x0_local = x0-xmin; Real x1_local = x1-xmin; - Real theta = d_rotationInstrument.getValue()[i]; + Real theta = rotInstruments[i]; m_instrumentsList[i]->addBeam(eID, length, x0_local, x1_local,theta ); - } } } From d4ef9bb0b2d0036cfae1bb63807fd97942a50d68 Mon Sep 17 00:00:00 2001 From: epernod Date: Fri, 28 Jul 2023 10:08:09 +0200 Subject: [PATCH 60/60] [IRCtrl] Update doc and rename method --- .../InterventionalRadiologyController.h | 17 +++++++---------- .../InterventionalRadiologyController.inl | 4 ++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h index 9dd6f49c8..eec80be5d 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.h +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.h @@ -140,20 +140,17 @@ class InterventionalRadiologyController : public MechanicalStateController - /// Compute the sambling curv abscisses using each instrument sampling and key points parameters - /// Will call @sa sortCurvAbs to sort the curv abs and remove doubloon - /// - /// - /// - /// - /// + /** Compute the sambling curv abscisses using each instrument sampling and key points parameters + * Will call @sa sortCurvAbs to sort the curv abs and remove doubloon + * Need each tool starting position to sample only activated nodes and tool total length (combined deployed tool lengths) + **/ void computeInstrumentsCurvAbs(type::vector& newCurvAbs, const type::vector& tools_xBegin, const Real& totalLength); - /// Method to sort the curv Abs in the ascending order and avoid doubloon + /// Method to sort the curv Abs in the ascending order and remove doubloon that are closer than d_threshold void sortCurvAbs(type::vector& curvAbs); - void fillInstrumentCurvAbsMap(const type::vector& curvAbs, const type::vector& tools_xBegin, const type::vector& tools_xEnd, type::vector< type::vector >& id_instrument_table); + /// Method to fill the id_instrument_table based on curvAbs and each tool begin and end. The table as the same size as the curvAbs buffer and store for each curvAbs[i] a vector with the ids of the instruments that are present at this position. + void fillInstrumentCurvAbsTable(const type::vector& curvAbs, const type::vector& tools_xBegin, const type::vector& tools_xEnd, type::vector< type::vector >& id_instrument_table); public: void totalLengthIsChanging(const type::vector& newNodeCurvAbs, type::vector& modifiedNodeCurvAbs, const type::vector< type::vector >& newTable); diff --git a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl index 2eddd290f..7fc76f012 100644 --- a/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl +++ b/src/BeamAdapter/component/controller/InterventionalRadiologyController.inl @@ -740,7 +740,7 @@ void InterventionalRadiologyController::applyInterventionalRadiologyC computeInstrumentsCurvAbs(newCurvAbs, tools_xBegin, totalLengthCombined); // => id_instrument_table which provides for each simulated node, the id of all instruments which belong this node - fillInstrumentCurvAbsMap(newCurvAbs, tools_xBegin, tools_xEnd, idInstrumentTable); + fillInstrumentCurvAbsTable(newCurvAbs, tools_xBegin, tools_xEnd, idInstrumentTable); helper::AdvancedTimer::stepEnd("step2"); // ## STEP 3: Re-interpolate the positions and the velocities @@ -965,7 +965,7 @@ void InterventionalRadiologyController::sortCurvAbs(type::vector -void InterventionalRadiologyController::fillInstrumentCurvAbsMap(const type::vector& curvAbs, +void InterventionalRadiologyController::fillInstrumentCurvAbsTable(const type::vector& curvAbs, const type::vector& tools_xBegin, const type::vector& tools_xEnd, type::vector< type::vector >& idInstrumentTable)