]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
[bos #29479] Show edges directions
authorAlexey Kondratyev <alexey.kondratyev@opencascade.com>
Wed, 27 Apr 2022 08:51:19 +0000 (11:51 +0300)
committervsv <vsv@opencascade.com>
Wed, 8 Jun 2022 12:03:34 +0000 (15:03 +0300)
Add algorithm to show direction of edges.

16 files changed:
doc/gui/General/Introduction.rst
src/Model/Model_Data.cpp
src/ModelAPI/ModelAPI_Result.cpp
src/ModelAPI/ModelAPI_Result.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_ArrowPrs.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_ArrowPrs.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_ResultPrs.cpp
src/ModuleBase/ModuleBase_ResultPrs.h
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_msg_fr.ts

index b691bdf2afa9b9c0d372d69668d6c04e73acba0b..8da63702fd841157ebb5bb854b4eb6678ad6a264 100644 (file)
@@ -394,6 +394,13 @@ This point of view can be modified using viewer commands: **Panning**, **Zooming
 
    Two view windows
 
+The viewer is able to show direction of edges of objects.
+
+.. figure:: /images/edges_directions.png
+   :align: center
+
+   Showing the edges direction
+
 The description of OCC 3D Viewer architecture and functionality is provided in GUI module user's guide in chapter **OCC 3D Viewer**.
 
 .. _parameter_usage:
index 058b326e6541d944c69dcde72253317f3d0d6642..00e6defd2e6566b00481ceb52d2c24f8ec0abb8e 100644 (file)
@@ -465,7 +465,8 @@ void Model_Data::sendAttributeUpdated(ModelAPI_Attribute* theAttr)
     // trim: need to redisplay or set color in the python script
     if (myObject && (theAttr->attributeType() == "Point2D" || theAttr->id() == "Color" ||
       theAttr->id() == "Transparency" || theAttr->id() == "Deflection" ||
-      theAttr->id() == "Iso_lines" || theAttr->id() == "Show_Iso_lines")) {
+      theAttr->id() == "Iso_lines" || theAttr->id() == "Show_Iso_lines" ||
+      theAttr->id() == "Show_Edges_direction")) {
       static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
       ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
     }
index ec27cbf8216d29b55c4e585ef79dc94995b1237c..a225fe95032bbf12e231d7845927c76b50c86603 100644 (file)
@@ -41,6 +41,8 @@ void ModelAPI_Result::initAttributes()
   aData->addAttribute(ISO_LINES_ID(), ModelAPI_AttributeIntArray::typeId())->setIsArgument(false);
   aData->addAttribute(SHOW_ISO_LINES_ID(), ModelAPI_AttributeBoolean::typeId())->
     setIsArgument(false);
+  aData->addAttribute(SHOW_EDGES_DIRECTION_ID(), ModelAPI_AttributeBoolean::typeId())->
+    setIsArgument(false);
 }
 
 bool ModelAPI_Result::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, const bool theFlag)
index df12ecaf6b5b8f5f01dd3e24d1f2a9e5550597a9..778529c221b0ae2d34b4ec84f7b51af32e138765 100644 (file)
@@ -79,6 +79,14 @@ class ModelAPI_Result : public ModelAPI_Object
     return MY_SHOW_ISO_LINES_ID;
   }
 
+  /// Reference to the transparency of the result.
+  /// The double value is used. The value is in [0, 1] range
+  inline static const std::string& SHOW_EDGES_DIRECTION_ID()
+  {
+    static const std::string MY_SHOW_EDGES_DIRECTION_ID("Show_Edges_direction");
+    return MY_SHOW_EDGES_DIRECTION_ID;
+  }
+
   /// Returns true if the result is concealed from the data tree (referenced by other objects)
   MODELAPI_EXPORT virtual bool isConcealed();
 
index dda65e007eb6440f843479ccee8b2efdbb8d70d8..5c927a6a9df1b4816853ce2a22907f25f3cec728 100644 (file)
@@ -1169,6 +1169,31 @@ bool isShownIsoLines(std::shared_ptr<ModelAPI_Result> theResult)
   return false;
 }
 
