Home › Forum › SOFA › Programming with SOFA › [SOLVED] usage of BaseData and SingleLink
Tagged: 64_bits, Linux_ubuntu, SOFA_1608
- This topic has 5 replies, 2 voices, and was last updated 7 years, 5 months ago by Noura.
-
AuthorPosts
-
28 May 2017 at 23:55 #9195NouraBlocked
Hi all,
According to my understanding, in order to access some data in sofa scene from C++ code, data or links should be initialized.
Having one’s own component, this initialization could be placed in the constructor (see code pls.)
My question is: Could you give more explanation when initData should be used and when initLink?
For now, I usesofa::core::objectmodel::Data<BaseData>
to access “base data” types like bool,int,float,vec as listed in the documentation webpage
while i use linkssofa::core::objectmodel::SingleLink<TOwnerType,TDestType,TFlags&~BaseLink::FLAG_MULTILINK>
in more complex types like loaders, oglModels, etc. Is this correct?Now I need to access a “sofa::helper::io::Mesh” object, should I use a link for that?
If it is true, could anyone have a look at this piece of code where I declared a link to a mesh but I got a compilation error (see error below)!Here is a minimal code example:
class MyComponent : public BaseController { public: SOFA_CLASS(MyComponent, BaseController); typedef sofa::component::visualmodel::OglModel TOGLModel; typedef sofa::helper::io::Mesh TMesh; typedef sofa::core::objectmodel::SingleLink< MyComponent, TOGLModel, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> OGLLink; //works typedef sofa::core::objectmodel::SingleLink< MyComponent, TMesh, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> MeshLink; //compiles fine OGLLink m_ogl_link; //MeshLink m_mesh_link; //Compilation error! protected: sofa::core::objectmodel::Data<int> m_stiffness; } MyComponent<DataTypes>::MyComponent(): m_ogl_link(initLink("ogl_link", "desc. of the link")), /* m_mesh_link(initLink("mesh_link", "desc. of the link")), compilation error */ m_stiffness(initData(&m_stiffness, 1, "stiffness", "desc. of the link")) { ... }
Here is a the node where I use the above mentioned links
<Node name="Lunatum" activated="1"> <MeshSTLLoader name="loader" filename="Lunatum.stl" dx="9,425276" dy="-36,149002" dz="4,296117" rx="0" ry="5" rz="0"/> <Mesh src="@loader"/> <MechanicalObject src="@loader" /> <OglModel name="Visual" fileMesh="Lunatum.stl" color="blue" /> <MyComponent stiffness = "x" ogl_link="@Visual" listening="1" /> <!-- <MyComponent stiffness = "x" mesh_link="@loader" ogl_link="@Visual" listening="1" /> --> </Node>
the compilation error is:
`
error: no type named ‘SPtr’ in ‘class sofa::helper::io::Mesh’ typedef typename TDestType::SPtr T;
error: using invalid field ‘sofa::core::objectmodel::SingleLink<TOwnerType, TDestType, TFlags>::m_validator’: m_validator(NULL)
error: ‘GetClass’ is not a member of ‘sofa::core::objectmodel::TLink<sofa::core::behavior::MyComponent<int>, sofa::helper::io::Mesh, 34u>::DestType {aka sofa::helper::io::Mesh}’ return DestType::GetClass();
error: no matching function for call to ‘sofa::core::objectmodel::LinkTraitsPtrCasts<sofa::helper::io::Mesh>::getBase(sofa::core::objectmodel::TLink<sofa::core::behavior::MyComponent<int>, sofa::helper::io::Mesh, 34u>::DestType*)’return TraitsDestCasts::getBase(getIndex(index));
`
It seems to me that there is mismatching in the destination type “TDestType” which is typedef sofa::helper::io::Mesh TMesh in my code. Could it be some “target_link_libraries” missing in my CMakeLists?Thanks,
Noura
29 May 2017 at 00:20 #9196NouraBlockedHere are other connected questions, I put them in the same thread, but in a separate post for the sake of clarity.
I have some wrong behaviour when getting values using links, the problem is illustrated in the following minimal example, and the questions are listed as comments inside the code:class MyComponent : public BaseController { public: SOFA_CLASS(MyComponent, BaseController); typedef sofa::core::loader::MeshLoader TMeshSTLLoader; typedef sofa::component::visualmodel::OglModel TOGLModel; typedef sofa::helper::io::Mesh TMesh; typedef sofa::core::objectmodel::SingleLink< MyComponent, TMeshSTLLoader, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> STLLink; typedef sofa::core::objectmodel::SingleLink< MyComponent, TOGLModel, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> OGLLink; typedef sofa::core::objectmodel::SingleLink< MyComponent, TMesh, BaseLink::FLAG_STOREPATH|BaseLink::FLAG_STRONGLINK> MeshLink; OGLLink m_ogl_link; STLLink m_stl_link; //MeshLink m_mesh_link; } MyComponent<DataTypes>::MyComponent(): m_stl_link(initLink("stl_link", "desc. of the link")), m_ogl_link(initLink("ogl_link", "desc. of the link")) /* m_mesh_link(initLink("mesh_link", "desc. of the link")) */ { ... } template<class DataTypes> void MyComponent<DataTypes>::updateOnBeginStep(){ if(!m_stl_link.get()) { std::cout << "Error getting link" << std::endl; return; } TMeshSTLLoader* ldr = m_stl_link.get(); ldr->load(); sofa::helper::vector < sofa::defaulttype::Vec< 3, SReal > > my_vertices; my_vertices = ldr->d_positions.getValue(); // First question concerning the size of the vertices // I noticed that the my_vertices size increases by x(the initial size of the positions in the stl loader) at each updateOnBeginStep. // Should I establish the link to the mesh instead of the the stlLoader? this brings me back to my first post std::cout<<"number of vertices: "<<my_vertices<<std::endl; // Second question concerning the translation value Data<Vector3> myVec; myVec=ldr->getTranslation(); std::cout<<myVec.getValue()[0]<<", "<<myVec.getValue()[1]<<", "<<myVec.getValue()[2]<<std::endl; // I was expecting to get the values dx="9,425276" dy="-36,149002" dz="4,296117" as they are set in the scene, but I get 0 0 0. Did I missed something? // Third question concerning the visual model if(!m_ogl_link.get()) { std::cout << "Error getting link" << std::endl; return; } TOGLModel* ogl = m_ogl_link.get(); ldr->applyTranslation(1,0.0,0.0); ogl->applyTranslation(1,0.0,0.0); // Is there another way to make the oglModel updates automatically with the corresponding mesh. }
Again the scene node:
<Node name="Lunatum" activated="1"> <MeshSTLLoader name="loader" filename="Lunatum.stl" dx="9,425276" dy="-36,149002" dz="4,296117" rx="0" ry="5" rz="0"/> <Mesh src="@loader"/> <MechanicalObject src="@loader" /> <OglModel name="Visual" fileMesh="Lunatum.stl" color="blue" /> <MyComponent ogl_link="@Visual" stl_link="@loader" listening="1" /> </Node>
Thanks,
Noura
30 May 2017 at 10:36 #9208jnbrunetModeratorHey Noura,
I believe that in order to be used by a linked relationship, the object linked must inherit the
Base
class, which isn’t the case with asofa::helper::io::Mesh
.Also, note that in your scene node, you do not have any
sofa::helper::io::Mesh
. You do have asofa::component::loader::MeshSTLLoader
which is named “loader” and asofa::component::topology::MeshTopology
represented by the alias “Mesh” (the Mesh node).The “mesh_link” attribute of your component should be linked to the
sofa::component::topology::MeshTopology
, a.k.a “Mesh” node.Now, for the SingleLinked vs Data question, I could not explicitly tell you all differences between those 2 types as I really doesn’t know them very much, but I guess Link types can resolved automatically a “Node” by a given path (“@../the/node”), for which you would need to do manually with a Data type. I may be wrong, but I think Link type can also resolve a Node’s attribute by a given path (“@../the/node.attribute”) There is also some sort of Master – Slave relationship with linked types, so maybe there is a critical path of the order of initialisation between the scene nodes. And there may also be some sort of sync between those linked attributes.
But as I said, those are all guesses. Maybe someone with more knowledge of the Link types could shed some light on what exactly a linked attribute or node can offer us.
Hope that helped.
Jean-Nico30 May 2017 at 17:42 #9235NouraBlockedHi Jean-Nico,
Yes, your explanation helped me a lot. Thank you!
1- The remark concerning the
sofa::component::topology::MeshTopology
was on point! I mistaked the type of the “Mesh” component in the scene. I linked the “mesh_link” attribute to asofa::component::topology::MeshTopology
and it works fine.2- Concerning your remark that the linked object must inherit the
Base
class, I’m not quite sure about this because both theOGLLink
andSTLLink
in the above code do not, and they are working fine.Looking at the
SingleLink
classclass SingleLink : public TLink<TOwnerType,TDestType,TFlags&~BaseLink::FLAG_MULTILINK>
where
template<class TOwnerType, class TDestType, unsigned TFlags> class TLink : public BaseLink
It isn’t clear enough to me which types
TDestType
is destinated to. But no problem! I did what I need using the link to the MeshTopology.Before marking the topic as resolved, I would ask for some hints concerning the odd size values of the d_positions in my second post.
I’ll summarize the problem again:
The “Lunatum.stl” mesh file contains 1732 points.
It is the same value which I obtain using the “mesh_link” when calling thegetNbPoints()
However, after the following code
TMeshSTLLoader* ldr = m_stl_link.get(); ldr->load(); sofa::helper::vector < sofa::defaulttype::Vec< 3, SReal > > my_vertices; my_vertices = ldr->d_positions.getValue(); std::cout<<"number of vertices: "<<my_vertices<<std::endl;
I’m expecting that size of my_vertices should be equal the vertices number in the file loaded using the STLLoader(which is 1732) Right?
But, at the first simulation step the size of my_vertices is equal to 3464 which is (1732+1732)
at the second step the the size becomes 5196 which is (3464+1732)
then 6928 ( 5196+1732) and so on …I should have missed some reinitializing for example? Any idea?
Thanks,
Noura
30 May 2017 at 18:32 #9236jnbrunetModeratorHey Noura,
Is there a reason why you call the
MeshSTLLoader::load
function on each call toupdateOnBeginStep
?Looking at the
MeshSTLLoader::load
function, we can see that the vertices, normals and triangles are appended at the end of the internal data container. That means that each time you call theload
function, it re-parse your entire mesh file from your disk and append the same data to the end of your already loaded data vector from the last step! This is why each time you call it, your container’s size become larger (by duplicating the data of your mesh file at the end).Parsing the entire mesh file from your disk is extremely slow, if you need to take into account changes in the mesh, maybe you could try to find a way that doesn’t involve disk I/O operations.
As for the
TDestType
template of the Link class, it really should inherits the Base class. TheMeshSTLLoader
andOglModel
inheritance looks like this:MeshSTLLoader -> MeshLoader -> BaseLoader -> BaseObject -> Base OglModel -> VisualModelImpl-> VisualModel -> BaseObject -> Base
They actually need to inherit BaseObject in order to represent a scene object (node).
For your second question concerning the translation, could you try without passing by a Data object? Something like this:
Vector3 myVec = ldr->getTranslation();
For your third question, I’m not quite sure what you want to do. Normally you would fill a mechanical state with your mesh positions, and do a rigid mapping between the mechanical state (which contains the updated positions at each time step) and your visual state (OglModel).
Keep us updated on your progress!
Jean-Nico30 May 2017 at 22:54 #9238NouraBlockedExactly! the simulation will be slow and saturates after a while, this is why I worried about the increasing memory size. I placed the
load
function in the constructor and now it keeps the correct positions size ( My error was because I thought that since the ldr is declared at every simulation step, the positions should not be appended).As for the
TDestType
, I agree it must inherit the base class 😉Concerning the translation, still not correct, but I’ll manage to find out the reason.
Finally, the
OglModel
, now it is working fine. There was an error in the mapping I used which prevented it from updating correctly according to the correspondent mesh. This is why I was trying to reproduce the same positions change. Now, the behaviour is as it should be.Thanks again Jean-Nico!
Noura
-
AuthorPosts
- You must be logged in to reply to this topic.