Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
-
Ibraheem Al-Dhamari
- Posts: 35
- Joined: Thu Mar 16, 2017 2:44 am
Post
by Ibraheem Al-Dhamari » Sun Mar 15, 2020 11:41 am
Dear all,
I am trying to add an xml node to the model .osim file similar to this
viewtopicPhpbb.php?f=91&t=11447&p=31986&start=0&view=
. RapidXML introduced NULL characters to the .osim file in windowa
. I decided to try the built-in opensim XMLDocument class but I could not iterate over the model correctly and I could not find a clear example of how to do this. Here is my try
Code: Select all
#include "SimTKcommon/internal/Xml.h"
//read model file from a string variable
XMLDocument doc(inputFilePath);
SimTK::Xml::Element myModelNode, myCurrentNode;
SimTK::Xml::Attribute nodeAtt;
myModelNode = doc.getRootDataElement();
// this gives only the first body and stops
SimTK::Xml::element_iterator nodeItr1 = myModelNode.element_begin("BodySet");
nodeItr1 = nodeItr1->element_begin();
while (nodeItr1 != myModelNode.element_end()) {
myCurrentNode = nodeItr1->getRequiredElement("Body");
nodeAtt = myCurrentNode.getRequiredAttribute("name");
std::cout << "BodyName : " << nodeAtt.getValue() << std::endl;
nodeItr1++;
}
Tags:
-
Ibraheem Al-Dhamari
- Posts: 35
- Joined: Thu Mar 16, 2017 2:44 am
Post
by Ibraheem Al-Dhamari » Tue Mar 17, 2020 12:12 pm
I couldn't find a function for this so I wrote this function:
Code: Select all
SimTK::Xml::Element findNode(SimTK::Xml::Element rootNd, std::string nodeName) {
SimTK::Xml::node_iterator pnI;
SimTK::Xml::Element cEl;
pnI = rootNd.element_begin();
int j = 0;
while ( (pnI != rootNd.element_end()) ) {
cEl = pnI->getParentElement().getAllElements()[j];
if (noName == cEl.getNodeText()) {
cout << cEl.getNodeText() << " " << cEl.getRequiredAttribute("name").getValue() << endl;
}else
cEl = findNode(cEl, nodeName);
pnI++; j++;
}//while1
return cEl;
}
then in the main function we can find all the bodies using
Code: Select all
SimTK::Xml::Document doc(modelPath); // read model from some path variable
SimTK::Xml::Element rootNd, bodyNd;
rootNd = doc.getRootElement(); // get the root node
bodyNd= findNode(rootNd, "Body");
-
Thomas Uchida
- Posts: 1793
- Joined: Wed May 16, 2012 11:40 am
Post
by Thomas Uchida » Tue Mar 17, 2020 12:45 pm
What is it you are trying to do with this code (find a Body in a Model, add a Body, etc.)? Is it possible to use the OpenSim API rather than stepping through the XML?
-
Ibraheem Al-Dhamari
- Posts: 35
- Joined: Thu Mar 16, 2017 2:44 am
Post
by Ibraheem Al-Dhamari » Wed Mar 18, 2020 3:16 am
As I mentioned, I ma trying to add a pluginforce to the model in the cpp code as in
viewtopicPhpbb.php?f=91&t=11447&p=31986&start=0&view=
I already did this using rapidXML library but there was an error in windows. Now I am using the SimTK:::Xml class so no need to use external library.
The code I post here is just an example how to iterate over all bodies.
Here is how I added the plugin force:
Code: Select all
SimTK::Xml::Element GlobalForceSetEl;
SimTK::Xml::Element findNode(SimTK::Xml::Element rootNd, std::string nodName) {
SimTK::Xml::node_iterator pnI;
SimTK::Xml::Element cEl;
pnI = rootNd.element_begin();
int j = 0; int Stp = 0;
while ( pnI != rootNd.element_end() ) {
cEl = pnI->getParentElement().getAllElements()[j];
if (nodName == cEl.getNodeText()) {
GlobalForceSetEl = cEl;
break;
}else
cEl = findNode(cEl, nodName);
pnI++; j++;
}//while1
return cEl;
}
void addForcePlugin(SimTK::Xml::Element forceNode, std::string modelPath) {
try {
SimTK::Xml::Document modelDoc(modelPath);
SimTK::Xml::Element rootNd = modelDoc.getRootElement();
cout << " model file is oppened: " <<modelPath<< endl;
try {
SimTK::Xml::Element ForceSetElem = findNode(rootNd, "ForceSet");
cout << " ForceSet is found ......." << endl;
SimTK::Xml::Element ObjectsElem = GlobalForceSetEl.getAllElements()[0];
cout << "ok" << endl;
cout << ObjectsElem.getNodeText() << endl;
ObjectsElem.appendNode(forceNode);
}
catch (Exception ee) {
cout << " ForceSet Not found ......." << endl;
SimTK::Xml::Element ForceSetElem("ForceSet");
ForceSetElem.setAttributeValue("name", "ForceSet");
SimTK::Xml::Element ObjectsElem("Objects");
ForceSetElem.appendNode(ObjectsElem);
ObjectsElem.appendNode(forceNode);
}
modelDoc.writeToFile(modelPath);
cout << " Plug-in force is added ......." << endl;
}
catch(Exception e){
cout << " ERROR: plug-in force is not added ......"<< endl;
}
in the main function:
1. we create the plugin force XML:
Code: Select all
SimTK::Xml::Element nElem("somePluginForce"); nElem.setAttributeValue("name", "myPluginForce");
std::string modelPath = "somePath/myModel.osim";
SimTK::Xml::Element par1("par1"); par1.setValue(to_string(par1)); nElem.appendNode(par1);
SimTK::Xml::Element par1("par2"); par1.setValue(to_string(par2)); nElem.appendNode(par2);
2. after printing the model we call the addForcePlugin function:
Code: Select all
osimModel.print(modelPath);
addForcePlugin(nElem, modelPath);