+//******************************************************
+void showEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult, bool theShow)
+{
+  if (!theResult.get())
+    return;
+
+  AttributeBooleanPtr aAttr = theResult->data()->boolean(ModelAPI_Result::SHOW_EDGES_DIRECTION_ID());
+  if (aAttr.get() != NULL) {
+    aAttr->setValue(theShow);
+  }
+}
+
+//******************************************************
+bool isShowEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult)
+{
+  if (!theResult.get())
+    return false;
+
+  AttributeBooleanPtr aAttr = theResult->data()->boolean(ModelAPI_Result::SHOW_EDGES_DIRECTION_ID());
+  if (aAttr.get() != NULL) {
+    return aAttr->value();
+  }
+  return false;
+}
+
 //**************************************************************
 void setTransparency(ResultPtr theResult, double theTransparency)
 {
index 6f61423e8e666c5b512c97c26e8164ad8cd0fcc6..1e5ea73806cc3f5edec6036d630fa72d8990d81f 100644 (file)
@@ -304,6 +304,14 @@ MODELAPI_EXPORT void showIsoLines(std::shared_ptr<ModelAPI_Result> theResult, bo
 
 MODELAPI_EXPORT bool isShownIsoLines(std::shared_ptr<ModelAPI_Result> theResult);
 
+/*! Set visibility of edges direction
+* \param[in] theResult a result object
+* \param[in] theShow is a visibility flag
+*/
+MODELAPI_EXPORT void showEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult, bool theShow);
+
+MODELAPI_EXPORT bool isShowEdgesDirection(std::shared_ptr<ModelAPI_Result> theResult);
+
 /*! Returns current transparency in the given result
 * \param theResult a result object
 * \return a transparency value or -1 if it was not defined
index e4161f97b44472f7a0219025dda03d7dfff02e53..84bf06cd3ca2082767f05cc44775958cd211f336 100644 (file)
@@ -65,6 +65,7 @@ SET(PROJECT_HEADERS
   ModuleBase_ParamSpinBox.h
   ModuleBase_Preferences.h
   ModuleBase_ResultPrs.h
+  ModuleBase_ArrowPrs.h
   ModuleBase_SelectionValidator.h
   ModuleBase_ToolBox.h
   ModuleBase_Tools.h
@@ -190,6 +191,7 @@ SET(PROJECT_SOURCES
   ModuleBase_ParamSpinBox.cpp
   ModuleBase_Preferences.cpp
   ModuleBase_ResultPrs.cpp
+  ModuleBase_ArrowPrs.cpp
   ModuleBase_ToolBox.cpp
   ModuleBase_Tools.cpp
   ModuleBase_ViewerFilters.cpp
diff --git a/src/ModuleBase/ModuleBase_ArrowPrs.cpp b/src/ModuleBase/ModuleBase_ArrowPrs.cpp
new file mode 100644 (file)
index 0000000..da02554
--- /dev/null
@@ -0,0 +1,113 @@
+// Copyright (C) 2014-2022  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ModuleBase_ArrowPrs.h"
+
+#include <Prs3d_ArrowAspect.hxx>
+
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Prs3d_Arrow.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopExp.hxx>
+
+
+IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ArrowPrs, AIS_InteractiveContext)
+
+
+ModuleBase_ArrowPrs::ModuleBase_ArrowPrs(const Handle(V3d_Viewer)& theViewer,
+                                         const GeomEdgePtr& theEdge)
+  : AIS_InteractiveContext(theViewer),
+    myEdge(theEdge)
+{
+}
+
+//********************************************************************
+void ModuleBase_ArrowPrs::DrawArrow(const Handle(Prs3d_Presentation)& thePrs,
+                                    Quantity_Color theColor)
+{
+  Handle(Prs3d_Drawer) aDrawer = myDefaultDrawer;
+  Handle(Prs3d_ArrowAspect) anArrowAspect = aDrawer->ArrowAspect();
+
+  Handle(Graphic3d_AspectLine3d) PtA = anArrowAspect->Aspect();
+  PtA->SetColor(theColor);
+
+  Handle(Graphic3d_Group) TheGroup = thePrs->CurrentGroup();
+  TheGroup->SetPrimitivesAspect(PtA);
+
+  TopoDS_Vertex aV1, aV2;
+  TopoDS_Edge anEdgeE = myEdge->impl<TopoDS_Edge>();
+  anEdgeE.Orientation(TopAbs_FORWARD);
+  if (anEdgeE.IsNull()) return;
+
+  TopExp::Vertices(anEdgeE, aV1, aV2);
+  gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
+  gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
+
+  double fp, lp;
+  gp_Vec aDirVec;
+  Handle(Geom_Curve) C = BRep_Tool::Curve(anEdgeE, fp, lp);
+
+  if (C.IsNull()) return;
+
+  if (anEdgeE.Orientation() == TopAbs_FORWARD)
+    C->D1(lp, aP2, aDirVec);
+  else {
+    C->D1(fp, aP1, aDirVec);
+    aP2 = aP1;
+  }
+
+  GeomAdaptor_Curve aAdC;
+  aAdC.Load(C, fp, lp);
+  Standard_Real aDist = GCPnts_AbscissaPoint::Length(aAdC, fp, lp);
+
+  if (aDist > gp::Resolution()) {
+    gp_Dir aDir;
+    if (anEdgeE.Orientation() == TopAbs_FORWARD)
+      aDir = aDirVec;
+    else
+      aDir = -aDirVec;
+
+    TopoDS_Vertex aVertex;
+    BRep_Builder aB;
+    aB.MakeVertex(aVertex, aP2, Precision::Confusion());
+    Prs3d_Arrow::Draw(TheGroup, aP2, aDir, M_PI / 180. * 5., aDist / 10.);
+  }
+}
+
+//********************************************************************
+bool ModuleBase_ArrowPrs::Comparator::operator()(const std::shared_ptr<GeomAPI_Edge>& theEdge1,
+                                                 const std::shared_ptr<GeomAPI_Edge>& theEdge2) const
+{
+  const TopoDS_Edge& aShape1 = theEdge1->impl<TopoDS_Edge>();
+  const TopoDS_Edge& aShape2 = theEdge2->impl<TopoDS_Edge>();
+  bool isLess = aShape1.TShape() < aShape2.TShape();
+  if (aShape1.TShape() == aShape2.TShape()) {
+    Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast());
+    Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast());
+    isLess = aHash1 < aHash2;
+  }
+  return isLess;
+}
diff --git a/src/ModuleBase/ModuleBase_ArrowPrs.h b/src/ModuleBase/ModuleBase_ArrowPrs.h
new file mode 100644 (file)
index 0000000..238bca1
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2014-2022  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef ModuleBase_ArrowPrs_H
+#define ModuleBase_ArrowPrs_H
+
+#include <ModuleBase.h>
+#include <GeomAPI_Edge.h>
+#include <AIS_InteractiveContext.hxx>
+
+#include <map>
+
+DEFINE_STANDARD_HANDLE(ModuleBase_ArrowPrs, AIS_InteractiveContext)
+
+/**
+* \ingroup GUI
+* A presentation class for displaying a direction of edge
+*/
+
+class ModuleBase_ArrowPrs : public AIS_InteractiveContext
+{
+public:
+  /// Constructor
+  /// \param theViewer a viewer which theEdge is displaying.
+  /// \param theEdge an edge whose direction to display.
+  Standard_EXPORT ModuleBase_ArrowPrs(const Handle(V3d_Viewer)& theViewer,
+                                      const GeomEdgePtr& theEdge);
+
+  /// Returns an edge shape
+  GeomEdgePtr Edge() const { return myEdge; }
+
+  /// Draw arrow that represent direction of the edge.
+  Standard_EXPORT void DrawArrow(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor);
+
+  /// \brief Compare addresses of edges
+  class Comparator
+  {
+  public:
+    /// Return \c true if the address of the first edge is less than the address of the second
+    MODULEBASE_EXPORT
+      bool operator ()(const std::shared_ptr<GeomAPI_Edge>& theEdge1,
+                       const std::shared_ptr<GeomAPI_Edge>& theEdge2) const;
+  };
+
+  DEFINE_STANDARD_RTTIEXT(ModuleBase_ArrowPrs, AIS_InteractiveContext)
+
+private:
+
+  /// The edge whose direction to display.
+  GeomEdgePtr myEdge;
+};
+
+typedef std::pair<GeomEdgePtr, Handle(ModuleBase_ArrowPrs)> EdgeDirection;
+typedef std::map<GeomEdgePtr, Handle(ModuleBase_ArrowPrs), ModuleBase_ArrowPrs::Comparator> EdgesDirectionMap;
+
+#endif
\ No newline at end of file
index c9cf044731ea893bac90f50417cca39efabb3bbd..81f55c806dc748ad9ba66cffd6f10a535e1fa300 100644 (file)
@@ -55,6 +55,7 @@
 #include <StdPrs_ShadedShape.hxx>
 #include <StdSelect_BRepSelectionTool.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Builder.hxx>
@@ -296,6 +297,7 @@ void ModuleBase_ResultPrs::Compute(
   // change deviation coefficient to provide more precise circle
   try {
     AIS_Shape::Compute(thePresentationManager, thePresentation, theMode);
+    AddRemoveEdgesDir(GetContext()->CurrentViewer());
   }
   catch (...) {
     return;
@@ -538,3 +540,49 @@ void ModuleBase_ResultPrs::updateIsoLines()
   myUIsoAspect->SetNumber(aIsoValues[0]);
   myVIsoAspect->SetNumber(aIsoValues[1]);
 }
+
+bool ModuleBase_ResultPrs::AddRemoveEdgesDir(const Handle(V3d_Viewer)& theViewer)
+{
+  bool isShow = ModelAPI_Tools::isShowEdgesDirection(myResult);
+  if (isShow) {
+    std::list<GeomShapePtr> aSubEdges = myResult->shape()->subShapes(GeomAPI_Shape::EDGE);
+
+    for (auto anEdgeIter = aSubEdges.begin(); anEdgeIter != aSubEdges.end(); ++anEdgeIter) {
+      GeomEdgePtr anEdgePtr = (*anEdgeIter)->edge();
+      if (myEdgesDirection.find(anEdgePtr) != myEdgesDirection.end()) {
+        myEdgesDirection.at(anEdgePtr)->DrawArrow(Presentation(), Quantity_NOC_BLACK);
+      }
+      else {
+        Handle(ModuleBase_ArrowPrs) anArrowPrs = new ModuleBase_ArrowPrs(theViewer, anEdgePtr);
+        myEdgesDirection.insert(EdgeDirection(anEdgePtr, anArrowPrs));
+        anArrowPrs->DrawArrow(Presentation(), Quantity_NOC_BLACK);
+      }
+    }
+  }
+  else
+    myEdgesDirection.clear();
+
+  GetContext()->UpdateCurrentViewer();
+  return isShow;
+}
+
+Standard_EXPORT void ModuleBase_ResultPrs::UpdateEdgesDir()
+{
+  TopoDS_Shape aSelectedShape = GetContext()->SelectedShape();
+  for (auto anEdgeDir = myEdgesDirection.begin(); anEdgeDir != myEdgesDirection.end(); ++anEdgeDir) {
+    TopoDS_Edge anEdge = anEdgeDir->first->impl<TopoDS_Edge>();
+    bool isSelect = false;
+    TopExp_Explorer Exp(aSelectedShape, TopAbs_EDGE);
+    for (; Exp.More(); Exp.Next()) {
+      if (TopoDS::Edge(Exp.Current()).IsSame(anEdge)) {
+        isSelect = true;
+        break;
+      }
+    }
+    if(isSelect)
+      anEdgeDir->second->DrawArrow(Presentation(), Quantity_NOC_WHITE);
+    else
+      anEdgeDir->second->DrawArrow(Presentation(), Quantity_NOC_BLACK);
+  }
+  GetContext()->UpdateCurrentViewer();
+}
index 5607c2bb08437a54cc6c4e1ee6b24326916a3fd6..5eddec23cb20587e85680376f156d44c86701a9b 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "ModuleBase.h"
 
+#include "ModuleBase_ArrowPrs.h"
+
 #include <ModelAPI_Result.h>
 #include <ModelAPI_ResultField.h>
 
@@ -121,6 +123,10 @@ public:
 
   Standard_EXPORT void updateIsoLines();
 
+  Standard_EXPORT bool AddRemoveEdgesDir(const Handle(V3d_Viewer)& theViewer);
+
+  Standard_EXPORT void UpdateEdgesDir();
+
   DEFINE_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape)
 
 protected:
@@ -178,6 +184,9 @@ private:
 
   Handle(Prs3d_IsoAspect) myUIsoAspect;
   Handle(Prs3d_IsoAspect) myVIsoAspect;
+
+
+  EdgesDirectionMap myEdgesDirection;
 };
 
 
