void TensegrityModel::addChildren(tgStructure& structure, const std::string& structurePath, tgBuildSpec& spec, const Yam& children) { if (!children) return; std::string structureAttributeKeys[] = {"path", "rotation", "translation", "scale", "offset"}; std::vector<std::string> structureAttributeKeysVector(structureAttributeKeys, structureAttributeKeys + sizeof(structureAttributeKeys) / sizeof(std::string)); // add all the children first for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) { Yam childAttributes = child->second; yamlContainsOnly(childAttributes, structurePath, structureAttributeKeysVector); // multiple children can be defined using the syntax: child1/child2/child3... // (add a slash so that each child is a string with a its name and a slash at the end) std::string childCombos = child->first.as<std::string>() + "/"; while (childCombos.find("/") != std::string::npos) { std::string childName = childCombos.substr(0, childCombos.find("/")); addChild(structure, structurePath, childName, childAttributes["path"], spec); childCombos = childCombos.substr(childCombos.find("/") + 1); } } // apply rotation attribute to children for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) { Yam childAttributes = child->second; // multiple children can be defined using the syntax: child1/child2/child3... // (add a slash so that each child is a string with a its name and a slash at the end) std::string childCombos = child->first.as<std::string>() + "/"; while (childCombos.find("/") != std::string::npos) { std::string childName = childCombos.substr(0, childCombos.find("/")); tgStructure& childStructure = structure.findChild(childName); addChildRotation(childStructure, childAttributes["rotation"]); childCombos = childCombos.substr(childCombos.find("/") + 1); } } // apply scale, offset and translation attributes to children for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) { Yam childAttributes = child->second; // multiple children can be defined using the syntax: child1/child2/child3... // (add a slash so that each child is a string with a its name and a slash at the end) std::string childCombos = child->first.as<std::string>() + "/"; int childComboIndex = 0; while (childCombos.find("/") != std::string::npos) { std::string childName = childCombos.substr(0, childCombos.find("/")); tgStructure& childStructure = structure.findChild(childName); addChildScale(childStructure, childAttributes["scale"]); addChildOffset(childStructure, childComboIndex, childAttributes["offset"]); addChildTranslation(childStructure, childAttributes["translation"]); childCombos = childCombos.substr(childCombos.find("/") + 1); childComboIndex++; } } }
void TensegrityModel::addNodeEdgePairs(tgStructure& structure, const std::string& tags, const Yam& pairs, const std::string* childStructure1Name, const std::string* childStructure2Name, tgBuildSpec& spec) { if (pairs.size() < 3) { throw std::invalid_argument("Error: node_edge bonds must specify at least 3 node_edge pairs"); } tgStructure& childStructure1 = structure.findChild(*childStructure1Name); tgStructure& childStructure2 = structure.findChild(*childStructure2Name); // these are used for transformations std::vector<btVector3> structure1RefNodes; std::vector<btVector3> structure2RefNodes; // these are nodes std::vector<tgNode*> ligands; // these are edges std::vector< std::pair<tgNode*, tgNode*> > receptors; // populate refNodes arrays, ligands and receptors parseNodeEdgePairs(childStructure1, childStructure2, structure1RefNodes, structure2RefNodes, ligands, receptors, pairs); rotateAndTranslate(childStructure2, structure1RefNodes, structure2RefNodes); std::vector<tgBuildSpec::RigidAgent*> rigidAgents = spec.getRigidAgents(); for (unsigned int i = 0; i < ligands.size(); i++) { // remove old edge connections // try removing from both children since we are not sure which child the pair belongs to // (could add more information to receptors array so we don't have to do this) removePair(childStructure1, receptors[i].first, receptors[i].second, true, rigidAgents, spec); removePair(childStructure2, receptors[i].first, receptors[i].second, true, rigidAgents, spec); for (unsigned int j = 0; j < ligands.size(); j++) { // remove old string connections between nodes/ligands // try removing from both children since we are not sure which child the node belongs to removePair(childStructure1, ligands[i], ligands[j], false, rigidAgents, spec); removePair(childStructure2, ligands[i], ligands[j], false, rigidAgents, spec); } // make new connection from edge -> node -> edge structure.addPair(*(receptors[i].first), *ligands[i], tags); structure.addPair(*ligands[i], *(receptors[i].second), tags); } }
void TensegrityModel::addNodeNodePairs(tgStructure& structure, const std::string& tags, const Yam& pairs, const std::string* childStructure1Name, const std::string* childStructure2Name) { for (YAML::const_iterator pairPtr = pairs.begin(); pairPtr != pairs.end(); ++pairPtr) { Yam pair = *pairPtr; std::string node1Path = pair[0].as<std::string>(); std::string node2Path = pair[1].as<std::string>(); tgNode* node1; tgNode* node2; if (childStructure1Name && childStructure2Name) { node1 = &getNode(structure.findChild(*childStructure1Name), node1Path); node2 = &getNode(structure.findChild(*childStructure2Name), node2Path); } else { node1 = &getNode(structure, node1Path); node2 = &getNode(structure, node2Path); } structure.addPair(*node1, *node2, tags); } }