From b56912013176d2c47c9412ab4bdfda7a90c0091b Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sat, 29 Sep 2018 20:55:50 -0400 Subject: [PATCH] Add 3Point Angle Dimension --- src/Mod/TechDraw/App/DrawViewDimension.cpp | 55 +- src/Mod/TechDraw/App/DrawViewDimension.h | 3 + src/Mod/TechDraw/Gui/CommandCreateDims.cpp | 118 ++++- src/Mod/TechDraw/Gui/MDIViewPage.cpp | 75 ++- src/Mod/TechDraw/Gui/MDIViewPage.h | 5 +- src/Mod/TechDraw/Gui/QGIViewDimension.cpp | 3 +- src/Mod/TechDraw/Gui/Resources/TechDraw.qrc | 1 + .../icons/TechDraw_Dimension_Angle3Pt.svg | 468 ++++++++++++++++++ src/Mod/TechDraw/Gui/Workbench.cpp | 3 + 9 files changed, 711 insertions(+), 20 deletions(-) create mode 100644 src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_Angle3Pt.svg diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 829208f7f24c..8006d7ac48c8 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -74,6 +74,7 @@ const char* DrawViewDimension::TypeEnums[]= {"Distance", "Radius", "Diameter", "Angle", + "Angle3Pt", NULL}; const char* DrawViewDimension::MeasureTypeEnums[]= {"True", @@ -85,7 +86,8 @@ enum RefType{ oneEdge, twoEdge, twoVertex, - vertexEdge + vertexEdge, + threeVertex }; DrawViewDimension::DrawViewDimension(void) @@ -406,6 +408,32 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void) pts.vertex = apex; m_anglePoints = pts; m_hasGeometry = true; + } else if(Type.isValue("Angle3Pt")){ + if (getRefType() != threeVertex) { + Base::Console().Log("Error: DVD - %s - 2D references are corrupt\n",getNameInDocument()); + return App::DocumentObject::StdReturn; + } + int idx0 = DrawUtil::getIndexFromName(subElements[0]); + int idx1 = DrawUtil::getIndexFromName(subElements[1]); + int idx2 = DrawUtil::getIndexFromName(subElements[2]); + + TechDrawGeometry::Vertex* vert0 = getViewPart()->getProjVertexByIndex(idx0); + TechDrawGeometry::Vertex* vert1 = getViewPart()->getProjVertexByIndex(idx1); + TechDrawGeometry::Vertex* vert2 = getViewPart()->getProjVertexByIndex(idx2); + if (!vert0 || !vert1 || !vert2) { + Base::Console().Log("Error: DVD - %s - 2D references are corrupt\n",getNameInDocument()); + return App::DocumentObject::StdReturn; + } + + anglePoints pts; + Base::Vector3d apex = vert1->getAs3D(); + Base::Vector3d extPoint0 = vert0->getAs3D(); + Base::Vector3d extPoint2 = vert2->getAs3D(); + pts.ends.first = extPoint0; + pts.ends.second = extPoint2; + pts.vertex = apex; + m_anglePoints = pts; + m_hasGeometry = true; } //TODO: if MeasureType = Projected and the Projected shape changes, the Dimension may become invalid (see tilted Cube example) @@ -559,6 +587,14 @@ double DrawViewDimension::getDimValue() Base::Vector3d leg1 = pts.ends.second - vertex; double legAngle = leg0.GetAngle(leg1) * 180.0 / M_PI; result = legAngle; + + } else if(Type.isValue("Angle3Pt")){ //same as case "Angle"? + anglePoints pts = m_anglePoints; + Base::Vector3d vertex = pts.vertex; + Base::Vector3d leg0 = pts.ends.first - vertex; + Base::Vector3d leg1 = pts.ends.second - vertex; + double legAngle = leg0.GetAngle(leg1) * 180.0 / M_PI; + result = legAngle; } } return result; @@ -662,6 +698,8 @@ int DrawViewDimension::getRefType() const refType = getRefType1(subElements[0]); } else if (subElements.size() == 2) { refType = getRefType2(subElements[0],subElements[1]); + } else if (subElements.size() == 3) { + refType = getRefType3(subElements[0],subElements[1],subElements[2]); } return refType; } @@ -697,6 +735,21 @@ int DrawViewDimension::getRefType2(const std::string g1, const std::string g2) return refType; } +int DrawViewDimension::getRefType3(const std::string g1, + const std::string g2, + const std::string g3) +{ + int refType = invalidRef; + if ((DrawUtil::getGeomTypeFromName(g1) == "Vertex") && + (DrawUtil::getGeomTypeFromName(g2) == "Vertex") && + (DrawUtil::getGeomTypeFromName(g3) == "Vertex") ) { + refType = threeVertex; + } + + return refType; +} + + //! validate 2D references - only checks if they exist, not if they are the right type bool DrawViewDimension::checkReferences2D() const { diff --git a/src/Mod/TechDraw/App/DrawViewDimension.h b/src/Mod/TechDraw/App/DrawViewDimension.h index ccb00f13f708..f13d156d6035 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.h +++ b/src/Mod/TechDraw/App/DrawViewDimension.h @@ -126,6 +126,9 @@ class TechDrawExport DrawViewDimension : public TechDraw::DrawView virtual QRectF getRect() const { return QRectF(0,0,1,1);} //pretend dimensions always fit! static int getRefType1(const std::string s); static int getRefType2(const std::string s1, const std::string s2); + static int getRefType3(const std::string g1, + const std::string g2, + const std::string g3); int getRefType() const; //Vertex-Vertex, Edge, Edge-Edge void setAll3DMeasurement(); void clear3DMeasurements(void); diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 462bc045ea14..7d2778d3eadb 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -78,7 +78,8 @@ enum EdgeType{ isEllipse, isBSplineCircle, isBSpline, - isAngle + isAngle, + isAngle3Pt }; @@ -92,7 +93,7 @@ bool _checkSelection(Gui::Command* cmd, unsigned maxObjs = 2); bool _checkDrawViewPart(Gui::Command* cmd); bool _checkPartFeature(Gui::Command* cmd); int _isValidSingleEdge(Gui::Command* cmd); -bool _isValidVertexes(Gui::Command* cmd); +bool _isValidVertexes(Gui::Command* cmd, int count = 2); int _isValidEdgeToEdge(Gui::Command* cmd); bool _isValidVertexToEdge(Gui::Command* cmd); char* _edgeTypeToText(int e); @@ -856,6 +857,96 @@ bool CmdTechDrawNewAngleDimension::isActive(void) return (havePage && haveView); } +//=========================================================================== +// TechDraw_NewAngle3PtDimension +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawNewAngle3PtDimension); + +CmdTechDrawNewAngle3PtDimension::CmdTechDrawNewAngle3PtDimension() + : Command("TechDraw_NewAngle3PtDimension") +{ + sAppModule = "TechDraw"; + sGroup = QT_TR_NOOP("TechDraw"); + sMenuText = QT_TR_NOOP("Insert a new 3 point Angle dimension"); + sToolTipText = QT_TR_NOOP("Insert a new 3 point Angle dimension"); + sWhatsThis = "TechDraw_Dimension_Angle3Pt"; + sStatusTip = sToolTipText; + sPixmap = "TechDraw_Dimension_Angle3Pt"; +} + +void CmdTechDrawNewAngle3PtDimension::activated(int iMsg) +{ + Q_UNUSED(iMsg); + bool result = _checkSelection(this,3); + if (!result) + return; + result = _checkDrawViewPart(this); + if (!result) + return; + + std::vector selection = getSelection().getSelectionEx(); + TechDraw::DrawViewPart * objFeat = 0; + std::vector SubNames; + + std::vector::iterator itSel = selection.begin(); + for (; itSel != selection.end(); itSel++) { + if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) { + objFeat = static_cast ((*itSel).getObject()); + SubNames = (*itSel).getSubNames(); + } + } + TechDraw::DrawPage* page = objFeat->findParentPage(); + std::string PageName = page->getNameInDocument(); + + TechDraw::DrawViewDimension *dim = 0; + std::string FeatName = getUniqueObjectName("Dimension"); + + std::vector objs; + std::vector subs; + + if (_isValidVertexes(this, 3)) { + objs.push_back(objFeat); + objs.push_back(objFeat); + objs.push_back(objFeat); + subs.push_back(SubNames[0]); + subs.push_back(SubNames[1]); + subs.push_back(SubNames[2]); + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), + QObject::tr("Need three points to make an 3 point Angle Dimension")); + return; + } + + openCommand("Create Dimension"); + doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str() + ,"Angle3Pt"); + + dim = dynamic_cast(getDocument()->getObject(FeatName.c_str())); + if (!dim) { + throw Base::Exception("CmdTechDrawNewAngle3PtDimension - dim not found\n"); + } + dim->References2D.setValues(objs, subs); + + doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + + commitCommand(); + dim->recomputeFeature(); + + //Horrible hack to force Tree update + double x = objFeat->X.getValue(); + objFeat->X.setValue(x); +} + +bool CmdTechDrawNewAngle3PtDimension::isActive(void) +{ + bool havePage = DrawGuiUtil::needPage(this); + bool haveView = DrawGuiUtil::needView(this); + return (havePage && haveView); +} + + //! link 3D geometry to Dimension(s) on a Page //TODO: should we present all potential Dimensions from all Pages? //=========================================================================== @@ -948,6 +1039,7 @@ void CreateTechDrawCommandsDims(void) rcCmdMgr.addCommand(new CmdTechDrawNewDistanceXDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewDistanceYDimension()); rcCmdMgr.addCommand(new CmdTechDrawNewAngleDimension()); + rcCmdMgr.addCommand(new CmdTechDrawNewAngle3PtDimension()); rcCmdMgr.addCommand(new CmdTechDrawLinkDimension()); } @@ -1063,17 +1155,22 @@ int _isValidSingleEdge(Gui::Command* cmd) { return edgeType; } -//! verify that Selection contains valid geometries for a Vertex to Vertex Dimension -bool _isValidVertexes(Gui::Command* cmd) { +//! verify that Selection contains valid geometries for a Vertex based Dimensions +bool _isValidVertexes(Gui::Command* cmd, int count) { std::vector selection = cmd->getSelection().getSelectionEx(); const std::vector SubNames = selection[0].getSubNames(); - if(SubNames.size() == 2) { //there are 2 - if (TechDraw::DrawUtil::getGeomTypeFromName(SubNames[0]) == "Vertex" && //they both start with "Vertex" - TechDraw::DrawUtil::getGeomTypeFromName(SubNames[1]) == "Vertex") { - return true; + bool isValid = true; + if(SubNames.size() == (unsigned) count) { + for (auto& s: SubNames) { + if (TechDraw::DrawUtil::getGeomTypeFromName(s) != "Vertex") { + isValid = false; + break; + } } + } else { + isValid = false; } - return false; + return isValid; } //! verify that the Selection contains valid geometries for an Edge to Edge Dimension @@ -1198,6 +1295,9 @@ char* _edgeTypeToText(int e) case isAngle: result = "angle"; break; + case isAngle3Pt: + result = "angle3"; + break; default: result = "unknown"; } diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 6e1720d7f73c..04ecf443ab36 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -235,6 +235,7 @@ void MDIViewPage::closeEvent(QCloseEvent* ev) if (!ev->isAccepted()) return; detachSelection(); + blockSelection(true); // when closing the view from GUI notify the view provider to mark it invisible if (_pcDocument && !m_objectName.empty()) { @@ -246,6 +247,7 @@ void MDIViewPage::closeEvent(QCloseEvent* ev) vp->hide(); } } + blockSelection(false); } @@ -716,6 +718,8 @@ void MDIViewPage::print(QPrinter* printer) // Reset m_view->toggleMarkers(true); + //bool block = + static_cast (blockConnection(false)); } @@ -904,7 +908,7 @@ void MDIViewPage::preSelectionChanged(const QPoint &pos) //flag to prevent selection activity within mdivp void MDIViewPage::blockSelection(const bool state) { - isSelectionBlocked = state; + isSelectionBlocked = state; } @@ -912,6 +916,8 @@ void MDIViewPage::blockSelection(const bool state) void MDIViewPage::clearSceneSelection() { blockSelection(true); + m_sceneSelected.clear(); + std::vector views = m_view->getViews(); // Iterate through all views and unselect all @@ -970,17 +976,67 @@ void MDIViewPage::onSelectionChanged(const Gui::SelectionChanges& msg) } } +//! maintain QGScene selected items in selection order +void MDIViewPage::sceneSelectionManager() +{ + QList sceneSel = m_view->scene()->selectedItems(); + + if (sceneSel.isEmpty()) { + m_sceneSelected.clear(); //TODO: need to signal somebody? Tree? handled elsewhere + //clearSelection + return; + } + + if (m_sceneSelected.isEmpty() && + !sceneSel.isEmpty()) { + m_sceneSelected.push_back(sceneSel.front()); + return; + } + + //add to m_sceneSelected anything that is in q_sceneSel + for (auto qts: sceneSel) { + bool found = false; + for (auto ms: m_sceneSelected) { + if ( qts == ms ) { + found = true; + break; + } + } + if (!found) { + m_sceneSelected.push_back(qts); + break; + } + } + + //remove items from m_sceneSelected that are not in q_sceneSel + QList m_new; + for (auto m: m_sceneSelected) { + for (auto q: sceneSel) { + if (m == q) { + m_new.push_back(m); + break; + } + } + } + m_sceneSelected = m_new; +} + //! update Tree Selection from QGraphicsScene selection //triggered by m_view->scene() signal void MDIViewPage::sceneSelectionChanged() { + sceneSelectionManager(); + + QList dbsceneSel = m_view->scene()->selectedItems(); + if(isSelectionBlocked) { return; } std::vector treeSel = Gui::Selection().getSelectionEx(); - QList sceneSel = m_view->scene()->selectedItems(); - +// QList sceneSel = m_view->scene()->selectedItems(); + QList sceneSel = m_sceneSelected; + //check if really need to change selection bool sameSel = compareSelections(treeSel,sceneSel); if (sameSel) { @@ -990,12 +1046,14 @@ void MDIViewPage::sceneSelectionChanged() setTreeToSceneSelect(); } +//Note: no guarantee of selection order??? void MDIViewPage::setTreeToSceneSelect(void) { bool saveBlock = blockConnection(true); // block selectionChanged signal from Tree/Observer blockSelection(true); Gui::Selection().clearSelection(); - QList sceneSel = m_view->scene()->selectedItems(); +// QList sceneSel = m_view->scene()->selectedItems(); //"no particular order"!!! + QList sceneSel = m_sceneSelected; for (QList::iterator it = sceneSel.begin(); it != sceneSel.end(); ++it) { QGIView *itemView = dynamic_cast(*it); if(itemView == 0) { @@ -1037,6 +1095,7 @@ void MDIViewPage::setTreeToSceneSelect(void) std::stringstream ss; ss << "Vertex" << vert->getProjIndex(); + ss.str().c_str(); //bool accepted = static_cast (Gui::Selection().addSelection(viewObj->getDocument()->getName(), viewObj->getNameInDocument(), @@ -1113,7 +1172,7 @@ void MDIViewPage::setTreeToSceneSelect(void) blockConnection(saveBlock); } -bool MDIViewPage::compareSelections(std::vector& treeSel,QList& sceneSel) +bool MDIViewPage::compareSelections(std::vector treeSel, QList sceneSel) { bool result = true; @@ -1132,7 +1191,7 @@ bool MDIViewPage::compareSelections(std::vector& treeSel,Q std::vector treeNames; std::vector sceneNames; - for (auto& tn: treeSel) { + for (auto tn: treeSel) { if (tn.getObject()->isDerivedFrom(TechDraw::DrawView::getClassTypeId())) { int treeSubs = tn.getSubNames().size(); subCount += treeSubs; @@ -1143,8 +1202,8 @@ bool MDIViewPage::compareSelections(std::vector& treeSel,Q std::sort(treeNames.begin(),treeNames.end()); treeCount = treeNames.size(); - for (auto& sn:sceneSel){ - QGIView *itemView = dynamic_cast(sn); + for (auto sn:sceneSel){ + QGIView *itemView = dynamic_cast(sn); //<<<<< if(itemView == 0) { QGIPrimPath* pp = dynamic_cast(sn); //count Vertex/Edge/Face if (pp != nullptr) { diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.h b/src/Mod/TechDraw/Gui/MDIViewPage.h index 4baa422bf670..8be30abbec27 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.h +++ b/src/Mod/TechDraw/Gui/MDIViewPage.h @@ -124,8 +124,10 @@ public Q_SLOTS: typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection; Connection connectDeletedObject; - bool compareSelections(std::vector& treeSel,QList& sceneSel); + bool compareSelections(std::vector treeSel,QList sceneSel); void setTreeToSceneSelect(void); + void sceneSelectionManager(void); + private: QAction *m_nativeAction; @@ -146,6 +148,7 @@ public Q_SLOTS: bool m_frameState; + QList m_sceneSelected; QList deleteItems; }; diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp index 7c74661f6c13..d8033a79a2b6 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp @@ -1164,7 +1164,8 @@ void QGIViewDimension::draw() // centerMark->show(); // dim->getViewPart()->addVertex(curveCenter,true); // } - } else if(strcmp(dimType, "Angle") == 0) { + } else if( (strcmp(dimType, "Angle") == 0) || + (strcmp(dimType, "Angel3Pt")) ) { // Only use two straight line edeges for angle anglePoints pts = dim->getAnglePoints(); Base::Vector3d X(1.0,0.0,0.0); diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index 5cf68d23702f..f9f6696c24ec 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -25,6 +25,7 @@ icons/TechDraw_ProjTop.svg icons/TechDraw_Dimension.svg icons/TechDraw_Dimension_Angle.svg + icons/TechDraw_Dimension_Angle3Pt.svg icons/TechDraw_Dimension_Diameter.svg icons/TechDraw_Dimension_Horizontal.svg icons/TechDraw_Dimension_Length.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_Angle3Pt.svg b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_Angle3Pt.svg new file mode 100644 index 000000000000..99f991952dae --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_Angle3Pt.svg @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [WandererFan] + + + TechDraw_Dimension_Angle + 2016-04-27 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/TechDraw/Gui/Resources/icons/TechDraw_Dimension_Angle.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 1e2ec261be68..f089cdede996 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -76,6 +76,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const *draw << "TechDraw_NewRadiusDimension"; *draw << "TechDraw_NewDiameterDimension"; *draw << "TechDraw_NewAngleDimension"; + *draw << "TechDraw_NewAngle3PtDimension"; *draw << "TechDraw_LinkDimension"; *draw << "Separator"; *draw << "TechDraw_ExportPage"; @@ -125,6 +126,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *dims << "TechDraw_NewRadiusDimension"; *dims << "TechDraw_NewDiameterDimension"; *dims << "TechDraw_NewAngleDimension"; + *dims << "TechDraw_NewAngle3PtDimension"; *dims << "TechDraw_LinkDimension"; // *dims << "TechDraw_NewDimension" @@ -177,6 +179,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const *dims << "TechDraw_NewRadiusDimension"; *dims << "TechDraw_NewDiameterDimension"; *dims << "TechDraw_NewAngleDimension"; + *dims << "TechDraw_NewAngle3PtDimension"; *dims << "TechDraw_LinkDimension"; // *dims << "TechDraw_NewDimension";