Salome HOME
Issue #2927: Show/Hide markers on free points
[modules/shaper.git] / src / PartSet / PartSet_SketcherMgr.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 86d0c59..4092534
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  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
 //
 // 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
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "PartSet_SketcherMgr.h"
+
+#include "PartSet_Filters.h"
 #include "PartSet_SketcherReentrantMgr.h"
 #include "PartSet_Module.h"
 #include "PartSet_MouseProcessor.h"
@@ -34,6 +35,7 @@
 #include <XGUI_Workshop.h>
 #include <XGUI_ContextMenuMgr.h>
 #include <XGUI_Selection.h>
+#include <XGUI_SelectionActivate.h>
 #include <XGUI_SelectionMgr.h>
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_PropertyPanel.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_ResultPrs.h>
+#include <ModuleBase_ViewerFilters.h>
 
 #include <GeomDataAPI_Point2D.h>
 
+#include <GeomAPI_Shape.h>
+
 #include <Events_Loop.h>
 
 #include <SketchPlugin_Line.h>
@@ -85,6 +90,9 @@
 #include <SketchPlugin_MultiTranslation.h>
 #include <SketchPlugin_IntersectionPoint.h>
 #include <SketchPlugin_Projection.h>
+#include <SketchPlugin_ConstraintDistanceAlongDir.h>
+#include <SketchPlugin_ConstraintDistanceHorizontal.h>
+#include <SketchPlugin_ConstraintDistanceVertical.h>
 
 #include <SketcherPrs_Tools.h>
 
@@ -184,14 +192,13 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
 
   mySketchPlane = new PartSet_PreviewSketchPlane();
 
-  myCirclePointFilter = new PartSet_CirclePointFilter(anIWorkshop);
-  myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
+  registerSelectionFilter(SF_SketchCirclePointFilter, new PartSet_CirclePointFilter(anIWorkshop));
+  registerSelectionFilter(SF_SketchPlaneFilter, new ModuleBase_ShapeInPlaneFilter());
 }
 
 PartSet_SketcherMgr::~PartSet_SketcherMgr()
 {
-  myPlaneFilter.Nullify();
-  myCirclePointFilter.Nullify();
+  delete mySketchPlane;
 }
 
 void PartSet_SketcherMgr::onEnterViewPort()
@@ -643,8 +650,10 @@ void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMo
       QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
       // Find corresponded widget to activate value editing
       foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
-        if (aWgt->attributeID() == SketchPlugin_Constraint::VALUE() ||
-            aWgt->attributeID() == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()) {
+        std::string anId = aWgt->attributeID();
+        if (anId == SketchPlugin_Constraint::VALUE() ||
+          anId == SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID() ||
+          anId == SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()) {
           PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
           if (anEditor)
             anEditor->showPopupEditor();
@@ -669,8 +678,8 @@ void PartSet_SketcherMgr::onApplicationStarted()
 
     connect(aPropertyPanel, SIGNAL(noMoreWidgets(const std::string&)),
             aReentranceMgr, SLOT(onNoMoreWidgets(const std::string&)));
-    connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
-            aReentranceMgr, SLOT(onWidgetActivated()));
+    //connect(aPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)),
+    //        aReentranceMgr, SLOT(onWidgetActivated()));
   }
 
   XGUI_ViewerProxy* aViewerProxy = aWorkshop->viewer();
@@ -730,10 +739,15 @@ void PartSet_SketcherMgr::launchEditing()
       if (!aSPFeature->isExternal())
         myModule->editFeature(aSPFeature);
       else {
-        FeaturePtr aProjectionFeature = PartSet_Tools::findRefsToMeFeature(aFeature,
+        // need to edit a feature (Projection/IntersectionPoint),
+        // which produces current External feature
+        FeaturePtr aProducerFeature = PartSet_Tools::findRefsToMeFeature(aFeature,
                                                         SketchPlugin_Projection::ID());
-        if (aProjectionFeature.get())
-          myModule->editFeature(aProjectionFeature);
+        if (!aProducerFeature.get())
+          aProducerFeature = PartSet_Tools::findRefsToMeFeature(aFeature,
+                                                        SketchPlugin_IntersectionPoint::ID());
+        if (aProducerFeature.get())
+          myModule->editFeature(aProducerFeature);
       }
     }
   }
@@ -802,13 +816,18 @@ const QStringList& PartSet_SketcherMgr::constraintsIdList()
     aConstraintIds << SketchPlugin_ConstraintMirror::ID().c_str();
     aConstraintIds << SketchPlugin_MultiTranslation::ID().c_str();
     aConstraintIds << SketchPlugin_MultiRotation::ID().c_str();
+    aConstraintIds << SketchPlugin_ConstraintDistanceAlongDir::ID().c_str();
+    aConstraintIds << SketchPlugin_ConstraintDistanceHorizontal::ID().c_str();
+    aConstraintIds << SketchPlugin_ConstraintDistanceVertical::ID().c_str();
   }
   return aConstraintIds;
 }
 
