20 June 2019 at 18 h 08 min #13837
I’m trying to export the deformation gradients at some integration points, using the Flexible plugin, inside a component in C++.
Here are the interesting parts of the python scene, ie the dofs node “Meca” and its child “behavior”, defining the deformation gradients mapping.
# rootNode Meca.createObject('MechanicalObject', template='Vec3d') Meca.createObject("BarycentricShapeFunction") # Meca/behavior behavior = Meca.createChild('behavior') behavior.createObject('TopologyGaussPointSampler') behavior.createObject('MechanicalObject', template='F331') behavior.createObject('MLSMapping', template='Vec3d,F331') behavior.createObject("DataExporter")
What I want to do is use the Mechanical object of node behavior to extract the gradient matrix F. Here is the problematic part of the C++ code of my component “DataExporter” :
#include "Flexible/types/DeformationGradientTypes.h" typedef defaulttype::DefGradientTypes<3,3,1,Real> F331; typedef helper::vector<F331::Deriv> VDeriv; core::State<F331>* state;// Non-mechanical state vectors this->getContext()->get(state);// Proper way to do it ? // state->getSize() crashes at runtime // Then in a loop : helper::ReadAccessor<Data<VDeriv>> vf(state->read(core::ConstVecCoordId::position())); F331::Frame F = vf.getF();
In know that for a topology or MechanicalObject, the get method is appropriate but in this case it doesn’t seem to work, the program crashes at runtime.
Could you help me understanding the process of reaching other components in a python scene ?
Thank you in advance,
Gaetan21 June 2019 at 19 h 17 min #13843HugoKeymaster
- SOFA Consortium
Before anything, I apologize I am no expert from the Flexible plugin.
If I understand correctly you are using Flexible, in a scene written in python. Is that correct?
Is the gradient matrix directly computed from a Flexible component? or do you want to compute it yourself from the position, rest_position and topology information?
Hugo23 June 2019 at 19 h 59 min #13844
Hi Hugo, thank you for your answer. I don’t think my problem is specific to Flexible since I’m trying to get the state vector of a MechanicalObject. That’s right the scene is written in Python, I can post the full scene Tuesday but the main components are in my previous message. I will try to explain a bit more :
The node I called Meca contains the state vector of the positions (type vec3d) with the associated shape functions.
The MechanicalObject of the child node behavior contains the state vector for the deformation gradients under the form of a 3×3 matrix (type F331 coded in the Flexible plugin). The values of the deformation gradients are computed by the MLSMapping at points defined by the TopologyGaussPointSampler.
My component “DataExporter” exports, for each integration point, the 9 values of the gradient matrix stored in the state vector (with the getF() method).
My problem, if I well understood, is to get a pointer toward the MechanicalObject within the node of my component. I didn’t quite understand the difference between the following types and when I should use one of them :
sofa::component::container::MechanicalObject<TYPE>* mecaState; sofa::core::behavior::BaseMechanicalState* mecaState; sofa::core::State<TYPE>* mecaState;
When I have defined mecaState, should I use the get method as following ?
Then I think I will be able to retrieve the state vectors with a ReadAccessor and the read method.
If you need the full python/c++ code I can post them as well.
Gaëtan28 June 2019 at 12 h 17 min #13866HugoKeymaster
- SOFA Consortium
I think I better understood, the question is how to correctly access the fields of a MechanicalObject in C++. Your approach using
Just a remark: this means that your exporter will implicitely browse its node and look for a MechanicalObject. In SOFA, we are now advising to rather use explicit Links (see and example in NearestPointROI). In your case, feel free to use the getContext() approach.
Let me know you struggle to access the ‘position’ field of your MechanicalObject.
Hugo1 July 2019 at 10 h 23 min #13870
Thanks I will try the explicit links. For the moment, changing the state from MechanicalObject to MechanicalState seems to solve my problem, here is the sample code in case somebody needs it :
#include "Flexible/types/DeformationGradientTypes.h" #include <sofa/core/behavior/BaseMechanicalState.h> typedef defaulttype::F331Types F331; sofa::core::behavior::MechanicalState<F331>* _state; // SingleLink<DataExporter, core::behavior::MechanicalState<F331>, BaseLink::FLAG_STRONGLINK> _state; this->getContext()->get(_state); // Then in a loop : helper::ReadAccessor<Data<F331::VecCoord>> vf(state->read(core::ConstVecCoordId::position())); F331::Frame F = vf.getF();
- You must be logged in to reply to this topic.