void ModelComponent::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { if (versionNumber < XMLDocument::getLatestVersion()) { if (versionNumber < 30506) { // geometry list property removed. Everything that was in this list // should be moved to the components list property. SimTK::Xml::element_iterator geometry = aNode.element_begin("geometry"); if (geometry != aNode.element_end()) { // We found a list property of geometry. SimTK::Xml::Element componentsNode; SimTK::Xml::element_iterator componentsIt = aNode.element_begin("components"); if (componentsIt == aNode.element_end()) { // This component does not yet have a list property of // components, so we'll create one. componentsNode = SimTK::Xml::Element("components"); aNode.insertNodeBefore(aNode.element_begin(), componentsNode); } else { componentsNode = *componentsIt; } // Copy each node under <geometry> into <components>. for (auto geomIt = geometry->element_begin(); geomIt != geometry->element_end(); ++geomIt) { componentsNode.appendNode(geomIt->clone()); } // Now that we moved over the geometry, we can delete the // <geometry> element. aNode.eraseNode(geometry); } } } Super::updateFromXMLNode(aNode, versionNumber); }
// 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]); } }
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); }