-void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)
+void PartSet_SketcherMgr::sketchSelectionModes(const CompositeFeaturePtr& theSketch,
+                                               QIntList& theModes)
 {
-  theModes.clear();
+  if (!theSketch.get() || !PartSet_Tools::sketchPlane(theSketch).get())
+    return;
 
   theModes.append(SketcherPrs_Tools::Sel_Dimension_Text);
   theModes.append(SketcherPrs_Tools::Sel_Dimension_Line);
@@ -915,7 +934,10 @@ bool PartSet_SketcherMgr::isDistanceKind(std::string& theKind)
   return (theKind == SketchPlugin_ConstraintLength::ID()) ||
          (theKind == SketchPlugin_ConstraintDistance::ID()) ||
          (theKind == SketchPlugin_ConstraintRadius::ID()) ||
-         (theKind == SketchPlugin_ConstraintAngle::ID());
+         (theKind == SketchPlugin_ConstraintAngle::ID()) ||
+         (theKind == SketchPlugin_ConstraintDistanceHorizontal::ID()) ||
+         (theKind == SketchPlugin_ConstraintDistanceVertical::ID()) ||
+         (theKind == SketchPlugin_ConstraintDistanceAlongDir::ID());
 }
 
 void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
@@ -929,6 +951,13 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 
   // Display all sketcher sub-Objects
   myCurrentSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFOperation->feature());
+  double aSizeOfView = 0;
+  std::shared_ptr<GeomAPI_Pnt> aCentralPoint;
+  if (aFOperation->isEditOperation() &&
+      mySketchPlane->getDefaultSizeOfView(myCurrentSketch, aSizeOfView, aCentralPoint)) {
+    mySketchPlane->setSizeOfView(aSizeOfView, true, aCentralPoint);
+  }
+
   mySketchPlane->createSketchPlane(myCurrentSketch, myModule->workshop());
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
@@ -943,7 +972,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
   // Remove invalid sketch entities
   std::set<FeaturePtr> anInvalidFeatures;
   ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
-  for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+  int aNumberOfSubs = myCurrentSketch->numberOfSubs();
+  for (int i = 0; i < aNumberOfSubs; i++) {
     FeaturePtr aFeature = myCurrentSketch->subFeature(i);
     if (aFeature.get()) {
       if (!aFactory->validate(aFeature))
@@ -984,7 +1014,8 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
   QStringList anInfo;
   Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
   const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
-  for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+  aNumberOfSubs = myCurrentSketch->numberOfSubs();
+  for (int i = 0; i < aNumberOfSubs; i++) {
     FeaturePtr aFeature = myCurrentSketch->subFeature(i);
 #ifdef DEBUG_SKETCHER_ENTITIES
     anInfo.append(ModuleBase_Tools::objectInfo(aFeature));
@@ -1011,17 +1042,18 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
   bool aHasPlane = false;
   std::shared_ptr<GeomAPI_Pln> aPln;
   aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
-  myPlaneFilter->setPlane(aPln);
+  Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter);
+  if (!aFilter.IsNull())
+    Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(aPln);
 
-  activateSelectionFilters();
+  workshop()->selectionActivate()->updateSelectionFilters();
+  workshop()->selectionActivate()->updateSelectionModes();
 
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-  // all displayed objects should be activated in current selection modes according to switched
-  // plane filter
-  if (aPln.get())
-    aConnector->activateModuleSelectionModes();
 
   myExternalPointsMgr = new PartSet_ExternalPointsMgr(myModule->workshop(), myCurrentSketch);
+
+  workshop()->viewer()->set2dMode(true);
 }
 
 void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
@@ -1035,6 +1067,7 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
     delete myExternalPointsMgr;
     myExternalPointsMgr = 0;
   }
+  onShowPoints(false);
 
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
@@ -1055,7 +1088,8 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
   }
   else {
     // Hide all sketcher sub-Objects
-    for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+    int aNumberOfSubs = myCurrentSketch->numberOfSubs();
+    for (int i = 0; i < aNumberOfSubs; i++) {
       FeaturePtr aFeature = myCurrentSketch->subFeature(i);
       std::list<ResultPtr> aResults = aFeature->results();
       std::list<ResultPtr>::const_iterator aIt;
@@ -1088,10 +1122,9 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
 
     Events_Loop::loop()->flush(aDispEvent);
   }
-  deactivateSelectionFilters();
-
-  // restore the module selection modes, which were changed on startSketch
-  aConnector->activateModuleSelectionModes();
+  workshop()->selectionActivate()->updateSelectionFilters();
+  workshop()->selectionActivate()->updateSelectionModes();
+  workshop()->viewer()->set2dMode(false);
 }
 
 void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
@@ -1133,6 +1166,8 @@ void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation)
   }
   if (isClearSelectionPossible)
     workshop()->selector()->clearSelection();
+  if (myPointsHighlight.size())
+    onShowPoints(true);
 }
 
 void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
