From 1f0a92458ca8823dfcf689a6de97828b98c1e561 Mon Sep 17 00:00:00 2001 From: vsv Date: Thu, 20 Jun 2019 17:54:56 +0300 Subject: [PATCH] Issue #2922: Set viewer normally to selected face --- src/XGUI/XGUI_ContextMenuMgr.cpp | 51 ++++++++++++++------- src/XGUI/XGUI_Workshop.cpp | 40 ++++++++++++++++ src/XGUI/XGUI_Workshop.h | 4 ++ src/XGUI/XGUI_pictures.qrc | 2 + src/XGUI/pictures/normal-view-inversed.png | Bin 0 -> 335 bytes src/XGUI/pictures/normal-view.png | Bin 0 -> 341 bytes 6 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/XGUI/pictures/normal-view-inversed.png create mode 100644 src/XGUI/pictures/normal-view.png diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index c48b8a8ef..55006b428 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -144,32 +144,25 @@ void XGUI_ContextMenuMgr::createActions() mySeparator3 = ModuleBase_Tools::createAction(QIcon(), "", aDesktop); mySeparator3->setSeparator(true); - //mySelectActions = new QActionGroup(this); - //mySelectActions->setExclusive(true); - aAction = ModuleBase_Tools::createAction(QIcon(":pictures/vertex.png"), tr("Vertices"), aDesktop, this, SLOT(onShapeSelection(bool))); aAction->setCheckable(true); addAction("SELECT_VERTEX_CMD", aAction); - //mySelectActions->addAction(aAction); aAction = ModuleBase_Tools::createAction(QIcon(":pictures/edge.png"), tr("Edges"), aDesktop, this, SLOT(onShapeSelection(bool))); aAction->setCheckable(true); addAction("SELECT_EDGE_CMD", aAction); - //mySelectActions->addAction(aAction); aAction = ModuleBase_Tools::createAction(QIcon(":pictures/face.png"), tr("Faces"), aDesktop, this, SLOT(onShapeSelection(bool))); aAction->setCheckable(true); addAction("SELECT_FACE_CMD", aAction); - //mySelectActions->addAction(aAction); aAction = ModuleBase_Tools::createAction(QIcon(":pictures/result.png"), tr("Results"), aDesktop, this, SLOT(onResultSelection(bool))); aAction->setCheckable(true); addAction("SELECT_RESULT_CMD", aAction); - //mySelectActions->addAction(aAction); aAction->setChecked(true); @@ -207,6 +200,14 @@ void XGUI_ContextMenuMgr::createActions() tr("Move out after the folder"), aDesktop); addAction("ADD_OUT_FOLDER_AFTER_CMD", aAction); + aAction = ModuleBase_Tools::createAction(QIcon(":pictures/normal-view-inversed.png"), + tr("Set view by inverted normal to face"), aDesktop); + addAction("SET_VIEW_INVERTEDNORMAL_CMD", aAction); + + aAction = ModuleBase_Tools::createAction(QIcon(":pictures/normal-view.png"), + tr("Set view by normal to face"), aDesktop); + addAction("SET_VIEW_NORMAL_CMD", aAction); + buildObjBrowserMenu(); buildViewerMenu(); } @@ -500,16 +501,22 @@ void XGUI_ContextMenuMgr::updateViewerMenu() bool isVisible = false; bool isShading = false; bool canBeShaded = false; + bool hasPlanar = false; ObjectPtr aObject; foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) { aObject = aPrs->object(); + GeomShapePtr aShape = aPrs->shape(); ResultPtr aRes = std::dynamic_pointer_cast(aObject); if (aRes && aRes->isDisplayed()) { isVisible = true; canBeShaded = myWorkshop->displayer()->canBeShaded(aObject); isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading); - break; + } + if (aShape.get()) { + if (aShape->isPlanar()) { + hasPlanar = true; + } } } if (isVisible) { @@ -527,6 +534,9 @@ void XGUI_ContextMenuMgr::updateViewerMenu() action("HIDE_CMD")->setEnabled(true); } else action("SHOW_CMD")->setEnabled(true); + + action("SET_VIEW_NORMAL_CMD")->setEnabled(hasPlanar); + action("SET_VIEW_INVERTEDNORMAL_CMD")->setEnabled(hasPlanar); } //issue #2159 Hide all incomplete behavior #ifdef HAVE_SALOME @@ -679,12 +689,15 @@ void XGUI_ContextMenuMgr::buildViewerMenu() { QActionsList aList; // Result construction menu - aList.append(action("HIDE_CMD")); - aList.append(action("SHOW_ONLY_CMD")); - aList.append(mySeparator1); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); aList.append(action("TRANSPARENCY_CMD")); + aList.append(mySeparator3); + aList.append(action("SET_VIEW_NORMAL_CMD")); + aList.append(action("SET_VIEW_INVERTEDNORMAL_CMD")); + aList.append(mySeparator1); + aList.append(action("SHOW_ONLY_CMD")); + aList.append(action("HIDE_CMD")); myViewerMenu[ModelAPI_ResultConstruction::group()] = aList; // Result part menu myViewerMenu[ModelAPI_ResultPart::group()] = aList; @@ -693,13 +706,16 @@ void XGUI_ContextMenuMgr::buildViewerMenu() aList.clear(); aList.append(action("WIREFRAME_CMD")); aList.append(action("SHADING_CMD")); - aList.append(mySeparator1); - aList.append(action("HIDE_CMD")); - aList.append(action("SHOW_ONLY_CMD")); aList.append(mySeparator2); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); aList.append(action("TRANSPARENCY_CMD")); + aList.append(mySeparator3); + aList.append(action("SET_VIEW_NORMAL_CMD")); + aList.append(action("SET_VIEW_INVERTEDNORMAL_CMD")); + aList.append(mySeparator1); + aList.append(action("SHOW_ONLY_CMD")); + aList.append(action("HIDE_CMD")); myViewerMenu[ModelAPI_ResultBody::group()] = aList; // Group menu myViewerMenu[ModelAPI_ResultGroup::group()] = aList; @@ -790,14 +806,15 @@ void XGUI_ContextMenuMgr::addViewerMenu(QMenu* theMenu) const aActions = myViewerMenu[aName]; } } else if (aSelected > 1) { + aActions.append(action("COLOR_CMD")); + aActions.append(action("DEFLECTION_CMD")); + aActions.append(action("TRANSPARENCY_CMD")); + aActions.append(mySeparator1); aActions.append(action("SHOW_ONLY_CMD")); aActions.append(action("HIDE_CMD")); } // hide all is shown always even if selection in the viewer is empty aActions.append(action("HIDEALL_CMD")); - aActions.append(action("COLOR_CMD")); - aActions.append(action("DEFLECTION_CMD")); - aActions.append(action("TRANSPARENCY_CMD")); theMenu->addActions(aActions); QMap aMenuActions; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 6a3e37035..1f5794a97 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -86,6 +86,8 @@ #include #include +#include + #include #include #include @@ -1630,6 +1632,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) highlightResults(aObjects); } else if (theId == "SHOW_FEATURE_CMD") { highlightFeature(aObjects); + } else if (theId == "SET_VIEW_NORMAL_CMD") { + setNormalView(); + } else if (theId == "SET_VIEW_INVERTEDNORMAL_CMD") { + setNormalView(true); } #ifdef TINSPECTOR else if (theId == "TINSPECTOR_VIEW") { @@ -2533,6 +2539,40 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) myObjectBrowser->updateAllIndexes(); } +//************************************************************** +void XGUI_Workshop::setNormalView(bool toInvert) +{ + QList aPrsList = + mySelector->selection()->getSelected(ModuleBase_ISelection::Viewer); + GeomShapePtr aPlanarFace; + foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) { + GeomShapePtr aShape = aPrs->shape(); + if (aShape.get() && aShape->isPlanar()) { + aPlanarFace = aShape; + break; + } + } + if (aPlanarFace.get()) { + GeomFacePtr aFace(new GeomAPI_Face(aPlanarFace)); + GeomPlanePtr aPlane = aFace->getPlane(); + GeomDirPtr aNormal = aPlane->direction(); + if (toInvert) + aNormal->reverse(); + GeomPointPtr aPos = aPlane->location(); + + double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + aFace->computeSize(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + + Handle(V3d_View) aView = myViewerProxy->activeView(); + double aScale = aView->Scale(); + aView->SetAt(aPos->x(), aPos->y(), aPos->z()); + aView->SetProj(aNormal->x(), aNormal->y(), aNormal->z()); + Bnd_Box aBox; + aBox.Update(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + aView->FitAll(aBox); + } +} + //************************************************************** void XGUI_Workshop::registerValidators() const { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 525d99ae9..50f266eee 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -516,6 +516,10 @@ private: /// Clear content of temporary directory void clearTemporaryDir(); + /// Set current point of view normal to selected planar face + /// \param toInvert invert the normal vector + void setNormalView(bool toInvert = false); + private: #ifndef HAVE_SALOME AppElements_MainWindow* myMainWindow; ///< desktop window diff --git a/src/XGUI/XGUI_pictures.qrc b/src/XGUI/XGUI_pictures.qrc index 4520529f1..2e0880496 100644 --- a/src/XGUI/XGUI_pictures.qrc +++ b/src/XGUI/XGUI_pictures.qrc @@ -84,5 +84,7 @@ pictures/arrow-down.png pictures/configure_toolbars.png pictures/color.png + pictures/normal-view-inversed.png + pictures/normal-view.png diff --git a/src/XGUI/pictures/normal-view-inversed.png b/src/XGUI/pictures/normal-view-inversed.png new file mode 100644 index 0000000000000000000000000000000000000000..078ec14b1aa9b6539acee7bf533eb07180e41e00 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=fts&@Fyn;$$~izmi4xa{lHmNblJdl&REC1Y%)Ao4ywnl}6Foyc zv%h|vFMw(ec)B=-SokMPu!gWL(rYwZw61aCjSV}z9i-IwzO-khCI}RNEEg~4{K0$V zzvqGb2WF|t)NXB@!yj};9O9TF8Dn|U}~F-_pR5Gi{? zLZ$DFcq!Khmae~yiGtG=^4ScpH!N0gb@;=4;+<<)&jH5C4WA6cYuHwoe>=})Eq~%C zx0nKBGY?BP8)M+}0~J>$9PM|F{Ua>tK4NA-t{_=_{$v(J#<^Ti3 Yj^_Ry_fNld0s4i()78&qol`;+0BN^$Jpcdz literal 0 HcmV?d00001 diff --git a/src/XGUI/pictures/normal-view.png b/src/XGUI/pictures/normal-view.png new file mode 100644 index 0000000000000000000000000000000000000000..9b39078f476d3e79f34aaf8f9ad21c2966b73021 GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=fts&@Fyn;$$~izmi4xa{lHmNblJdl&REC1Y%)Ao4ywnl}6Foyc zv%h|vFMw)}dAc};SokL^upEhD`sX}z3G;+Bi8ii@d>WT{n7)`gTv5H?cE!{{M6#KO z;o>7b#>^QO7vxuorcB;%9q=)K0-MkW^9^a7?(w+_&zVCCcm>Y898xf}h`(Z)z%*eW zqv-zw3U6gJcv9}LadzxtJHu$Tnpv{>$i$zE{21psY_wOy?}{G>k)j eYa}EjFfc@?PAX8n{;Uw_BL+`bKbLh*2~7YNVRaq= literal 0 HcmV?d00001 -- 2.39.2