From bca002ff09a73529a505b0e4cc6b13a495c2c8fc Mon Sep 17 00:00:00 2001 From: WandererFan Date: Sat, 11 Jun 2016 20:12:59 -0400 Subject: [PATCH] Hatch View Faces --- src/Mod/TechDraw/App/DrawHatch.cpp | 23 +++++-- src/Mod/TechDraw/App/DrawHatch.h | 8 ++- src/Mod/TechDraw/App/DrawViewPart.cpp | 17 +++++ src/Mod/TechDraw/App/DrawViewPart.h | 4 +- src/Mod/TechDraw/Gui/CommandDecorate.cpp | 31 ++++----- src/Mod/TechDraw/Gui/QGIFace.cpp | 41 +++++++----- src/Mod/TechDraw/Gui/QGIFace.h | 5 ++ src/Mod/TechDraw/Gui/QGIViewPart.cpp | 83 +++++++++++++++++------- src/Mod/TechDraw/Gui/QGIViewPart.h | 5 +- 9 files changed, 142 insertions(+), 75 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawHatch.cpp b/src/Mod/TechDraw/App/DrawHatch.cpp index 3bdd3986c..0bc4ead8c 100644 --- a/src/Mod/TechDraw/App/DrawHatch.cpp +++ b/src/Mod/TechDraw/App/DrawHatch.cpp @@ -52,9 +52,8 @@ DrawHatch::DrawHatch(void) { static const char *vgroup = "Hatch"; - ADD_PROPERTY_TYPE(PartView, (0), vgroup, (App::PropertyType)(App::Prop_None), "Parent view feature"); ADD_PROPERTY_TYPE(DirProjection ,(0,0,1.0) ,vgroup,App::Prop_None,"Projection direction when Hatch was defined"); //sb RO? - ADD_PROPERTY_TYPE(Edges,(0,0),vgroup,(App::PropertyType)(App::Prop_None),"The outline of the hatch area"); + ADD_PROPERTY_TYPE(Source,(0),vgroup,(App::PropertyType)(App::Prop_None),"The View + Face to be hatched"); ADD_PROPERTY_TYPE(HatchPattern ,(""),vgroup,App::Prop_None,"The hatch pattern file for this area"); ADD_PROPERTY_TYPE(HatchColor,(0.0f,0.0f,0.0f),vgroup,App::Prop_None,"The color of the hatch area"); @@ -79,15 +78,14 @@ DrawHatch::~DrawHatch() void DrawHatch::onChanged(const App::Property* prop) { - if (prop == &PartView || - prop == &Edges || + if (prop == &Source || prop == &HatchPattern || prop == &HatchColor) { if (!isRestoring()) { DrawHatch::execute(); - if (PartView.getValue()) { - PartView.getValue()->touch(); - PartView.getValue()->recompute(); + if (getSourceView()) { + getSourceView()->touch(); + getSourceView()->recompute(); } } } @@ -97,9 +95,20 @@ void DrawHatch::onChanged(const App::Property* prop) App::DocumentObjectExecReturn *DrawHatch::execute(void) { //TODO: need to refresh DrawViewPart to reflect change in hatch + DrawViewPart* parent = getSourceView(); + if (parent) { + parent->touch(); + } return App::DocumentObject::StdReturn; } +DrawViewPart* DrawHatch::getSourceView(void) const +{ + App::DocumentObject* obj = Source.getValue(); + DrawViewPart* result = dynamic_cast(obj); + return result; +} + PyObject *DrawHatch::getPyObject(void) { if (PythonObject.is(Py::_None())) { diff --git a/src/Mod/TechDraw/App/DrawHatch.h b/src/Mod/TechDraw/App/DrawHatch.h index 5adef7bfb..721875f75 100644 --- a/src/Mod/TechDraw/App/DrawHatch.h +++ b/src/Mod/TechDraw/App/DrawHatch.h @@ -42,9 +42,8 @@ public: DrawHatch(); virtual ~DrawHatch(); - App::PropertyLink PartView; - App::PropertyVector DirProjection; //edge list is only valid for original projection? - App::PropertyLinkSubList Edges; + App::PropertyVector DirProjection; //Source is only valid for original projection? + App::PropertyLinkSub Source; //the dvp & face this hatch belongs to App::PropertyFile HatchPattern; App::PropertyColor HatchColor; @@ -57,6 +56,9 @@ public: } //return PyObject as DrawHatchPy virtual PyObject *getPyObject(void); + + DrawViewPart* getSourceView(void) const; + protected: void onChanged(const App::Property* prop); diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index a60a061ca..c68a8b093 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -581,6 +581,23 @@ TechDrawGeometry::Vertex* DrawViewPart::getProjVertexByIndex(int idx) const return geoms[idx]; } +//! returns existing geometry of 2D Face(idx) +//version 1 Face has 1 wire +std::vector DrawViewPart::getProjFaceByIndex(int idx) const +{ + std::vector result; + const std::vector& faces = getFaceGeometry(); + for (auto& f:faces) { + for (auto& w:f->wires) { + for (auto& g:w->geoms) { + result.push_back(g); + } + } + } + return result; +} + + Base::BoundBox3d DrawViewPart::getBoundingBox() const { return bbox; diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index df0e3dde0..1bb898a14 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -76,7 +76,7 @@ public: TechDrawGeometry::BaseGeom* getProjEdgeByIndex(int idx) const; //get existing geom for edge idx in projection TechDrawGeometry::Vertex* getProjVertexByIndex(int idx) const; //get existing geom for vertex idx in projection - + std::vector getProjFaceByIndex(int idx) const; //get edges for face idx in projection virtual Base::BoundBox3d getBoundingBox() const; short mustExecute() const; @@ -113,7 +113,7 @@ protected: 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); + int findEdgeByWalkerEdge(WalkerEdge we, std::vector uniqueVert, std::vector& edges); //obs? private: static App::PropertyFloatConstraint::Constraints floatRange; diff --git a/src/Mod/TechDraw/Gui/CommandDecorate.cpp b/src/Mod/TechDraw/Gui/CommandDecorate.cpp index 16e8829ec..99083aba6 100644 --- a/src/Mod/TechDraw/Gui/CommandDecorate.cpp +++ b/src/Mod/TechDraw/Gui/CommandDecorate.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include # include "MDIViewPage.h" @@ -129,38 +130,27 @@ void CmdTechDrawNewHatch::activated(int iMsg) std::vector selection = getSelection().getSelectionEx(); TechDraw::DrawViewPart * objFeat = dynamic_cast(selection[0].getObject()); - const std::vector &SubNames = selection[0].getSubNames(); + const std::vector &subNames = selection[0].getSubNames(); TechDraw::DrawPage* page = objFeat->findParentPage(); std::string PageName = page->getNameInDocument(); TechDraw::DrawHatch *hatch = 0; std::string FeatName = getUniqueObjectName("Hatch"); - std::vector objs; - std::vector subs; - - std::vector::const_iterator itSub = SubNames.begin(); - for (; itSub != SubNames.end(); itSub++) { - objs.push_back(objFeat); - subs.push_back((*itSub)); - } - openCommand("Create Hatch"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawHatch','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.PartView = App.activeDocument().%s",FeatName.c_str(),objFeat->getNameInDocument()); hatch = dynamic_cast(getDocument()->getObject(FeatName.c_str())); - hatch->Edges.setValues(objs, subs); - //should this be: doCommand(Doc,"App..Feat..Edges = [(App...%s,%s),(App..%s,%s),...]",objs[0]->getNameInDocument(),subs[0],...); + hatch->Source.setValue(objFeat, subNames); + //should this be: doCommand(Doc,"App..Feat..Source = [(App...%s,%s),(App..%s,%s),...]",objs[0]->getNameInDocument(),subs[0],...); //seems very unwieldy - //Note: Hatch is not added to the Page Views. DVP::getHatches gathers them via PartView property when needed. Can't remember why! - //doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); commitCommand(); //Horrible hack to force Tree update ??still required?? double x = objFeat->X.getValue(); objFeat->X.setValue(x); + getDocument()->recompute(); } bool CmdTechDrawNewHatch::isActive(void) @@ -248,10 +238,13 @@ bool _checkSelectionHatch(Gui::Command* cmd) { return false; } -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), -// QObject::tr("Can't make a Hatched area from this selection")); -// return false; + const std::vector &SubNames = selection[0].getSubNames(); + std::string gType = TechDraw::DrawUtil::getGeomTypeFromName(SubNames.at(0)); + if (!(gType == "Face")) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), + QObject::tr("Can't make a Hatched area from this selection")); + return false; + } - //TODO: if selection != set of closed edges, return false return true; } diff --git a/src/Mod/TechDraw/Gui/QGIFace.cpp b/src/Mod/TechDraw/Gui/QGIFace.cpp index 98d035da7..35b9526be 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.cpp +++ b/src/Mod/TechDraw/Gui/QGIFace.cpp @@ -67,15 +67,19 @@ QGIFace::QGIFace(int index) : fcColor.setPackedValue(hGrp->GetUnsigned("PreSelectColor", 0x00080800)); m_colPre = fcColor.asValue(); - m_pen.setCosmetic(true); m_pen.setColor(m_colNormal); - m_colNormalFill = m_colDefFill; - m_brush.setColor(m_colDefFill); - m_styleNormal = m_styleDef; - m_brush.setStyle(m_styleDef); + m_brushDef.setColor(m_colDefFill); + m_brushDef.setStyle(m_styleDef); + m_brushNormal = m_brushDef; + m_brushCurrent = m_brushNormal; setPrettyNormal(); + + m_brushPre.setColor(m_colPre); + m_brushPre.setStyle(m_styleSelect); + m_brushSel.setColor(m_colSel); + m_brushSel.setStyle(m_styleSelect); } QVariant QGIFace::itemChange(GraphicsItemChange change, const QVariant &value) @@ -118,22 +122,19 @@ void QGIFace::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) void QGIFace::setPrettyNormal() { m_colCurrent = m_colNormal; - m_colCurrFill = m_colNormalFill; - m_styleCurr = m_styleNormal; + m_brushCurrent = m_brushNormal; update(); } void QGIFace::setPrettyPre() { m_colCurrent = m_colPre; - m_colCurrFill = m_colPre; - m_styleCurr = m_styleSelect; + m_brushCurrent = m_brushPre; update(); } void QGIFace::setPrettySel() { m_colCurrent = m_colSel; - m_colCurrFill = m_colSel; - m_styleCurr = m_styleSelect; + m_brushCurrent = m_brushSel; update(); } @@ -150,21 +151,25 @@ void QGIFace::setHighlighted(bool b) } void QGIFace::setFill(QColor c, Qt::BrushStyle s) { - m_colNormalFill = c; - //m_styleCurr = s; - m_styleNormal = s; + //m_colNormalFill = c; + //m_styleNormal = s; + m_brushNormal.setColor(c); + m_brushNormal.setStyle(s); } void QGIFace::setFill(QBrush b) { m_colNormalFill = b.color(); //m_styleCurr = b.style(); - m_styleNormal = b.style(); + m_brushNormal = b; } void QGIFace::resetFill() { m_colNormalFill = m_colDefFill; //m_styleCurr = m_styleDef; m_styleNormal = m_styleDef; + m_brushNormal.setColor(m_colDefFill); + m_brushNormal.setStyle(m_styleDef); + m_brushCurrent = m_brushNormal; } QRectF QGIFace::boundingRect() const @@ -183,8 +188,8 @@ void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * optio m_pen.setColor(m_colCurrent); setPen(m_pen); - m_brush.setStyle(m_styleCurr); - m_brush.setColor(m_colCurrFill); - setBrush(m_brush); + //m_brush.setStyle(m_styleCurr); + //m_brush.setColor(m_colCurrFill); + setBrush(m_brushCurrent); QGraphicsPathItem::paint (painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/QGIFace.h b/src/Mod/TechDraw/Gui/QGIFace.h index 2bea62b0c..4ba5a4ccf 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.h +++ b/src/Mod/TechDraw/Gui/QGIFace.h @@ -91,6 +91,11 @@ private: Qt::BrushStyle m_styleCurr; //current fill style Qt::BrushStyle m_styleNormal; //Normal fill style Qt::BrushStyle m_styleSelect; //Select/preSelect fill style + QBrush m_brushNormal; + QBrush m_brushPre; + QBrush m_brushSel; + QBrush m_brushDef; + QBrush m_brushCurrent; }; } diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 6fb160e1d..56ab770c1 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -38,6 +38,12 @@ #endif // #ifndef _PreComp_ +#include +#include +#include +#include +#include + #include #include #include @@ -300,10 +306,19 @@ void QGIViewPart::drawViewPart() #if MOD_TECHDRAW_HANDLE_FACES // Draw Faces + std::vector hatchObjs = viewPart->getHatches(); const std::vector &faceGeoms = viewPart->getFaceGeometry(); std::vector::const_iterator fit = faceGeoms.begin(); for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) { QGIFace* newFace = drawFace(*fit,i); + TechDraw::DrawHatch* fHatch = faceIsHatched(i,hatchObjs); + if (fHatch) { + if (!fHatch->HatchPattern.isEmpty()) { + QBrush fBrush = brushFromFile(fHatch->HatchPattern.getValue()); + fBrush.setColor(fHatch->HatchColor.getValue().asValue()); + newFace->setFill(fBrush); + } + } newFace->setZValue(ZVALUE::FACE); newFace->setFlag(QGraphicsItem::ItemIsSelectable, true); newFace->setAcceptHoverEvents(true); @@ -311,6 +326,7 @@ void QGIViewPart::drawViewPart() } #endif //#if MOD_TECHDRAW_HANDLE_FACES +#if 0 // Draw Hatches std::vector hatchObjs = viewPart->getHatches(); if (!hatchObjs.empty()) { @@ -318,18 +334,22 @@ void QGIViewPart::drawViewPart() for(; itHatch != hatchObjs.end(); itHatch++) { //if hatchdirection == viewPartdirection { TechDraw::DrawHatch* feat = (*itHatch); - const std::vector &edgeNames = feat->Edges.getSubValues(); - std::vector::const_iterator itEdge = edgeNames.begin(); + const std::vector &sourceNames = feat->Source.getSubValues(); std::vector unChained; - - //get all edge geometries for this hatch - for (; itEdge != edgeNames.end(); itEdge++) { - int idxEdge = TechDraw::DrawUtil::getIndexFromName((*itEdge)); - TechDrawGeometry::BaseGeom* edgeGeom = viewPart->getProjEdgeByIndex(idxEdge); - if (!edgeGeom) { - Base::Console().Log("Error - qgivp::drawViewPart - edgeGeom: %d is NULL\n",idxEdge); + if (TechDraw::DrawUtil::getGeomTypeFromName(sourceNames.at(0)) == "Face") { + int idxFace = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0)); + unChained = viewPart->getProjFaceByIndex(idxFace); + } else { + std::vector::const_iterator itEdge = sourceNames.begin(); + //get all edge geometries for this hatch + for (; itEdge != sourceNames.end(); itEdge++) { + int idxEdge = TechDraw::DrawUtil::getIndexFromName((*itEdge)); + TechDrawGeometry::BaseGeom* edgeGeom = viewPart->getProjEdgeByIndex(idxEdge); + if (!edgeGeom) { + Base::Console().Log("Error - qgivp::drawViewPart - edgeGeom: %d is NULL\n",idxEdge); + } + unChained.push_back(edgeGeom); } - unChained.push_back(edgeGeom); } //chain edges tail to nose into a closed region @@ -360,6 +380,7 @@ void QGIViewPart::drawViewPart() hatch->setZValue(ZVALUE::HATCH); } } +#endif // Draw Edges const std::vector &geoms = viewPart->getEdgeGeometry(); @@ -447,21 +468,6 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx) return gFace; } -std::vector QGIViewPart::getHatchesForView(TechDraw::DrawViewPart* viewPart) -{ - std::vector docObjs = viewPart->getDocument()->getObjectsOfType(TechDraw::DrawHatch::getClassTypeId()); - std::vector hatchObjs; - std::string viewName = viewPart->getNameInDocument(); - std::vector::iterator itDoc = docObjs.begin(); - for(; itDoc != docObjs.end(); itDoc++) { - TechDraw::DrawHatch* hatch = dynamic_cast(*itDoc); - if (viewName.compare((hatch->PartView.getValue())->getNameInDocument()) == 0) { - hatchObjs.push_back(hatch); - } - } - return hatchObjs; -} - // As called by arc of ellipse case: // pathArc(path, geom->major, geom->minor, geom->angle, geom->largeArc, geom->cw, // geom->endPnt.fX, geom->endPnt.fY, @@ -616,6 +622,33 @@ void QGIViewPart::toggleVertices(bool state) } } +QBrush QGIViewPart::brushFromFile(std::string fillSpec) +{ + QBrush result; + QString qs(QString::fromStdString(fillSpec)); + QSvgRenderer renderer(qs); + QBitmap pixMap(renderer.defaultSize()); + pixMap.fill(Qt::white); //try Qt::transparent? + QPainter painter(&pixMap); + renderer.render(&painter); //svg texture -> bitmap + result.setTexture(pixMap); + return result; +} + +TechDraw::DrawHatch* QGIViewPart::faceIsHatched(int i,std::vector hatchObjs) const +{ + TechDraw::DrawHatch* result = nullptr; + for (auto& h:hatchObjs) { + const std::vector &sourceNames = h->Source.getSubValues(); + int fdx = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0)); + if (fdx == i) { + result = h; + break; + } + } + return result; +} + QRectF QGIViewPart::boundingRect() const { //return childrenBoundingRect().adjusted(-2.,-2.,2.,6.); //just a bit bigger than the children need diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index 397554340..21f6f931e 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -81,12 +81,15 @@ protected: double curx, double cury) const; QPainterPath drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const; - std::vector getHatchesForView(TechDraw::DrawViewPart* viewPart); void drawViewPart(); QGIFace* drawFace(TechDrawGeometry::Face* f, int idx); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + //hatching routines + QBrush brushFromFile(std::string fillSpec); + TechDraw::DrawHatch* faceIsHatched(int i,std::vector hatchObjs) const; + QColor m_colHid; private: