/*************************************************************************** * Copyright (c) 2015 Thomas Anderson * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef DAGMODELGRAPH_H #define DAGMODELGRAPH_H #include #include #include #include #include #include #include #include #include #include #include #include "DAGRectItem.h" namespace App{class DocumentObject;} namespace Gui { class ViewProviderDocumentObject; namespace DAG { enum class VisibilityState { None = 0, // ColumnMask; /*! @brief Graph vertex information * * My data stored for each vertex; */ struct VertexProperty { VertexProperty(); std::shared_ptr rectangle; //!< background std::shared_ptr point; //!< point std::shared_ptr visibleIcon; //!< visible Icon std::shared_ptr stateIcon; //!< visible Icon std::shared_ptr icon; //!< icon std::shared_ptr text; //!< text int row; //!< row for this entry. ColumnMask column; //!< column number containing the point. int topoSortIndex; VisibilityState lastVisibleState; //!< visibility test. FeatureState lastFeatureState; //!< feature state test. bool dagVisible; //!< should entry be visible in the DAG view. }; /*! @brief boost data for each vertex. * * needed to create an internal index for vertex. needed for listS. * color is needed by some algorithms */ typedef boost::property < boost::vertex_index_t, std::size_t, boost::property > vertex_prop; /*! @brief Graph edge information * * My data stored for each edge; */ struct EdgeProperty { //! Feature relation meta data. Not used right now. enum class BranchTag { None = 0, //!< not defined. Create, //!< create a new branch. Continue, //!< continue a branch. Terminate //!< terminate a branch. }; EdgeProperty(); BranchTag relation; std::shared_ptr connector; //!< line representing link between nodes. }; /*! @brief needed to create an internal index for graph edges. needed for setS.*/ typedef boost::property edge_prop; typedef boost::adjacency_list Graph; typedef boost::graph_traits::vertex_descriptor Vertex; typedef boost::graph_traits::edge_descriptor Edge; typedef boost::graph_traits::vertex_iterator VertexIterator; typedef boost::graph_traits::edge_iterator EdgeIterator; typedef boost::graph_traits::in_edge_iterator InEdgeIterator; typedef boost::graph_traits::out_edge_iterator OutEdgeIterator; typedef boost::graph_traits::adjacency_iterator VertexAdjacencyIterator; typedef boost::reverse_graph GraphReversed; typedef std::vector Path; //!< a path or any array of vertices template class Edge_writer { public: Edge_writer(const GraphEW &graphEWIn) : graphEW(graphEWIn) {} template void operator()(std::ostream& out, const EdgeW& edgeW) const { out << "[label=\""; out << "edge"; out << "\"]"; } private: const GraphEW &graphEW; }; template class Vertex_writer { public: Vertex_writer(const GraphVW &graphVWIn) : graphVW(graphVWIn) {} template void operator()(std::ostream& out, const VertexW& vertexW) const { out << "[label=\""; out << graphVW[vertexW].text->toPlainText().toAscii().data(); out << "\"]"; } private: const GraphVW &graphVW; }; template void outputGraphviz(const GraphIn &graphIn, const std::string &filePath) { std::ofstream file(filePath.c_str()); boost::write_graphviz(file, graphIn, Vertex_writer(graphIn), Edge_writer(graphIn)); } //! get all the leaves of the templated graph. Not used right now. template class RakeLeaves { typedef boost::graph_traits::vertex_descriptor GraphInVertex; typedef std::vector GraphInVertices; public: RakeLeaves(const GraphIn &graphIn) : graph(graphIn) {} GraphInVertices operator()() const { GraphInVertices out; BGL_FORALL_VERTICES_T(currentVertex, graph, GraphIn) { if (boost::out_degree(currentVertex, graph) == 0) out.push_back(currentVertex); } return out; } private: const GraphIn &graph; }; //! get all the roots of the templated graph. Not used right now. template class DigRoots { typedef boost::graph_traits::vertex_descriptor GraphInVertex; typedef std::vector GraphInVertices; public: DigRoots(const GraphIn &graphIn) : graph(graphIn) {} GraphInVertices operator()() const { GraphInVertices out; BGL_FORALL_VERTICES_T(currentVertex, graph, GraphIn) { if (boost::in_degree(currentVertex, graph) == 0) out.push_back(currentVertex); } return out; } private: const GraphIn &graph; }; /*! @brief Get connected components. */ class ConnectionVisitor : public boost::default_bfs_visitor { public: ConnectionVisitor(std::vector &verticesIn) : vertices(verticesIn){} template void discover_vertex(TVertex vertex, TGraph &graph) { vertices.push_back(vertex); } private: std::vector &vertices; }; /*! Multi_index record. */ struct GraphLinkRecord { const App::DocumentObject *DObject; //!< document object const Gui::ViewProviderDocumentObject *VPDObject; //!< view provider const RectItem *rectItem; //!< qgraphics item. std::string uniqueName; //!< name for document object. Vertex vertex; //!< vertex in graph. //@{ //! used as tags. struct ByDObject{}; struct ByVPDObject{}; struct ByRectItem{}; struct ByUniqueName{}; struct ByVertex{}; //@} }; namespace BMI = boost::multi_index; typedef boost::multi_index_container < GraphLinkRecord, BMI::indexed_by < BMI::ordered_unique < BMI::tag, BMI::member >, BMI::ordered_unique < BMI::tag, BMI::member >, BMI::ordered_unique < BMI::tag, BMI::member >, BMI::ordered_unique < BMI::tag, BMI::member >, BMI::ordered_unique < BMI::tag, BMI::member > > > GraphLinkContainer; const GraphLinkRecord& findRecord(Vertex vertexIn, const GraphLinkContainer &containerIn); const GraphLinkRecord& findRecord(const App::DocumentObject* dObjectIn, const GraphLinkContainer &containerIn); const GraphLinkRecord& findRecord(const Gui::ViewProviderDocumentObject* VPDObjectIn, const GraphLinkContainer &containerIn); const GraphLinkRecord& findRecord(const RectItem* rectIn, const GraphLinkContainer &containerIn); const GraphLinkRecord& findRecord(const std::string &stringIn, const GraphLinkContainer &containerIn); void eraseRecord(const Gui::ViewProviderDocumentObject* VPDObjectIn, GraphLinkContainer &containerIn); } } #endif // DAGMODELGRAPH_H