@@ -1151,24 +1186,16 @@ void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
   }
 }
 
-void PartSet_SketcherMgr::activateSelectionFilters()
+bool PartSet_SketcherMgr::sketchSelectionFilter(const XGUI_SelectionFilterType theFilterType)
 {
-  myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);
-  myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
+  return mySelectionFilterTypes.find(theFilterType) != mySelectionFilterTypes.end();
 }
 
-void PartSet_SketcherMgr::deactivateSelectionFilters()
+void PartSet_SketcherMgr::registerSelectionFilter(const XGUI_SelectionFilterType theFilterType,
+                                                  const Handle(SelectMgr_Filter)& theFilter)
 {
-  myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
-  myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
-}
-
-void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)
-{
-  if (toActivate)
-    myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
-  else
-    myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
+  mySelectionFilterTypes.insert(theFilterType);
+  myModule->registerSelectionFilter(theFilterType, theFilter);
 }
 
 bool PartSet_SketcherMgr::operationActivatedByPreselection()
@@ -1463,7 +1490,7 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const
   FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject);
   if (anObjectFeature.get()) {
     int aSize = myCurrentSketch->numberOfSubs();
-    for (int i = 0; i < myCurrentSketch->numberOfSubs() && !isFoundObject; i++) {
+    for (int i = 0; i < aSize && !isFoundObject; i++) {
       FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i);
       isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature;
     }
@@ -1471,9 +1498,13 @@ bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const
   return isFoundObject;
 }
 
-void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePln)
+void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& thePlane)
 {
-  myPlaneFilter->setPlane(thePln);
+  Handle(SelectMgr_Filter) aFilter = myModule->selectionFilter(SF_SketchPlaneFilter);
+  if (!aFilter.IsNull())
+    Handle(ModuleBase_ShapeInPlaneFilter)::DownCast(aFilter)->setPlane(thePlane);
+
+  workshop()->selectionActivate()->updateSelectionModes();
 }
 
 bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,
@@ -1880,7 +1911,8 @@ void PartSet_SketcherMgr::updateBySketchParameters(
       if (aPrevState != theState) {
         ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
         XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
-        for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+        int aNumberOfSubs = myCurrentSketch->numberOfSubs();
+        for (int i = 0; i < aNumberOfSubs; i++) {
           FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
           bool aProcessed = false;
           bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed);
@@ -1963,3 +1995,63 @@ XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const
   return workshop()->operationMgr();
 }
 
+void PartSet_SketcherMgr::onShowPoints(bool toShow)
+{
+  if (!myCurrentSketch.get())
+    return;
+  ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+  ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+  Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
+
+  bool aToUpdate = false;
+  if (toShow) {
+    std::list<ResultPtr> aFreePoints = SketcherPrs_Tools::getFreePoints(myCurrentSketch);
+
+    // Delete obsolete presentations
+    std::list<ResultPtr> aDelList;
+    foreach(ResultPtr aObj, myPointsHighlight.keys()) {
+      bool aFound = (std::find(aFreePoints.begin(), aFreePoints.end(), aObj) != aFreePoints.end());
+      if (!aFound)
+        aDelList.push_back(aObj);
+    }
+    foreach(ResultPtr aObj, aDelList) {
+      aContext->Remove(myPointsHighlight[aObj], false);
+      aToUpdate = true;
+      myPointsHighlight.remove(aObj);
+    }
+
+    // Display new objects
+    QList<ResultPtr> aKeysList = myPointsHighlight.keys();
+    std::list<ResultPtr>::const_iterator aIt;
+    for (aIt = aFreePoints.cbegin(); aIt != aFreePoints.cend(); aIt++) {
+      if (!aKeysList.contains(*aIt)) {
+        GeomShapePtr aShapePtr = (*aIt)->shape();
+        TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
+        Handle(AIS_Shape) aShapePrs = new AIS_Shape(aShape);
+        aShapePrs->SetColor(Quantity_NOC_BLUE1);
+        aShapePrs->SetZLayer(Graphic3d_ZLayerId_Top);
+        Handle(Prs3d_Drawer) aDrawer = aShapePrs->Attributes();
+        if (aDrawer->HasOwnPointAspect()) {
+          aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_STAR);
+          aDrawer->PointAspect()->SetColor(Quantity_NOC_BLUE1);
+          aDrawer->PointAspect()->SetScale(2);
+        }
+        else
+          aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_O_STAR, Quantity_NOC_BLUE1, 2));
+        aContext->Display(aShapePrs, false);
+        aContext->Deactivate(aShapePrs);
+        myPointsHighlight[*aIt] = aShapePrs;
+        aToUpdate = true;
+      }
+    }
+  }
+  else {
+    foreach(Handle(AIS_Shape) aPrs, myPointsHighlight.values()) {
+      aContext->Remove(aPrs, false);
+      aToUpdate = true;
+    }
+    myPointsHighlight.clear();
+  }
+  if (aToUpdate)
+    aViewer->update();
+}