map<int, MyNode *> * convertGraph2Map(Graph *graph) { Graph *grille = graph->getSubGraph(2); if(!grille) grille = graph; LayoutProperty *layout = graph->getLocalProperty<LayoutProperty>("viewLayout"); BooleanProperty *fixed = graph->getProperty<BooleanProperty>("fixed nodes"); BooleanProperty *bordure = graph->getProperty<BooleanProperty>("viewSelection"); map<int,MyNode *> all_nodes; // Boucle sur tous les noeuds Iterator<node> *itNodes = grille->getNodes(); while(itNodes->hasNext()) { node n = itNodes->next(); if(all_nodes[n.id] == NULL) { Coord c = layout->getNodeValue(n); bool res = !(fixed->getNodeValue(n)) && !(bordure->getNodeValue(n)); all_nodes[n.id] = new MyNode(n, res, c); } MyNode *pn = all_nodes[n.id]; // Boucle sur tous les voisins du noeud courant Iterator<node> *itN = grille->getInOutNodes(n); while(itN->hasNext()) { node n = itN->next(); if(all_nodes[n.id] == NULL) { Coord c = layout->getNodeValue(n); bool res = !(fixed->getNodeValue(n)) && !(bordure->getNodeValue(n)); all_nodes[n.id] = new MyNode(n, res, c); } pn->getVoisin()->push_back(all_nodes[n.id]); } delete itN; } delete itNodes; Iterator <edge> *itE = grille->getEdges(); while (itE->hasNext()) { edge current_edge = itE->next(); if (bordure->getEdgeValue(current_edge)) { pair<node, node> nodes = grille->ends(current_edge); all_nodes[nodes.first.id]->setMobile(false); all_nodes[nodes.second.id]->setMobile(false); } } delete itE; return new map<int, MyNode *>(all_nodes); }
void MouseEdgeBuilder::addLink(QObject *widget, const node source, const node target) { GlMainWidget *glMainWidget = static_cast<GlMainWidget *>(widget); Graph * g = glMainWidget->getScene()->getGlGraphComposite()->getInputData()->getGraph(); LayoutProperty* mLayout = glMainWidget->getScene()->getGlGraphComposite()->getInputData()->getElementLayout(); edge newEdge = g->addEdge(source, target); mLayout->setEdgeValue(newEdge, bends()); _bends.clear(); }
static BoundingBox labelBoundingBoxForNode(Graph *graph, node n) { IntegerProperty *viewShape = graph->getProperty<IntegerProperty>("viewShape"); LayoutProperty *viewLayout = graph->getProperty<LayoutProperty>("viewLayout"); SizeProperty *viewSize = graph->getProperty<SizeProperty>("viewSize"); BoundingBox renderingBox; GlyphsManager::getGlyph(viewShape->getNodeValue(n))->getTextBoundingBox(renderingBox); const Coord &pos = viewLayout->getNodeValue(n); const Size &size = viewSize->getNodeValue(n) * Size(renderingBox.width(), renderingBox.height(), renderingBox.depth()); return BoundingBox(pos - size/2.f, pos + size/2.f); }
/* * TODO: move that function in LayoutProperty test. * */ void PlanarityTestTest::planarEmbeddingFromLayoutGraphs() { graph = tlp_loadGraph(GRAPHPATH + "planar/planar30drawnFPP.tlp.gz"); LayoutProperty *layout = graph->getProperty<LayoutProperty>("viewLayout"); layout->computeEmbedding(graph); CPPUNIT_ASSERT(PlanarityTest::isPlanarEmbedding(graph)); delete graph; graph = tlp_loadGraph(GRAPHPATH + "planar/planar30drawnMM.tlp.gz"); layout = graph->getProperty<LayoutProperty>("viewLayout"); layout->computeEmbedding(graph); CPPUNIT_ASSERT(PlanarityTest::isPlanarEmbedding(graph)); delete graph; graph = tlp_loadGraph(GRAPHPATH + "notplanar/k33lostInGrip.tlp.gz"); layout = graph->getProperty<LayoutProperty>("viewLayout"); layout->computeEmbedding(graph); CPPUNIT_ASSERT(!PlanarityTest::isPlanarEmbedding(graph)); delete graph; }
bool importGraph() { unsigned int nbNodes = 30; if (dataSet!=NULL) { dataSet->get("nodes", nbNodes); } if (nbNodes < 3) nbNodes = 3; srand(clock()); LayoutProperty *newLayout = graph->getLocalProperty<LayoutProperty>("viewLayout"); SizeProperty *newSize = graph->getLocalProperty<SizeProperty>("viewSize"); newSize->setAllNodeValue(Size(1.0,1.0,1.0)); vector<Triangle> faces; Triangle f(graph->addNode(), graph->addNode(), graph->addNode()); faces.push_back(f); graph->addEdge(f.a, f.b); graph->addEdge(f.b, f.c); graph->addEdge(f.c, f.a); float val = static_cast<float>(nbNodes); newLayout->setNodeValue(f.a, Coord(-val, -val, 0)); newLayout->setNodeValue(f.b, Coord(0, val, 0)); newLayout->setNodeValue(f.c, Coord(val, -val, 0)); unsigned int nb = 3; while(nb<nbNodes) { //choose a Triangle randomly unsigned int i = rand()%faces.size(); Triangle f = faces[i]; node n = graph->addNode(); Coord tmp = newLayout->getNodeValue(f.a) + newLayout->getNodeValue(f.b) + newLayout->getNodeValue(f.c); tmp /= 3.0; newLayout->setNodeValue(n, tmp); //Split the triangle in three part graph->addEdge(n, f.a); graph->addEdge(n, f.b); graph->addEdge(n, f.c); //add the three new Triangle, remove the old one(replace) Triangle f1(f.a, f.b, n); Triangle f2(f.b, f.c, n); Triangle f3(f.c, f.a, n); faces[i] = f1; faces.push_back(f2); faces.push_back(f3); ++nb; } return pluginProgress->state()!=TLP_CANCEL; }
void TestPropertiesMinMaxAfterAddNode::testLayoutPropertyMinMaxAfterAddNode() { LayoutProperty *property = graph->getProperty<LayoutProperty>("testLayout"); // add two nodes node n1 = graph->addNode(); node n2 = graph->addNode(); const Coord firstNodePos(1.0f, 2.0f); const Coord secondNodePos(3.0f, 4.0f); property->setNodeValue(n1, firstNodePos); property->setNodeValue(n2, secondNodePos); CPPUNIT_ASSERT_EQUAL(firstNodePos, property->getMin(graph)); CPPUNIT_ASSERT_EQUAL(secondNodePos, property->getMax(graph)); // add a new node, the value associated to the layout property is the default one 0 graph->addNode(); // min should be 0 CPPUNIT_ASSERT_EQUAL(Coord(), property->getMin(graph)); CPPUNIT_ASSERT_EQUAL(secondNodePos, property->getMax(graph)); }
bool exportGraph(ostream &os) { os << "graph [" << endl; os << "directed 1" << endl; os << "version 2" << endl; LayoutProperty *layout = graph->getProperty<LayoutProperty>("viewLayout"); StringProperty *label = graph->getProperty<StringProperty>("viewLabel"); // IntegerProperty *shape =getProperty<IntegerProperty>(graph->getPropertyManager(),"viewShape"); ColorProperty *colors = graph->getProperty<ColorProperty>("viewColor"); SizeProperty *sizes = graph->getProperty<SizeProperty>("viewSize"); //Save Nodes Iterator<node> *itN=graph->getNodes(); if (itN->hasNext()) { for (; itN->hasNext();) { node itn=itN->next(); os << "node [" << endl; os << "id "<< itn.id << endl ; os << "label \"" << convert(label->getNodeValue(itn)) << "\"" << endl; os << "graphics [" << endl; printCoord(os,layout->getNodeValue(itn)); printSize(os,sizes->getNodeValue(itn)); os << "type \"rectangle\"" << endl; os << "width 0.12" << endl; os << "fill \"#"<< hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getR() << hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getG() << hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getB() << "\""<< endl; // os << "outline \"#"<< hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getR() // << hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getG() // << hex << setfill('0') << setw(2) <<(int)colors->getNodeValue(itn).getB() << "\""<< endl; os << "outline \"#000000\"" << endl; os << dec << setfill(' ') << setw(6) << "]" << endl; os << ']' << endl; } } delete itN; //Save edges Iterator<edge> *itE=graph->getEdges(); for (; itE->hasNext();) { edge ite=itE->next(); os << "edge [" << endl; os << "source " << graph->source(ite).id << endl; os << "target " << graph->target(ite).id << endl; os << "id " << ite.id << endl; os << "label \"" << label->getEdgeValue(ite) << "\"" << endl; os << "graphics [" << endl; os << "type \"line\"" << endl; os << "arrow \"last\"" << endl; os << "width 0.1" << endl; os << "Line [" << endl; vector<Coord> lcoord; vector<Coord>::const_iterator it; lcoord=layout->getEdgeValue(ite); if (!lcoord.empty()) { node itn=graph->source(ite); printPoint(os,layout->getNodeValue(itn)); } for (it=lcoord.begin(); it!=lcoord.end(); ++it) { printPoint(os,*it); } if (!lcoord.empty()) { node itn=graph->target(ite); printPoint(os,layout->getNodeValue(itn)); } os << "]" << endl; os << "]" << endl; os << "]" << endl; } delete itE; os << "]" << endl; return true; }
//==================================================================== bool ConnectedComponentPacking::run() { LayoutProperty *layout = NULL; SizeProperty *size = NULL; DoubleProperty *rotation = NULL; string complexity("auto"); workingGraph = graph->addCloneSubGraph("workingGraph"); if ( dataSet!=NULL ) { dataSet->get("coordinates", layout); getNodeSizePropertyParameter(dataSet, size); dataSet->get("rotation", rotation); StringCollection complexityCol; if (dataSet->get("complexity", complexityCol)) complexity = complexityCol.getCurrentString(); } if (layout==NULL) layout = workingGraph->getProperty<LayoutProperty>("viewLayout"); if (size==NULL) size = workingGraph->getProperty<SizeProperty>("viewSize"); if (rotation==NULL) rotation = workingGraph->getProperty<DoubleProperty>("viewRotation"); if (complexity=="none") complexity = "auto"; // compute the connected components's subgraphs std::vector<std::set<node> > components; ConnectedTest::computeConnectedComponents(workingGraph, components); for (unsigned int i = 0; i < components.size(); ++i) { workingGraph->inducedSubGraph(components[i]); } vector<Rectangle<float> > rectangles; Iterator<Graph *> *it = workingGraph->getSubGraphs(); while(it->hasNext()) { Graph *sg = it->next(); BoundingBox tmp = tlp::computeBoundingBox(sg, layout, size, rotation); Rectangle<float> tmpRec; tmpRec[1][0] = tmp[1][0] + spacing; tmpRec[1][1] = tmp[1][1] + spacing; tmpRec[0][0] = tmp[0][0] + spacing; tmpRec[0][1] = tmp[0][1] + spacing; assert(tmpRec.isValid()); rectangles.push_back(tmpRec); } delete it; if (complexity == "auto") { if (rectangles.size()<25) { complexity="n5"; } else if (rectangles.size()<50) { complexity="n4logn"; } else if (rectangles.size()<100) { complexity="n4"; } else if (rectangles.size()<150) { complexity="n3logn"; } else if (rectangles.size()<250) { complexity="n3"; } else if (rectangles.size()<500) { complexity="n2logn"; } else if (rectangles.size()<1000) { complexity="n2"; } else if (rectangles.size()<5000) { complexity="nlogn"; } else complexity="n"; } vector<Rectangle<float> > rectanglesBackup(rectangles); RectanglePackingLimitRectangles(rectangles, complexity.c_str(), pluginProgress); Iterator<node> *itN = graph->getNodes(); while(itN->hasNext()) { node n = itN->next(); layoutResult->setNodeValue(n, layout->getNodeValue(n)); } delete itN; Iterator<edge> *itE = graph->getEdges(); while(itE->hasNext()) { edge e = itE->next(); layoutResult->setEdgeValue(e, layout->getEdgeValue(e)); } delete itE; unsigned int i = 0; it = workingGraph->getSubGraphs(); while(it->hasNext()) { Graph *sg = it->next(); Coord move(rectangles[i][0][0]-rectanglesBackup[i][0][0], rectangles[i][0][1]-rectanglesBackup[i][0][1], 0); layoutResult->translate(move, sg); ++i; } delete it; graph->delAllSubGraphs(workingGraph); return true; }
bool MouseEdgeBuilder::eventFilter(QObject *widget, QEvent *e) { GlMainWidget *glMainWidget = static_cast<GlMainWidget *>(widget); if (e->type() == QEvent::MouseButtonPress) { QMouseEvent * qMouseEv = static_cast<QMouseEvent *>(e); SelectedEntity selectedEntity; GlGraphInputData *inputData=glMainWidget->getScene()->getGlGraphComposite()->getInputData(); Graph * _graph = inputData->getGraph(); LayoutProperty* mLayout = inputData->getElementLayout(); if (qMouseEv->buttons()==Qt::LeftButton) { if (!_started) { bool result=glMainWidget->pickNodesEdges(qMouseEv->x(), qMouseEv->y(), selectedEntity); if (result && (selectedEntity.getEntityType() == SelectedEntity::NODE_SELECTED)) { _started=true; initObserver(_graph); _source=node(selectedEntity.getComplexEntityId()); _curPos=_startPos=mLayout->getNodeValue(_source); return true; } return false; } else { bool result = glMainWidget->pickNodesEdges(qMouseEv->x(),qMouseEv->y(),selectedEntity); if (result && (selectedEntity.getEntityType() == SelectedEntity::NODE_SELECTED)) { Observable::holdObservers(); _started=false; clearObserver(); // allow to undo _graph->push(); addLink(widget,_source,node(selectedEntity.getComplexEntityId())); Observable::unholdObservers(); } else { Coord point(glMainWidget->width() - qMouseEv->x(), qMouseEv->y(), 0); _bends.push_back(glMainWidget->getScene()->getGraphCamera().viewportTo3DWorld(glMainWidget->screenToViewport(point))); glMainWidget->redraw(); } } return true; } if (qMouseEv->buttons()==Qt::MidButton) { _bends.clear(); _started=false; _source=node(); clearObserver(); glMainWidget->draw(); return true; } } if (e->type() == QEvent::MouseMove) { QMouseEvent * qMouseEv = static_cast<QMouseEvent *>(e); if (!_started) { SelectedEntity selectedEntity; bool hoveringOverNode = glMainWidget->pickNodesEdges(qMouseEv->x(), qMouseEv->y(), selectedEntity) && selectedEntity.getEntityType() == SelectedEntity::NODE_SELECTED; if (!hoveringOverNode) { glMainWidget->setCursor(QCursor(Qt::ArrowCursor)); return false; } else { glMainWidget->setCursor(QCursor(Qt::CrossCursor)); } } else { SelectedEntity selectedEntity; if(glMainWidget->pickNodesEdges(qMouseEv->x(), qMouseEv->y(), selectedEntity) && selectedEntity.getEntityType() == SelectedEntity::NODE_SELECTED) { glMainWidget->setCursor(QCursor(Qt::CrossCursor)); } else { glMainWidget->setCursor(QCursor(Qt::ArrowCursor)); } Coord point(glMainWidget->width() - qMouseEv->x(), qMouseEv->y(), 0); point = glMainWidget->getScene()->getGraphCamera().viewportTo3DWorld(glMainWidget->screenToViewport(point)); _curPos.set(point[0], point[1], point[2]); glMainWidget->redraw(); } return true; } return false; }