index 64c590e661fc64b39e633776b80aac65d9be18ec..97e58c22f5b2ee694df83e66124d1bcaf6d89122 100644 (file)
@@ -161,6 +161,10 @@ void XGUI_ContextMenuMgr::createActions()
                                            aDesktop);
   addAction("ISOLINES_CMD", anAction);
 
+  anAction = ModuleBase_Tools::createAction(QIcon(), tr("Show edges direction"), aDesktop);
+  anAction->setCheckable(true);
+  addAction("SHOW_EDGES_DIRECTION_CMD", anAction);
+
   anAction = ModuleBase_Tools::createAction(QIcon(), tr("Show Isos"), aDesktop);
   anAction->setCheckable(true);
   addAction("SHOW_ISOLINES_CMD", anAction);
@@ -340,6 +344,8 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
             action("WIREFRAME_CMD")->setEnabled(true);
             action("SHADING_CMD")->setEnabled(true);
           }
+          action("SHOW_EDGES_DIRECTION_CMD")->setEnabled(true);
+          action("SHOW_EDGES_DIRECTION_CMD")->setChecked(ModelAPI_Tools::isShowEdgesDirection(aResult));
           action("SHOW_ISOLINES_CMD")->setEnabled(true);
           action("SHOW_ISOLINES_CMD")->setChecked(ModelAPI_Tools::isShownIsoLines(aResult));
           action("ISOLINES_CMD")->setEnabled(true);
