//read all cluster tree information bool GmlParser::clusterRead(GmlObject* rootCluster, ClusterGraph& CG) { //the root cluster is only allowed to hold child clusters and //nodes in a list if (rootCluster->m_valueType != gmlListBegin) return false; // read all clusters and nodes GmlObject *rootClusterSon = rootCluster->m_pFirstSon; for(; rootClusterSon; rootClusterSon = rootClusterSon->m_pBrother) { switch(id(rootClusterSon)) { case clusterPredefKey: { //we could delete this, but we aviod the call if (rootClusterSon->m_valueType != gmlListBegin) return false; // set attributes to default values //we currently do not set any values cluster c = CG.newCluster(CG.rootCluster()); //recursively read cluster recursiveClusterRead(rootClusterSon, CG, c); } //case cluster break; case vertexPredefKey: //direct root vertices { if (rootClusterSon->m_valueType != gmlStringValue) return false; String vIDString = rootClusterSon->m_stringValue; //we only allow a vertex id as string identification if ((vIDString[0] != 'v') && (!isdigit(vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit(vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = atoi(vIDString.cstr()); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned ! Changed: //all new nodes are assigned to root //CG.reassignNode(mapToNode[vID], CG.rootCluster()); //it seems that this may be unnessecary, TODO check CG.reassignNode(m_mapToNode[vID], CG.rootCluster()); //char* vIDChar = new char[vIDString.length()+1]; //for (int ind = 1; ind < vIDString.length(); ind++) // vIDChar }//case vertex }//switch }//for all rootcluster sons return true; }//clusterread
//recursively read cluster subtree information bool GmlParser::recursiveClusterRead(GmlObject* clusterObject, ClusterGraph& CG, cluster c) { //for direct root cluster sons, this is checked twice... if (clusterObject->m_valueType != gmlListBegin) return false; GmlObject *clusterSon = clusterObject->m_pFirstSon; for(; clusterSon; clusterSon = clusterSon->m_pBrother) { //we dont read the attributes, therefore look only for //id and sons switch(id(clusterSon)) { case clusterPredefKey: { if (clusterSon->m_valueType != gmlListBegin) return false; cluster cson = CG.newCluster(c); //recursively read child cluster recursiveClusterRead(clusterSon, CG, cson); } break; case vertexPredefKey: //direct cluster vertex entries { if (clusterSon->m_valueType != gmlStringValue) return false; string vIDString = clusterSon->m_stringValue; //if old style entry "v"i if ((vIDString[0] != 'v') && (!isdigit((int)vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit((int)vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = stoi(vIDString); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned //CG.reassignNode(mapToNode[vID], c); //changed: all nodes are already assigned to root CG.reassignNode(m_mapToNode[vID], c); //char* vIDChar = new char[vIDString.length()+1]; //for (int ind = 1; ind < vIDString.length(); ind++) // vIDChar }//case vertex }//switch }//for clustersons return true; }//recursiveclusterread
bool GraphMLParser::readClusters( Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, const cluster &rootCluster, const pugi::xml_node rootTag) { for(pugi::xml_node nodeTag : rootTag.children("node")) { pugi::xml_attribute idAttr = nodeTag.attribute("id"); pugi::xml_node clusterTag = nodeTag.child("graph"); if (clusterTag == nullptr) { // Got normal node then, add it to the graph - id is required. if (!idAttr) { GraphIO::logger.lout() << "Node is missing id attribute." << endl; return false; } const node v = G.newNode(); m_nodeId[idAttr.value()] = v; C.reassignNode(v, rootCluster); // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, v, nodeTag)) { return false; } } else { // Got a cluster node - read it recursively. const cluster c = C.newCluster(rootCluster); if (!readClusters(G, C, CA, c, clusterTag)) { return false; } // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, c, nodeTag)) { return false; } } } return readEdges(G, CA, rootTag); }
bool Parser::readCluster( Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, cluster rootCluster, const XmlTagObject &rootTag) { List<XmlTagObject *> nodeTags; rootTag.findSonXmlTagObjectByName("node", nodeTags); for(XmlTagObject *obj : nodeTags) { const XmlTagObject &nodeTag = *obj; XmlAttributeObject *idAttr; nodeTag.findXmlAttributeObjectByName("id", idAttr); if(!idAttr) { OGDF_ERROR("node is missing an attribute " << "(line " << nodeTag.getLine() << ")."); } // Node is a cluster iff it contains other nodes. XmlTagObject *nodesTag; nodeTag.findSonXmlTagObjectByName("nodes", nodesTag); if(nodesTag) { // Node tag found, therefore it is a cluster. const cluster c = C.newCluster(rootCluster); m_clusterId[idAttr->getValue()] = c; if(!readCluster(G, C, CA, c, *nodesTag)) { return false; } } else { // Node tag not found, therefore it is "normal" node. const node v = G.newNode(); C.reassignNode(v, rootCluster); m_nodeId[idAttr->getValue()] = v; if(CA) { readAttributes(*CA, v, nodeTag); } } } return true; }
void CconnectClusterPlanar::constructWheelGraph(ClusterGraph &C, Graph &G, cluster &parent, PlanarPQTree* T, EdgeArray<node> &outgoingTable) { const PQNode<edge,IndInfo*,bool>* root = T->root(); const PQNode<edge,IndInfo*,bool>* checkNode = nullptr; Queue<const PQNode<edge,IndInfo*,bool>*> treeNodes; treeNodes.append(root); node correspond = G.newNode(); // Corresponds to the root node. // root node is either a leaf or a P-node C.reassignNode(correspond,parent); Queue<node> graphNodes; graphNodes.append(correspond); node hub; node next = nullptr; node pre; node newNode; // corresponds to anchor of a hub or a cut node while (!treeNodes.empty()) { checkNode = treeNodes.pop(); correspond = graphNodes.pop(); PQNode<edge,IndInfo*,bool>* firstSon = nullptr; PQNode<edge,IndInfo*,bool>* nextSon = nullptr; PQNode<edge,IndInfo*,bool>* oldSib = nullptr; PQNode<edge,IndInfo*,bool>* holdSib = nullptr; if (checkNode->type() == PQNodeRoot::PNode) { // correspond is a cut node OGDF_ASSERT(checkNode->referenceChild()) firstSon = checkNode->referenceChild(); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon && nextSon != firstSon) { if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } else if (checkNode->type() == PQNodeRoot::QNode) { // correspond is the anchor of a hub OGDF_ASSERT(checkNode->getEndmost(PQNodeRoot::LEFT)) firstSon = checkNode->getEndmost(PQNodeRoot::LEFT); hub = G.newNode(); C.reassignNode(hub,parent); G.newEdge(hub,correspond); // link anchor and hub next = G.newNode(); // for first son C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(correspond,next); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon) { next = G.newNode(); C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(pre,next); if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; pre = next; } G.newEdge(next,correspond); } } OGDF_ASSERT(C.consistencyCheck()); }
//recursively read cluster subtree information bool GmlParser::recursiveAttributedClusterRead(GmlObject* clusterObject, ClusterGraph& CG, ClusterGraphAttributes& ACG, cluster c) { //for direct root cluster sons, this is checked twice... if (clusterObject->m_valueType != gmlListBegin) return false; GmlObject *clusterSon = clusterObject->m_pFirstSon; for(; clusterSon; clusterSon = clusterSon->m_pBrother) { //we dont read the attributes, therefore look only for //id and sons switch(id(clusterSon)) { case clusterPredefKey: { if (clusterSon->m_valueType != gmlListBegin) return false; cluster cson = CG.newCluster(c); //recursively read child cluster recursiveAttributedClusterRead(clusterSon, CG, ACG, cson); } break; case labelPredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.clusterLabel(c) = clusterSon->m_stringValue; } break; case templatePredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.templateCluster(c) = clusterSon->m_stringValue; break; } case graphicsPredefKey: //read the info for cluster c { if (clusterSon->m_valueType != gmlListBegin) return false; readClusterAttributes(clusterSon, c , ACG); }//graphics break; case vertexPredefKey: //direct cluster vertex entries { if (clusterSon->m_valueType != gmlStringValue) return false; String vIDString = clusterSon->m_stringValue; if ((vIDString[0] != 'v') && (!isdigit(vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit(vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = atoi(vIDString.cstr()); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned //changed: all nodes are already assigned to root CG.reassignNode(m_mapToNode[vID], c); }//case vertex }//switch }//for clustersons return true; }//recursiveAttributedClusterRead