diff --git a/src/Mod/TechDraw/App/CMakeLists.txt b/src/Mod/TechDraw/App/CMakeLists.txt index 366cd9f72d..cc0a024a6b 100644 --- a/src/Mod/TechDraw/App/CMakeLists.txt +++ b/src/Mod/TechDraw/App/CMakeLists.txt @@ -76,7 +76,8 @@ SET(Draw_SRCS DrawHatch.cpp DrawHatch.h DrawViewDraft.cpp - DrawViewDraft.h) + DrawViewDraft.h +) SET(TechDraw_SRCS AppTechDraw.cpp @@ -85,6 +86,8 @@ SET(TechDraw_SRCS DrawUtil.h PreCompiled.cpp PreCompiled.h + EdgeWalker.cpp + EdgeWalker.h ) SET(Geometry_SRCS diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index c327a5128f..a60a061caa 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -29,6 +29,7 @@ #endif #include +//#include #include #include @@ -45,8 +46,6 @@ #include #include #include -#include -#include #include #include #include @@ -61,6 +60,19 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +//# include +//# include +#include +#include +#include + #include #include #include @@ -69,12 +81,14 @@ #include "Geometry.h" #include "DrawViewPart.h" -//#include "ProjectionAlgos.h" #include "DrawHatch.h" -//#include "DrawViewDimension.h" +#include "EdgeWalker.h" + #include "DrawViewPartPy.h" // generated from DrawViewPartPy.xml +void _dumpEdge1(char* label, int i, TopoDS_Edge e); + using namespace TechDraw; using namespace std; @@ -242,14 +256,162 @@ void DrawViewPart::extractFaces() geometryObject->clearFaceGeom(); const std::vector& goEdges = geometryObject->getEdgeGeometry(); std::vector::const_iterator itEdge = goEdges.begin(); - std::vector occEdges; + std::vector origEdges; for (;itEdge != goEdges.end(); itEdge++) { - occEdges.push_back((*itEdge)->occEdge); + origEdges.push_back((*itEdge)->occEdge); } - //almost works. :( - std::vector wires = connectEdges(occEdges); - std::vector sortedWires = sortWiresBySize(wires,true); //smallest first + std::vector faceEdges = origEdges; + std::vector::iterator itOrig = origEdges.begin(); + + //HLR algo does not provide all edge intersections for edge endpoints. + //need to split long edges touched by Vertex of another edge + int idb = 0; + for (; itOrig != origEdges.end(); itOrig++, idb++) { + TopoDS_Vertex v1 = TopExp::FirstVertex((*itOrig)); + TopoDS_Vertex v2 = TopExp::LastVertex((*itOrig)); + std::vector::iterator itNew = faceEdges.begin(); + std::vector deleteList; + std::vector edgesToAdd; + int idx = 0; + for (; itNew != faceEdges.end(); itNew++,idx++) { + if ( itOrig->IsSame(*itNew) ){ + continue; + } + bool removeThis = false; + std::vector splitPoints; + if (isOnEdge((*itNew),v1,false)) { + splitPoints.push_back(v1); + removeThis = true; + } + if (isOnEdge((*itNew),v2,false)) { + splitPoints.push_back(v2); + removeThis = true; + } + if (removeThis) { + deleteList.push_back(idx); + } + + if (!splitPoints.empty()) { + std::vector subEdges = splitEdge(splitPoints,(*itNew)); + edgesToAdd.insert(std::end(edgesToAdd), std::begin(subEdges), std::end(subEdges)); + } + } + //delete the split edge(s) and add the subedges + //TODO: look into sets or maps or???? for all this + std::sort(deleteList.begin(),deleteList.end()); //ascending + auto last = std::unique(deleteList.begin(), deleteList.end()); //duplicates at back + deleteList.erase(last, deleteList.end()); //remove dupls + std::vector::reverse_iterator ritDel = deleteList.rbegin(); + for ( ; ritDel != deleteList.rend(); ritDel++) { + faceEdges.erase(faceEdges.begin() + (*ritDel)); + } + faceEdges.insert(std::end(faceEdges), std::begin(edgesToAdd),std::end(edgesToAdd)); + } + + //find list of unique Vertex + std::vector uniqueVert; + for(auto& fe:faceEdges) { + TopoDS_Vertex v1 = TopExp::FirstVertex(fe); + TopoDS_Vertex v2 = TopExp::LastVertex(fe); + bool addv1 = true; + bool addv2 = true; + for (auto v:uniqueVert) { + if (isSamePoint(v,v1)) + addv1 = false; + if (isSamePoint(v,v2)) + addv2 = false; + } + if (addv1) + uniqueVert.push_back(v1); + if (addv2) + uniqueVert.push_back(v2); + } + + //rebuild every edge using only unique verts + //this should help with connecting them later + std::vector cleanEdges; + std::vector walkerEdges; + for (auto fe:faceEdges) { + TopoDS_Vertex fev1 = TopExp::FirstVertex(fe); + TopoDS_Vertex fev2 = TopExp::LastVertex(fe); + int v1dx = findUniqueVert(fev1, uniqueVert); + int v2dx = findUniqueVert(fev2, uniqueVert); + BRepAdaptor_Curve adapt(fe); + Handle_Geom_Curve c = adapt.Curve().Curve(); + BRepBuilderAPI_MakeEdge mkBuilder1(c, uniqueVert.at(v1dx), uniqueVert.at(v2dx)); + TopoDS_Edge eClean = mkBuilder1.Edge(); + cleanEdges.push_back(eClean); + WalkerEdge we; + we.v1 = v1dx; + we.v2 = v2dx; + walkerEdges.push_back(we); + } + + EdgeWalker ew; + ew.setSize(uniqueVert.size()); + ew.loadEdges(walkerEdges); + ew.perform(); + facelist result = ew.getResult(); + + facelist::iterator iFace = result.begin(); + std::vector fw; + for (;iFace != result.end(); iFace++) { + edgelist::iterator iEdge = (*iFace).begin(); + std::vector fe; + for (;iEdge != (*iFace).end(); iEdge++) { + fe.push_back(cleanEdges.at((*iEdge).idx)); + } + std::vector w = connectEdges(fe); + fw.push_back(w.at(0)); //looks weird, but we only passing 1 wire's edges so we only want 1 wire back + } + + std::vector sortedWires = sortWiresBySize(fw,false); + + //remove the largest wire (OuterWire of graph) + Bnd_Box bigBox; + if (!(sortedWires.back().IsNull())) { + BRepBndLib::Add(sortedWires.front(), bigBox); + bigBox.SetGap(0.0); + } + std::vector toBeChecked; + std::vector::iterator it = sortedWires.begin() + 1; + for (; it != sortedWires.end(); it++) { + if (!(*it).IsNull()) { + Bnd_Box littleBox; + BRepBndLib::Add((*it), littleBox); + littleBox.SetGap(0.0); + if (bigBox.SquareExtent() > littleBox.SquareExtent()) { + break; + } else { + auto position = std::distance( sortedWires.begin(), it ); //get an index from iterator + toBeChecked.push_back(position); + } + } + } + //unfortuneately, faces can have same bbox, but not be same size. need to weed out biggest + if (toBeChecked.size() == 0) { + //nobody had as big a bbox as first element of sortedWires + sortedWires.erase(sortedWires.begin()); + } else if (toBeChecked.size() > 0) { + BRepBuilderAPI_MakeFace mkFace(sortedWires.front()); + const TopoDS_Face& face = mkFace.Face(); + GProp_GProps props; + BRepGProp::SurfaceProperties(face, props); + double bigArea = props.Mass(); + unsigned int bigIndex = 0; + for (unsigned int idx = 1; idx < toBeChecked.size(); idx++) { + BRepBuilderAPI_MakeFace mkFace2(sortedWires.at(idx)); + const TopoDS_Face& face2 = mkFace2.Face(); + BRepGProp::SurfaceProperties(face2, props); + double area = props.Mass(); + if (area > bigArea) { + bigArea = area; + bigIndex = idx; + } + } + sortedWires.erase(sortedWires.begin() + bigIndex); + } std::vector::iterator itWire = sortedWires.begin(); for (; itWire != sortedWires.end(); itWire++) { @@ -262,6 +424,113 @@ void DrawViewPart::extractFaces() } } +//obs? +int DrawViewPart::findEdgeByWalkerEdge(WalkerEdge we, std::vector uniqueVert, std::vector& edges) +{ + int result = -1; + TopoDS_Vertex v1 = uniqueVert.at(we.v1); + TopoDS_Vertex v2 = uniqueVert.at(we.v2); + int idx = 0; + for (auto& e:edges) { + TopoDS_Vertex ev1 = TopExp::FirstVertex(e); + TopoDS_Vertex ev2 = TopExp::LastVertex(e); + if ( (isSamePoint(v1,ev1) && isSamePoint(v2,ev2)) || + (isSamePoint(v2,ev1) && isSamePoint(v1,ev2)) ) { + result = idx; + break; + } + idx++; + } + return result; +} + +int DrawViewPart::findUniqueVert(TopoDS_Vertex vx, std::vector &uniqueVert) +{ + int idx = 0; + int result = 0; + for(auto& v:uniqueVert) { //we're always going to find vx, right? + if (isSamePoint(v,vx)) { + result = idx; + break; + } + idx++; + } //if idx >= uniqueVert.size() TARFU + return result; +} + +double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) +{ + Standard_Real minDist = -1; + + BRepExtrema_DistShapeShape extss(s1, s2); + if (!extss.IsDone()) { + Base::Console().Message("DVP - BRepExtrema_DistShapeShape failed"); + return -1; + } + int count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + } else { + minDist = -1; + } + return minDist; +} + +bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, bool allowEnds) +{ + bool result = false; + double dist = simpleMinDist(v,e); + if (dist < 0.0) { + Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist); + result = false; + } else if (dist < Precision::Confusion()) { + result = true; + } + if (result) { + TopoDS_Vertex v1 = TopExp::FirstVertex(e); + TopoDS_Vertex v2 = TopExp::LastVertex(e); + if (isSamePoint(v,v1) || isSamePoint(v,v2)) { + if (!allowEnds) { + result = false; + } + } + } + return result; +} + +bool DrawViewPart::isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2) +{ + bool result = false; + gp_Pnt p1 = BRep_Tool::Pnt(v1); + gp_Pnt p2 = BRep_Tool::Pnt(v2); + if (p1.IsEqual(p2,Precision::Confusion())) { + result = true; + } + return result; +} + +std::vector DrawViewPart::splitEdge(std::vector splitPoints, TopoDS_Edge e) +{ + std::vector result; + if (splitPoints.empty()) { + return result; + } + TopoDS_Vertex vStart = TopExp::FirstVertex(e); + TopoDS_Vertex vEnd = TopExp::LastVertex(e); + + BRepAdaptor_Curve adapt(e); + Handle_Geom_Curve c = adapt.Curve().Curve(); + //simple version for 1 splitPoint + //TODO: handle case where e is split in multiple points (ie circular edge cuts line twice) + BRepBuilderAPI_MakeEdge mkBuilder1(c, vStart, splitPoints[0]); + TopoDS_Edge e1 = mkBuilder1.Edge(); + BRepBuilderAPI_MakeEdge mkBuilder2(c, splitPoints[0], vEnd); + TopoDS_Edge e2 = mkBuilder2.Edge(); + result.push_back(e1); + result.push_back(e2); + return result; +} + std::vector DrawViewPart::getHatches() const { std::vector result; @@ -272,7 +541,6 @@ std::vector DrawViewPart::getHatches() const result.push_back(hatch); } } - return result; } @@ -331,20 +599,21 @@ std::vector DrawViewPart::connectEdges (std::vector& e //tolerance sb tolerance of DrawViewPart instead of Precision::Confusion()? ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_False, hWires); - int len = hWires->Length(); for(int i=1;i<=len;i++) { TopoDS_Wire w = TopoDS::Wire(hWires->Value(i)); - //if (BRep_Tool::IsClosed(w)) { + if (BRep_Tool::IsClosed(w)) { result.push_back(w); - //} + } } + //delete hEdges; //does Handle<> take care of this? //delete hWires; return result; } //! return true if w1 bbox is bigger than w2 bbox +//NOTE: this won't necessarily sort the OuterWire correctly (ex smaller wire, same bbox) class DrawViewPart::wireCompare: public std::binary_function { @@ -366,12 +635,12 @@ public: } }; -//sort wires in descending order of bbox diagonal. if reversed, then ascending bbox diagonal -std::vector DrawViewPart::sortWiresBySize(std::vector& w, bool reverse) +//sort wires in order of bbox diagonal. +std::vector DrawViewPart::sortWiresBySize(std::vector& w, bool ascend) { std::vector wires = w; std::sort(wires.begin(), wires.end(), wireCompare()); - if (reverse) { + if (ascend) { std::reverse(wires.begin(),wires.end()); } return wires; @@ -422,6 +691,22 @@ PyObject *DrawViewPart::getPyObject(void) return Py::new_reference_to(PythonObject); } +void _dumpEdge1(char* label, int i, TopoDS_Edge e) +{ + BRepAdaptor_Curve adapt(e); + double start = BRepLProp_CurveTool::FirstParameter(adapt); + double end = BRepLProp_CurveTool::LastParameter(adapt); + BRepLProp_CLProps propStart(adapt,start,0,Precision::Confusion()); + const gp_Pnt& vStart = propStart.Value(); + BRepLProp_CLProps propEnd(adapt,end,0,Precision::Confusion()); + const gp_Pnt& vEnd = propEnd.Value(); + //Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f)/%0.3f end:(%.2f,%.3f,%.3f)/%.3f\n",label,i, + // vStart.X(),vStart.Y(),vStart.Z(),start,vEnd.X(),vEnd.Y(),vEnd.Z(),end); + Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f) end:(%.2f,%.3f,%.3f)\n",label,i, + vStart.X(),vStart.Y(),vStart.Z(),vEnd.X(),vEnd.Y(),vEnd.Z()); +} + + // Python Drawing feature --------------------------------------------------------- namespace App { diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index a2ca7f8f33..df0e3dde0b 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -24,6 +24,9 @@ #ifndef _DrawViewPart_h_ #define _DrawViewPart_h_ +#include +#include + #include #include #include "DrawView.h" @@ -34,13 +37,12 @@ namespace TechDraw { class DrawHatch; +class WalkerEdge; } namespace TechDraw { -/** Base class of all View Features in the drawing module - */ class TechDrawExport DrawViewPart : public DrawView { PROPERTY_HEADER(TechDraw::DrawViewPart); @@ -106,6 +108,13 @@ protected: std::vector sortWiresBySize(std::vector& w, bool reverse = false); class wireCompare; + bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, bool allowEnds = false); + std::vector splitEdge(std::vector splitPoints, TopoDS_Edge e); + double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); + bool isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2); + int findUniqueVert(TopoDS_Vertex vx, std::vector &uniqueVert); + int findEdgeByWalkerEdge(WalkerEdge we, std::vector uniqueVert, std::vector& edges); + private: static App::PropertyFloatConstraint::Constraints floatRange; diff --git a/src/Mod/TechDraw/App/EdgeWalker.cpp b/src/Mod/TechDraw/App/EdgeWalker.cpp new file mode 100644 index 0000000000..a9a9ddf9d7 --- /dev/null +++ b/src/Mod/TechDraw/App/EdgeWalker.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** + * Copyright (c) 2016 Wandererfan * + * * + * 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 * + * * + ***************************************************************************/ + +//#include "PreCompiled.h" + +#include "EdgeWalker.h" + +using namespace TechDraw; +using namespace boost; + +//******************************************************* +//* edgeVisior methods +//******************************************************* +template +void edgeVisitor::next_edge(Edge e) +{ + std::cout << e << " "; + graph_traits::vertex_descriptor s = source(e,m_g); + graph_traits::vertex_descriptor t = target(e,m_g); + WalkerEdge we; + we.v1 = s; + we.v2 = t; + we.idx = get(edge_index,m_g,e); + faceEdges.push_back(we); +} + +void edgeVisitor::begin_face() +{ + std::cout << "begin_face()" << std::endl; + faceEdges.clear(); +} + +void edgeVisitor::end_face() +{ + std::cout << "end_face()" << std::endl; + graphFaces.push_back(faceEdges); +} + +facelist edgeVisitor::getResult(void) +{ + return graphFaces; +} + +void edgeVisitor::setGraph(graph& g) +{ + std::cout << "setGraph()" << std::endl; + m_g = g; +} + +//******************************************************* +//* EdgeWalker +//******************************************************* + +EdgeWalker::EdgeWalker() +{ +} + +EdgeWalker::~EdgeWalker() +{ +} + +bool EdgeWalker::loadEdges(std::vector edges) +{ + std::cout << "loadEdges()" << std::endl; + for (auto e: edges) { + add_edge(e.v1,e.v2,m_g); + } +// add_edge(0, 1, m_g); +// add_edge(2, 3, m_g); +// add_edge(4, 0, m_g); +// add_edge(5, 3, m_g); +// add_edge(6, 7, m_g); +// add_edge(6, 4, m_g); +// add_edge(7, 5, m_g); +// add_edge(8, 9, m_g); +// add_edge(4, 1, m_g); +// add_edge(1, 8, m_g); +// add_edge(5, 2, m_g); +// add_edge(2, 9, m_g); + return true; +} + +bool EdgeWalker::setSize(int size) +{ + std::cout << "setsize()" << std::endl; + m_g.clear(); + for (int i = 0; i < size; i++) { + boost::adjacency_list<>::vertex_descriptor vd = boost::add_vertex(m_g); + } + return true; +} + +bool EdgeWalker::perform() +{ + // Initialize the interior edge index + //property + property_map::type e_index = get(edge_index, m_g); + graph_traits::edges_size_type edge_count = 0; + graph_traits::edge_iterator ei, ei_end; + for(boost::tie(ei, ei_end) = edges(m_g); ei != ei_end; ++ei) + put(e_index, *ei, edge_count++); + + // Test for planarity - we know it is planar, we just want to + // compute the planar embedding as a side-effect + typedef std::vector< graph_traits::edge_descriptor > vec_t; + std::vector embedding(num_vertices(m_g)); + boyer_myrvold_planarity_test(boyer_myrvold_params::graph = m_g, + boyer_myrvold_params::embedding = &embedding[0]); + + m_eV.setGraph(m_g); + planar_face_traversal(m_g, &embedding[0], m_eV); + + return true; +} + +facelist EdgeWalker::getResult() +{ + TechDraw::facelist result = m_eV.getResult(); + TechDraw::facelist::iterator iFace = result.begin(); + for (;iFace != result.end(); iFace++) { + std::cout << "face begins:" << std::endl; + TechDraw::edgelist::iterator iEdge = (*iFace).begin(); + for (;iEdge != (*iFace).end(); iEdge++) { + std::cout << (*iEdge).idx << ":(" << (*iEdge).v1 << ", " << (*iEdge).v2 << ") "; + } + std::cout << std::endl; + } + return result; +} diff --git a/src/Mod/TechDraw/App/EdgeWalker.h b/src/Mod/TechDraw/App/EdgeWalker.h new file mode 100644 index 0000000000..98f4c3f42f --- /dev/null +++ b/src/Mod/TechDraw/App/EdgeWalker.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (c) 2016 Wandererfan * + * * + * 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 TECHDRAW_EDGEWALKER_H +#define TECHDRAW_EDGEWALKER_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace TechDraw { +using namespace boost; + +typedef adjacency_list + < vecS, + vecS, + undirectedS, + property, + property + > + graph; + +struct WalkerEdge { + int v1; + int v2; + int idx; +}; + +typedef std::vector edgelist; +typedef std::vector facelist ; + + +class edgeVisitor : public planar_face_traversal_visitor +{ +public: + template + void next_edge(Edge e); + void begin_face(); + void end_face(); + facelist getResult(void); + void setGraph(graph& g); + +private: + edgelist faceEdges; + facelist graphFaces; + graph m_g; +}; + +class EdgeWalker +{ +public: + EdgeWalker(void); + virtual ~EdgeWalker(); + + bool loadEdges(std::vector edges); + bool setSize(int size); + bool perform(); + facelist getResult(); + +private: + edgeVisitor m_eV; + graph m_g; +}; + +} //end namespace + +#endif //TECHDRAW_EDGEWALKER_H diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index 4cddb084d2..2b047fbd62 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -730,8 +730,8 @@ void _dumpEdge(char* label, int i, TopoDS_Edge e) const gp_Pnt& vStart = propStart.Value(); BRepLProp_CLProps propEnd(adapt,end,0,Precision::Confusion()); const gp_Pnt& vEnd = propEnd.Value(); - Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f) end:(%.2f,%.3f,%.3f)\n",label,i, - vStart.X(),vStart.Y(),vStart.Z(),vEnd.X(),vEnd.Y(),vEnd.Z()); + Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f)/%0.3f end:(%.2f,%.3f,%.3f)/%.3f\n",label,i, + vStart.X(),vStart.Y(),vStart.Z(),start,vEnd.X(),vEnd.Y(),vEnd.Z(),end); } const char* _printBool(bool b) diff --git a/src/Mod/TechDraw/CMakeLists.txt b/src/Mod/TechDraw/CMakeLists.txt index ebe8e7f47e..3ac9123676 100644 --- a/src/Mod/TechDraw/CMakeLists.txt +++ b/src/Mod/TechDraw/CMakeLists.txt @@ -1,5 +1,5 @@ -add_definitions(-DMOD_TECHDRAW_HANDLE_FACES=0) +add_definitions(-DMOD_TECHDRAW_HANDLE_FACES=1) add_subdirectory(App) if(BUILD_GUI) diff --git a/src/Mod/TechDraw/Gui/QGIFace.cpp b/src/Mod/TechDraw/Gui/QGIFace.cpp index e7009faafe..55fd16e29f 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.cpp +++ b/src/Mod/TechDraw/Gui/QGIFace.cpp @@ -44,7 +44,10 @@ using namespace TechDrawGui; QGIFace::QGIFace(int ref) : - reference(ref) + reference(ref), + m_fill(Qt::NoBrush) + //m_fill(Qt::CrossPattern) + //m_fill(Qt::Dense3Pattern) { setCacheMode(QGraphicsItem::NoCache); setAcceptHoverEvents(true); @@ -59,7 +62,7 @@ QGIFace::QGIFace(int ref) : m_colPre = fcColor.asValue(); //m_pen.setStyle(Qt::NoPen); - //m_brush.setStyle(m_fill); + m_brush.setStyle(m_fill); setPrettyNormal(); } @@ -112,10 +115,11 @@ void QGIFace::setPrettySel() { void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { QStyleOptionGraphicsItem myOption(*option); - //myOption.state &= ~QStyle::State_Selected; //temp for debugging + //myOption.state &= ~QStyle::State_Selected; //commented for debugging //m_pen.setColor(m_colCurrent); //setPen(m_pen); - //setBrush(m_brush); + //m_brush.setStyle(m_fill); + setBrush(m_brush); QGraphicsPathItem::paint (painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/QGIFace.h b/src/Mod/TechDraw/Gui/QGIFace.h index 5bd9187671..f7677142d8 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.h +++ b/src/Mod/TechDraw/Gui/QGIFace.h @@ -71,6 +71,7 @@ private: QColor m_colNormal; QColor m_colPre; QColor m_colSel; + Qt::BrushStyle m_fill; }; } // namespace MDIViewPageGui diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index cdc850da61..1c07996e27 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -296,15 +296,12 @@ void QGIViewPart::drawViewPart() facePen.setCosmetic(true); //QBrush faceBrush; for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) { - QGIFace* newFace = drawFace(*fit); + QGIFace* newFace = drawFace(*fit,i); newFace->setPen(facePen); newFace->setZValue(ZVALUE::FACE); + newFace->setFlag(QGraphicsItem::ItemIsSelectable, true); //newFace->setBrush(faceBrush); } - //debug a path - //std::stringstream faceId; - //faceId << "facePath" << i; - //_dumpPath(faceId.str().c_str(),facePath); #endif //#if MOD_TECHDRAW_HANDLE_FACES // Draw Hatches @@ -411,7 +408,7 @@ void QGIViewPart::drawViewPart() } } -QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f) +QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx) { std::vector fWires = f->wires; QPainterPath facePath; @@ -430,11 +427,14 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f) } facePath.addPath(wirePath); } - QGIFace* gFace = new QGIFace(-1); + QGIFace* gFace = new QGIFace(idx); addToGroup(gFace); gFace->setPos(0.0,0.0); gFace->setPath(facePath); - //_dumpPath("QGIVP.facePath",facePath); + //debug a path + //std::stringstream faceId; + //faceId << "facePath " << idx; + //_dumpPath(faceId.str().c_str(),facePath); //gFace->setFlag(QGraphicsItem::ItemIsSelectable, true); ??? return gFace; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index bca803f78e..3975543409 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -83,7 +83,7 @@ protected: QPainterPath drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const; std::vector getHatchesForView(TechDraw::DrawViewPart* viewPart); void drawViewPart(); - QGIFace* drawFace(TechDrawGeometry::Face* f); + QGIFace* drawFace(TechDrawGeometry::Face* f, int idx); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.cpp b/src/Mod/TechDraw/Gui/QGIViewSection.cpp index fe167322d1..975b98fb79 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSection.cpp @@ -80,7 +80,7 @@ void QGIViewSection::drawSectionFace() facePen.setCosmetic(true); QBrush faceBrush(QBrush(QColor(0,0,255,40))); //temp. sb preference or property. for(; fit != sectionFaces.end(); fit++) { - QGIFace* newFace = drawFace(*fit); + QGIFace* newFace = drawFace(*fit,-1); newFace->setZValue(ZVALUE::SECTIONFACE); newFace->setBrush(faceBrush); newFace->setPen(facePen);