@@ -396,6 +402,7 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
         action("SHOW_ONLY_CMD")->setEnabled(true);
         action("SHADING_CMD")->setEnabled(true);
         action("WIREFRAME_CMD")->setEnabled(true);
+        action("SHOW_EDGES_DIRECTION_CMD")->setEnabled(true);
         action("SHOW_ISOLINES_CMD")->setEnabled(true);
         action("ISOLINES_CMD")->setEnabled(true);
       }
@@ -588,6 +595,9 @@ void XGUI_ContextMenuMgr::updateViewerMenu()
         if (aPrsList.size() == 1) {
           ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
           if (aResult.get()) {
+            action("SHOW_EDGES_DIRECTION_CMD")->setEnabled(true);
+            action("SHOW_EDGES_DIRECTION_CMD")->setChecked(
+                ModelAPI_Tools::isShowEdgesDirection(aResult));
             action("SHOW_ISOLINES_CMD")->setEnabled(true);
             action("SHOW_ISOLINES_CMD")->setChecked(ModelAPI_Tools::isShownIsoLines(aResult));
           }
@@ -696,6 +706,7 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu()
   aList.clear();
   aList.append(action("WIREFRAME_CMD"));
   aList.append(action("SHADING_CMD"));
+  aList.append(action("SHOW_EDGES_DIRECTION_CMD"));
   aList.append(mySeparator1); // this separator is not shown as this action is added after show only
   // qt list container contains only one instance of the same action
   aList.append(action("SHOW_CMD"));
@@ -801,6 +812,7 @@ void XGUI_ContextMenuMgr::buildViewerMenu()
   aList.clear();
   aList.append(action("WIREFRAME_CMD"));
   aList.append(action("SHADING_CMD"));
+  aList.append(action("SHOW_EDGES_DIRECTION_CMD"));
   aList.append(mySeparator2);
   aList.append(action("COLOR_CMD"));
   aList.append(action("DEFLECTION_CMD"));
@@ -845,6 +857,7 @@ void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const
   } else if (aSelected > 1) {
       anActions.append(action("WIREFRAME_CMD"));
       anActions.append(action("SHADING_CMD"));
+      anActions.append(action("SHOW_EDGES_DIRECTION_CMD"));
       anActions.append(mySeparator1);
       anActions.append(action("SHOW_CMD"));
       anActions.append(action("HIDE_CMD"));
index b9be6db91d79f0761591c15155c0553c28f23ff2..87bc8aae261f12d55dcd216327f304198758ee61 100644 (file)
@@ -327,8 +327,10 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer)
 
       // Set Iso-Lines
       Handle(ModuleBase_ResultPrs) aResPrs = Handle(ModuleBase_ResultPrs)::DownCast(aAISIO);
