From bbabe833e966c0ed2fc43de6e7b2774236bb237f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Tue, 31 Jan 2017 07:22:14 +0100 Subject: [PATCH] DependencyGraph: grouping & unflatten is optional Property group "User parameter:BaseApp/Preferences/DependencyGraph" has two booleans to enable subgraphing and unflatten (by default on): "Unflatten", "GeoFeatureSubgraphs" --- src/App/Document.cpp | 93 ++++++++++++++++++++++++++-------------- src/Gui/GraphvizView.cpp | 54 ++++++++++++++--------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 039fc38137..af2622a671 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -325,20 +325,22 @@ void Document::exportGraphviz(std::ostream& out) const * @brief addExpressionSubgraphIfNeeded Add a subgraph to the main graph if it is needed, i.e there are defined at least one expression in hte * document object, or other objects are referencing properties in it. * @param obj DocumentObject to assess. + * @param CSSubgraphs Boolean if the GeoFeatureGroups are created as subgraphs */ - void addExpressionSubgraphIfNeeded(DocumentObject * obj) { - - //coordinate systems already have a subgraph - if(obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) - return; + void addExpressionSubgraphIfNeeded(DocumentObject * obj, bool CSsubgraphs) { boost::unordered_map expressions = obj->ExpressionEngine.getExpressions(); if (expressions.size() > 0) { - auto group = GeoFeatureGroupExtension::getGroupOfObject(obj); - auto graph = group ? GraphList[group] : &DepList; + Graph* graph; + if(CSsubgraphs) { + auto group = GeoFeatureGroupExtension::getGroupOfObject(obj); + graph = group ? GraphList[group] : &DepList; + } + else + graph = &DepList; // If documentObject has an expression, create a subgraph for it if (!GraphList[obj]) { @@ -359,7 +361,15 @@ void Document::exportGraphviz(std::ostream& out) const // Doesn't exist already? if (!GraphList[o]) { - GraphList[o] = &graph->create_subgraph(); + + if(CSsubgraphs) { + auto group = GeoFeatureGroupExtension::getGroupOfObject(o); + auto graph2 = group ? GraphList[group] : &DepList; + GraphList[o] = &graph2->create_subgraph(); + } + else + GraphList[o] = &graph->create_subgraph(); + setGraphAttributes(o); } ++j; @@ -375,7 +385,7 @@ void Document::exportGraphviz(std::ostream& out) const * @param name Name of node. */ - void add(DocumentObject * docObj, const std::string & name, const std::string & label) { + void add(DocumentObject * docObj, const std::string & name, const std::string & label, bool CSSubgraphs) { //don't add objects twice if(std::find(objects.begin(), objects.end(), docObj) != objects.end()) @@ -384,15 +394,17 @@ void Document::exportGraphviz(std::ostream& out) const //find the correct graph to add the vertex too. Check first expressions graphs, afterwards //the parent CS and origin graphs Graph * sgraph = GraphList[docObj]; - if(!sgraph) { - auto group = GeoFeatureGroupExtension::getGroupOfObject(docObj); - if(group) - sgraph = GraphList[group]; + if(CSSubgraphs) { + if(!sgraph) { + auto group = GeoFeatureGroupExtension::getGroupOfObject(docObj); + if(group) + sgraph = GraphList[group]; + } + if(!sgraph) { + if(docObj->isDerivedFrom(OriginFeature::getClassTypeId())) + sgraph = GraphList[static_cast(docObj)->getOrigin()]; + } } - if(!sgraph) { - if(docObj->isDerivedFrom(OriginFeature::getClassTypeId())) - sgraph = GraphList[static_cast(docObj)->getOrigin()]; - } if(!sgraph) sgraph = &DepList; @@ -500,15 +512,20 @@ void Document::exportGraphviz(std::ostream& out) const void addSubgraphs() { - //first build up the coordinate system subgraphs - for (auto objectIt : d->objectArray) { - if (objectIt->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()) && objectIt->getInList().empty()) - recursiveCSSubgraphs(objectIt, nullptr); + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + bool CSSubgraphs = depGrp->GetBool("GeoFeatureSubgraphs", true); + + if(CSSubgraphs) { + //first build up the coordinate system subgraphs + for (auto objectIt : d->objectArray) { + if (objectIt->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()) && objectIt->getInList().empty()) + recursiveCSSubgraphs(objectIt, nullptr); + } } // Internal document objects for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) - addExpressionSubgraphIfNeeded(It->second); + addExpressionSubgraphIfNeeded(It->second, CSSubgraphs); // Add external document objects for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { @@ -518,7 +535,7 @@ void Document::exportGraphviz(std::ostream& out) const std::map::const_iterator item = GlobalVertexList.find(getId(*It2)); if (item == GlobalVertexList.end()) - addExpressionSubgraphIfNeeded(*It2); + addExpressionSubgraphIfNeeded(*It2, CSSubgraphs); } } } @@ -526,9 +543,13 @@ void Document::exportGraphviz(std::ostream& out) const // Filling up the adjacency List void buildAdjacencyList() { + + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + bool CSSubgraphs = depGrp->GetBool("GeoFeatureSubgraphs", true); + // Add internal document objects for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) - add(It->second, It->second->getNameInDocument(), It->second->Label.getValue()); + add(It->second, It->second->getNameInDocument(), It->second->Label.getValue(), CSSubgraphs); // Add external document objects for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { @@ -540,7 +561,8 @@ void Document::exportGraphviz(std::ostream& out) const if (item == GlobalVertexList.end()) add(*It2, std::string((*It2)->getDocument()->getName()) + "#" + (*It2)->getNameInDocument(), - std::string((*It2)->getDocument()->getName()) + "#" + (*It2)->Label.getValue()); + std::string((*It2)->getDocument()->getName()) + "#" + (*It2)->Label.getValue(), + CSSubgraphs); } } } @@ -588,16 +610,21 @@ void Document::exportGraphviz(std::ostream& out) const ++j; } + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + bool omitGeoFeatureGroups = depGrp->GetBool("GeoFeatureSubgraphs", true); + // Add edges between document objects for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { - - //coordinate systems are represented by subgraphs - if(It->second->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId())) - continue; - - //as well as origins - if(It->second->isDerivedFrom(Origin::getClassTypeId())) - continue; + + if(omitGeoFeatureGroups) { + //coordinate systems are represented by subgraphs + if(It->second->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId())) + continue; + + //as well as origins + if(It->second->isDerivedFrom(Origin::getClassTypeId())) + continue; + } std::map dups; std::vector OutList = It->second->getOutList(); diff --git a/src/Gui/GraphvizView.cpp b/src/Gui/GraphvizView.cpp index 670210ced9..051575dcc1 100644 --- a/src/Gui/GraphvizView.cpp +++ b/src/Gui/GraphvizView.cpp @@ -99,13 +99,20 @@ public: } void run() { - // Write data to unflatten process - unflattenProc.write(str); - unflattenProc.closeWriteChannel(); QByteArray preprocessed = str; - //no error handling: unflatten is optional - unflattenProc.waitForFinished(); - preprocessed = unflattenProc.readAll(); + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + if(hGrp->GetBool("Unflatten", true)) { + // Write data to unflatten process + unflattenProc.write(str); + unflattenProc.closeWriteChannel(); + //no error handling: unflatten is optional + unflattenProc.waitForFinished(); + preprocessed = unflattenProc.readAll(); + } else { + unflattenProc.closeWriteChannel(); + unflattenProc.waitForFinished(); + } dotProc.write(preprocessed); dotProc.closeWriteChannel(); @@ -193,7 +200,7 @@ void GraphvizView::updateSvgItem(const App::Document &doc) QProcess * flatProc = thread->unflattenProcess(); QStringList args, flatArgs; args << QLatin1String("-Tsvg"); - flatArgs << QLatin1String("-c2 -l3"); + flatArgs << QLatin1String("-c2 -l2"); #ifdef FC_OS_LINUX QString path = QString::fromUtf8(hGrp->GetASCII("Graphviz", "/usr/bin").c_str()); @@ -302,7 +309,7 @@ QByteArray GraphvizView::exportGraph(const QString& format) QProcess dotProc, flatProc; QStringList args, flatArgs; args << QString::fromLatin1("-T%1").arg(format); - flatArgs << QLatin1String("-c2 -l3"); + flatArgs << QLatin1String("-c2 -l2"); #ifdef FC_OS_LINUX QString path = QString::fromUtf8(hGrp->GetASCII("Graphviz", "/usr/bin").c_str()); @@ -317,23 +324,30 @@ QByteArray GraphvizView::exportGraph(const QString& format) QString exe = QString::fromLatin1("%1/dot").arg(path); QString unflatten = QString::fromLatin1("%1/unflatten").arg(path); #endif - flatProc.setEnvironment(QProcess::systemEnvironment()); - flatProc.start(unflatten, flatArgs); - if (!flatProc.waitForStarted()) { - return QByteArray(); - } - flatProc.write(graphCode.c_str(), graphCode.size()); - flatProc.closeWriteChannel(); - if (!flatProc.waitForFinished()) - return QByteArray(); - + dotProc.setEnvironment(QProcess::systemEnvironment()); dotProc.start(exe, args); if (!dotProc.waitForStarted()) { return QByteArray(); } - - dotProc.write(flatProc.readAll()); + + ParameterGrp::handle depGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/DependencyGraph"); + if(depGrp->GetBool("Unflatten", true)) { + flatProc.setEnvironment(QProcess::systemEnvironment()); + flatProc.start(unflatten, flatArgs); + if (!flatProc.waitForStarted()) { + return QByteArray(); + } + flatProc.write(graphCode.c_str(), graphCode.size()); + flatProc.closeWriteChannel(); + if (!flatProc.waitForFinished()) + return QByteArray(); + + dotProc.write(flatProc.readAll()); + } + else + dotProc.write(graphCode.c_str(), graphCode.size()); + dotProc.closeWriteChannel(); if (!dotProc.waitForFinished()) return QByteArray();