// Handle conversion from older format void VisibleObject::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { SimTK::Array_<SimTK::String> oldGeometryFiles; if ( versionNumber < XMLDocument::getLatestVersion()){ if (versionNumber<20101){ SimTK::Xml::element_iterator visPropIter = aNode.element_begin("VisibleProperties"); // Get geometry files and Preferences if any and set them into if (visPropIter!=aNode.element_end()){ // Move display_prference, and show_axes nodes up to VisibleObject SimTK::Xml::element_iterator prefIter = visPropIter->element_begin("display_preference"); if (prefIter!= visPropIter->element_end()){ SimTK::Xml::Node moveNode = visPropIter->removeNode(prefIter); aNode.insertNodeAfter(aNode.element_end(), moveNode); } SimTK::Xml::element_iterator showAxesIter = visPropIter->element_begin("show_axes"); if (showAxesIter!=aNode.element_end()){ SimTK::Xml::Node moveNode = visPropIter->removeNode(showAxesIter); aNode.insertNodeAfter(aNode.element_end(), moveNode); } } SimTK::Xml::element_iterator geometryIter = aNode.element_begin("geometry_files"); string propValue=""; bool hasPieces=false; if (geometryIter!= aNode.element_end()){ geometryIter->getValueAs(oldGeometryFiles); } } } Object::updateFromXMLNode(aNode, versionNumber); if (oldGeometryFiles.size()>0){ for(unsigned i=0; i< oldGeometryFiles.size(); i++) setGeometryFileName(i, oldGeometryFiles[i]); } }
/*virtual*/ void Marker::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { if (versionNumber < XMLDocument::getLatestVersion()){ if (versionNumber < 30501) { // Parse name of Body under <body>node SimTK::Xml::element_iterator bIter = aNode.element_begin("body"); SimTK::String bName = bIter->getValue(); // Create nodes for new layout SimTK::Xml::Element connectorsElement("connectors"); SimTK::Xml::Element frameElement("Connector_PhysicalFrame_"); connectorsElement.insertNodeAfter(connectorsElement.node_end(), frameElement); frameElement.setAttributeValue("name", "parent_frame"); SimTK::Xml::Element connecteeElement("connectee_name"); // Markers in pre-4.0 models are necessarily 1 level deep // (model, markers), and Bodies were necessarily 1 level deep; // here we create the correct relative path (accounting for sets // being components). bName = XMLDocument::updateConnecteePath30517("bodyset", bName); connecteeElement.setValue(bName); frameElement.insertNodeAfter(frameElement.node_end(), connecteeElement); aNode.insertNodeAfter(bIter, connectorsElement); aNode.eraseNode(bIter); } } // Call base class now assuming _node has been corrected for current version Super::updateFromXMLNode(aNode, versionNumber); }
void Body::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { if (versionNumber < XMLDocument::getLatestVersion()) { if (versionNumber < 30500) { SimTK::Vec6 newInertia(1.0, 1.0, 1.0, 0., 0., 0.); std::string inertiaComponents[] = { "inertia_xx", "inertia_yy", "inertia_zz", "inertia_xy", "inertia_xz", "inertia_yz" }; for (int i = 0; i < 6; ++i) { SimTK::Xml::element_iterator iIter = aNode.element_begin(inertiaComponents[i]); if (iIter != aNode.element_end()) { newInertia[i] = iIter->getValueAs<double>(); aNode.removeNode(iIter); } } std::ostringstream strs; for (int i = 0; i < 6; ++i) { strs << newInertia[i]; if (i < 5) strs << " "; } std::string strInertia = strs.str(); SimTK::Xml::Element inertiaNode("inertia", strInertia); aNode.insertNodeAfter(aNode.element_end(), inertiaNode); } } Super::updateFromXMLNode(aNode, versionNumber); }
void XMLDocument::writeDefaultObjects(SimTK::Xml::Element& elmt) { if (_defaultObjects.getSize()==0) return; // Make node for "defaults" SimTK::Xml::Element defaultsElement("defaults"); elmt.insertNodeAfter(elmt.node_end(), defaultsElement); for(int i=0; i < _defaultObjects.getSize(); i++){ _defaultObjects.get(i)->updateXMLNode(defaultsElement); } }
//_____________________________________________________________________________ // Override default implementation by object to intercept and fix the XML node // underneath the model to match current version. void Muscle::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { if ( versionNumber < XMLDocument::getLatestVersion()) { if (Object::getDebugLevel()>=1) cout << "Updating Muscle object to latest format..." << endl; if (versionNumber <= 20301){ SimTK::Xml::element_iterator pathIter = aNode.element_begin("GeometryPath"); if (pathIter != aNode.element_end()) { XMLDocument::renameChildNode(*pathIter, "MusclePointSet", "PathPointSet"); XMLDocument::renameChildNode(*pathIter, "MuscleWrapSet", "PathWrapSet"); } else { // There was no GeometryPath, just MusclePointSet SimTK::Xml::element_iterator musclePointSetIter = aNode.element_begin("MusclePointSet"); bool pathPointSetFound=false; if (musclePointSetIter != aNode.element_end()){ XMLDocument::renameChildNode(aNode, "MusclePointSet", "PathPointSet"); pathPointSetFound=true; } bool pathWrapSetFound=false; SimTK::Xml::element_iterator muscleWrapSetIter = aNode.element_begin("MuscleWrapSet"); if (muscleWrapSetIter != aNode.element_end()){ XMLDocument::renameChildNode(aNode, "MuscleWrapSet", "PathWrapSet"); pathWrapSetFound=true; } // Now create a "GeometryPath" node and move MusclePointSet & MuscleWrapSet under it SimTK::Xml::Element myPathElement("GeometryPath"); SimTK::Xml::Node moveNode; if (pathPointSetFound) { SimTK::Xml::element_iterator pathPointSetIter = aNode.element_begin("PathPointSet"); moveNode = aNode.removeNode(pathPointSetIter); myPathElement.insertNodeAfter(myPathElement.element_end(),moveNode); } if (pathWrapSetFound) { SimTK::Xml::element_iterator pathWrapSetIter = aNode.element_begin("PathWrapSet"); moveNode = aNode.removeNode(pathWrapSetIter); myPathElement.insertNodeAfter(myPathElement.element_end(),moveNode); } aNode.insertNodeAfter(aNode.element_end(), myPathElement); } XMLDocument::renameChildNode(aNode, "pennation_angle", "pennation_angle_at_optimal"); } } // Call base class now assuming aNode has been corrected for current version Super::updateFromXMLNode(aNode, versionNumber); }
/*virtual*/ void Marker::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { if (versionNumber < XMLDocument::getLatestVersion()){ if (versionNumber < 30501) { // Parse name of Body under <body>node SimTK::Xml::element_iterator bIter = aNode.element_begin("body"); SimTK::String bName = bIter->getValue(); // Create nodes for new layout SimTK::Xml::Element connectorsElement("connectors"); SimTK::Xml::Element frameElement("Connector_PhysicalFrame_"); connectorsElement.insertNodeAfter(connectorsElement.node_end(), frameElement); frameElement.setAttributeValue("name", "reference_frame"); SimTK::Xml::Element connecteeElement("connectee_name"); connecteeElement.setValue(bName); frameElement.insertNodeAfter(frameElement.node_end(), connecteeElement); aNode.insertNodeAfter(bIter, connectorsElement); aNode.eraseNode(bIter); } } // Call base class now assuming _node has been corrected for current version Object::updateFromXMLNode(aNode, versionNumber); }
void Joint::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { int documentVersion = versionNumber; //bool converting = false; if (documentVersion < XMLDocument::getLatestVersion()){ if (documentVersion<30500){ XMLDocument::renameChildNode(aNode, "location", "location_in_child"); XMLDocument::renameChildNode(aNode, "orientation", "orientation_in_child"); } // Version 30501 converted Connector_Body_ to Connector_PhysicalFrame_ if (documentVersion < 30501) { // Handle any models that have the Joint connecting to Bodies instead // of PhyscialFrames XMLDocument::renameChildNode(aNode, "Connector_Body_", "Connector_PhysicalFrame_"); } // Version 30505 changed "parent_body" connector name to "parent_frame" // Convert location and orientation into PhysicalOffsetFrames owned by the Joint if (documentVersion < 30505) { // Elements for the parent and child names the joint connects SimTK::Xml::element_iterator parentNameElt; SimTK::Xml::element_iterator childNameElt; // The names of the two PhysicalFrames this joint connects std::string parentFrameName(""); std::string childFrameName(""); SimTK::Xml::element_iterator connectors_node = aNode.element_begin("connectors"); SimTK::Xml::element_iterator connectorElement = connectors_node->element_begin("Connector_PhysicalFrame_"); while (connectorElement != aNode.element_end()) { // If connector name is "parent_body" rename it to "parent_frame" if (connectorElement->getRequiredAttributeValue("name") == "parent_body") { connectorElement->setAttributeValue("name", "parent_frame"); } // If connector name is "parent_frame" get the name of the connectee if (connectorElement->getRequiredAttributeValue("name") == "parent_frame"){ parentNameElt = connectorElement->element_begin("connectee_name"); parentNameElt->getValueAs<std::string>(parentFrameName); const auto slashLoc = parentFrameName.rfind('/'); if (slashLoc != std::string::npos) parentFrameName = parentFrameName.substr(slashLoc + 1); } if (connectorElement->getRequiredAttributeValue("name") == "child_body") { connectorElement->setAttributeValue("name", "child_frame"); } if (connectorElement->getRequiredAttributeValue("name") == "child_frame") { childNameElt = connectorElement->element_begin("connectee_name"); childNameElt->getValueAs<std::string>(childFrameName); const auto slashLoc = childFrameName.rfind('/'); if (slashLoc != std::string::npos) childFrameName = childFrameName.substr(slashLoc + 1); } ++connectorElement; } SimTK::Xml::element_iterator locParentElt = aNode.element_begin("location_in_parent"); SimTK::Xml::element_iterator orientParentElt = aNode.element_begin("orientation_in_parent"); SimTK::Xml::element_iterator locChildElt = aNode.element_begin("location_in_child"); SimTK::Xml::element_iterator orientChildElt = aNode.element_begin("orientation_in_child"); Vec3 location_in_parent(0); Vec3 orientation_in_parent(0); Vec3 location_in_child(0); Vec3 orientation_in_child(0); if (locParentElt != aNode.element_end()){ locParentElt->getValueAs<Vec3>(location_in_parent); } if (orientParentElt != aNode.element_end()){ orientParentElt->getValueAs<Vec3>(orientation_in_parent); } if (locChildElt != aNode.element_end()){ locChildElt->getValueAs<Vec3>(location_in_child); } if (orientChildElt != aNode.element_end()){ orientChildElt->getValueAs<Vec3>(orientation_in_child); } // now append updated frames to the property list for // both parent and child XMLDocument::addPhysicalOffsetFrame30505_30517(aNode, parentFrameName+"_offset", parentFrameName, location_in_parent, orientation_in_parent); parentNameElt->setValue(parentFrameName + "_offset"); XMLDocument::addPhysicalOffsetFrame30505_30517(aNode, childFrameName + "_offset", childFrameName, location_in_child, orientation_in_child); childNameElt->setValue(childFrameName + "_offset"); } // Version 30507 replaced Joint's CoordinateSet with a "coordinates" // list property. if (documentVersion < 30507) { if (aNode.hasElement("CoordinateSet")) { auto coordSetIter = aNode.element_begin("CoordinateSet"); if (coordSetIter->hasElement("objects")) { auto coordIter = coordSetIter->getRequiredElement("objects") .element_begin("Coordinate"); if (coordIter != aNode.element_end()) { // A "CoordinateSet" element exists, it contains an // "objects" element, and the "objects" element contains // at least one "Coordinate" element. // Create an element for the new layout. Xml::Element coordinatesElement("coordinates"); // Copy all "Coordinate" elements from the old layout. while (coordIter != aNode.element_end()) { coordinatesElement.appendNode(coordIter->clone()); ++coordIter; } // Insert new "coordinates" element. aNode.insertNodeAfter(coordSetIter, coordinatesElement); } } // Remove old "CoordinateSet" element. aNode.eraseNode(coordSetIter); } } // Version 30514 removed the user-facing "reverse" property from Joint. // The parent and child frames are swapped if a "reverse" element is // found and its value is "true". if (documentVersion < 30514) { auto reverseElt = aNode.element_begin("reverse"); if (reverseElt != aNode.element_end()) { bool swapFrames = false; reverseElt->getValue().tryConvertToBool(swapFrames); if (swapFrames) { std::string oldParentFrameName = ""; std::string oldChildFrameName = ""; // Find names of parent and child frames. If more than one // "parent_frame" or "child_frame" element exists, keep the // first one. The "parent_frame" and "child_frame" elements // may be listed in either order. SimTK::Xml::element_iterator connectorsNode = aNode.element_begin("connectors"); SimTK::Xml::element_iterator connectorElt = connectorsNode-> element_begin("Connector_PhysicalFrame_"); SimTK::Xml::element_iterator connecteeNameElt; while (connectorElt != connectorsNode->element_end()) { if (connectorElt->getRequiredAttributeValue("name") == "parent_frame" && oldParentFrameName.empty()) { connecteeNameElt = connectorElt-> element_begin("connectee_name"); connecteeNameElt->getValueAs<std::string>( oldParentFrameName); } else if (connectorElt->getRequiredAttributeValue("name") == "child_frame" && oldChildFrameName.empty()) { connecteeNameElt = connectorElt-> element_begin("connectee_name"); connecteeNameElt->getValueAs<std::string>( oldChildFrameName); } ++connectorElt; } // Swap parent and child frame names. If more than one // "parent_frame" or "child_frame" element exists, assign // the same value to all such elements. connectorsNode = aNode.element_begin("connectors"); connectorElt = connectorsNode->element_begin( "Connector_PhysicalFrame_"); while (connectorElt != connectorsNode->element_end()) { if (connectorElt->getRequiredAttributeValue("name") == "parent_frame") { connecteeNameElt = connectorElt-> element_begin("connectee_name"); connecteeNameElt->setValue(oldChildFrameName); } else if (connectorElt->getRequiredAttributeValue("name") == "child_frame") { connecteeNameElt = connectorElt-> element_begin("connectee_name"); connecteeNameElt->setValue(oldParentFrameName); } ++connectorElt; } } // Remove "reverse" element regardless of its value (it is no // longer a property of Joint). aNode.eraseNode(reverseElt); } } } Super::updateFromXMLNode(aNode, versionNumber); }