-      if (!aResPrs.IsNull())
+      if (!aResPrs.IsNull()) {
         aResPrs->updateIsoLines();
+        aResPrs->AddRemoveEdgesDir(AISContext()->CurrentViewer());
+      }
     }
     //myWorkshop->module()->storeSelection();
 
index 5eb5498fad36110fe75a6b47478c22432098a69c..af8a65e4868c2b546d000ee1dcfc781046623bfc 100644 (file)
@@ -72,6 +72,17 @@ QList<ModuleBase_ViewerPrsPtr> XGUI_Selection::getSelected(const SelectionPlace&
   QList<ModuleBase_ViewerPrsPtr> aPresentations;
   QList<ModuleBase_ViewerPrsPtr> aToRemove;
 
+  Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+  if (!aContext.IsNull()) {
+    AIS_ListOfInteractive aListOfObjects;
+    aContext->DisplayedObjects(aListOfObjects);
+    for (auto anObject = aListOfObjects.begin(); anObject != aListOfObjects.end(); ++anObject) {
+      Handle(ModuleBase_ResultPrs) aResPrs = Handle(ModuleBase_ResultPrs)::DownCast(*anObject);
+      if(aResPrs.get())
+        aResPrs->UpdateEdgesDir();
+    }
+  }
+
   switch (thePlace) {
     case Browser:
       getSelectedInBrowser(aPresentations);
@@ -173,7 +184,10 @@ void XGUI_Selection::getSelectedInViewer(QList<ModuleBase_ViewerPrsPtr>& thePres
       aSelectedIds.append((size_t)anOwner.get());
 
       fillPresentation(aPrs, anOwner);
-
+      AISObjectPtr anAISObject = myWorkshop->displayer()->getAISObject(aPrs->object());
+      Handle(ModuleBase_ResultPrs) aResPrs = Handle(ModuleBase_ResultPrs)::DownCast(anAISObject->
+                                                                 impl<Handle(AIS_InteractiveObject)>());
+      aResPrs->UpdateEdgesDir();
       if (!thePresentations.contains(aPrs)) // TODO: check whether the presentation in a list
         thePresentations.append(aPrs);
     }
index 624f6442233e1efdc94170689afdc72cac4ad8e9..69428360133977f603ae3de16d65b5ac8979318b 100644 (file)
@@ -1866,6 +1866,15 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
   } else if (theId == "SET_VIEW_INVERTEDNORMAL_CMD") {
     setNormalView(true);
   }
+  else if (theId == "SHOW_EDGES_DIRECTION_CMD") {
+    foreach(ObjectPtr aObj, anObjects) {
+      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+      if (aResult.get())
+        ModelAPI_Tools::showEdgesDirection(aResult, !ModelAPI_Tools::isShowEdgesDirection(aResult));
+    }
+    mySelector->clearSelection();
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  }
 #ifdef TINSPECTOR
   else if (theId == "TINSPECTOR_VIEW") {
     std::shared_ptr<Model_Session> aSession =
index 2e320d15e2cee60c25fb8f756b8b528691075744..1d7ec9610c93c7bed18390317a63cdd62a0d928b 100644 (file)
       <source>Recover</source>
       <translation>Récupérer</translation>
     </message>
+    <message>
+        <source>Show edges direction</source>
+        <translation>Afficher la direction des bords</translation>
+    </message>
 </context>
 <context>
     <name>XGUI_DataTree</name>