Salome HOME
Pipe validator fix
[modules/shaper.git] / src / PartSet / PartSet_SketcherMgr.cpp
index 583e132981a1d492063ddf6bb815fcf87c25ed52..22c4b653a1c586ccf11b1a317a6da2db49a12372 100755 (executable)
@@ -12,6 +12,7 @@
 #include "PartSet_Tools.h"
 #include "PartSet_WidgetSketchLabel.h"
 #include "PartSet_WidgetEditor.h"
+#include "PartSet_ResultSketchPrs.h"
 
 #include <XGUI_ModuleConnector.h>
 #include <XGUI_Displayer.h>
@@ -23,6 +24,7 @@
 #include <XGUI_PropertyPanel.h>
 #include <XGUI_ViewerProxy.h>
 #include <XGUI_OperationMgr.h>
+#include <XGUI_Tools.h>
 
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_ISelection.h>
@@ -34,6 +36,7 @@
 #include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_WidgetEditor.h>
+#include <ModuleBase_ViewerPrs.h>
 
 #include <GeomDataAPI_Point2D.h>
 
 //#define DEBUG_CURSOR
 
 /// Returns list of unique objects by sum of objects from List1 and List2
-/*QList<ModuleBase_ViewerPrs> getSumList(const QList<ModuleBase_ViewerPrs>& theList1,
-                                       const QList<ModuleBase_ViewerPrs>& theList2)
+/*QList<ModuleBase_ViewerPrsPtr> getSumList(const QList<ModuleBase_ViewerPrsPtr>& theList1,
+                                       const QList<ModuleBase_ViewerPrsPtr>& theList2)
 {
-  QList<ModuleBase_ViewerPrs> aRes;
-  foreach (ModuleBase_ViewerPrs aPrs, theList1) {
+  QList<ModuleBase_ViewerPrsPtr> aRes;
+  foreach (ModuleBase_ViewerPrsPtr aPrs, theList1) {
     if (!aRes.contains(aPrs))
       aRes.append(aPrs);
   }
-  foreach (ModuleBase_ViewerPrs aPrs, theList2) {
+  foreach (ModuleBase_ViewerPrsPtr aPrs, theList2) {
     if (!aRes.contains(aPrs))
       aRes.append(aPrs);
   }
 // \param theSketch a sketch to project a vertex shape of a presentation to the plane
 // and find the corresponded attribute
 // \param theFeatureList  an output list of features
-void fillFeatureList(const QList<ModuleBase_ViewerPrs>& theList,
+void fillFeatureList(const QList<ModuleBase_ViewerPrsPtr>& theList,
                      const FeaturePtr theSketch,
                      QList<FeaturePtr>& theFeatureList)
 {
-  QList<ModuleBase_ViewerPrs> aRes;
+  QList<ModuleBase_ViewerPrsPtr> aRes;
 
-  QList<ModuleBase_ViewerPrs>::const_iterator anIt = theList.begin(),
+  QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theList.begin(),
                                               aLast = theList.end();
   for (; anIt != aLast; anIt++)
   {
-    ModuleBase_ViewerPrs aPrs = *anIt;
-    FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
+    ModuleBase_ViewerPrsPtr aPrs = *anIt;
+    FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs->object());
     if (aFeature.get()  && !theFeatureList.contains(aFeature))
       theFeatureList.append(aFeature);
   }
@@ -188,6 +191,7 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
 
   myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
   myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+  myIsConstraintsShown[PartSet_Tools::Expressions] = false;
 }
 
 PartSet_SketcherMgr::~PartSet_SketcherMgr()
@@ -310,8 +314,10 @@ void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
 void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
 {
   if (!isNestedEditOperation(getCurrentOperation()) ||
-      myModule->sketchReentranceMgr()->isInternalEditActive())
+      myModule->sketchReentranceMgr()->isInternalEditActive()) {
+    myModule->sketchReentranceMgr()->updateInternalEditActiveState();
     return;
+  }
   // it is necessary to restore current selection in order to restore it after the values are modified
   restoreSelection();
   myCurrentSelection.clear();
@@ -324,6 +330,8 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel()
   XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
   aDisplayer->enableUpdateViewer(myPreviousUpdateViewerEnabled);
   aDisplayer->updateViewer();
+
+
 }
 
 void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
@@ -779,6 +787,17 @@ void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes)
   theModes.append(TopAbs_EDGE);
 }
 
+Handle(AIS_InteractiveObject) PartSet_SketcherMgr::createPresentation(const ResultPtr& theResult)
+{
+  Handle(AIS_InteractiveObject) aPrs;
+
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theResult);
+  if (aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID()) {
+    aPrs = new PartSet_ResultSketchPrs(theResult);
+  }
+  return aPrs;
+}
+
 bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation)
 {
   return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID();
@@ -860,24 +879,25 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
     aFeature->setDisplayed(true);
   }
 
+  if(myCirclePointFilter.IsNull()) {
+    myCirclePointFilter = new PartSet_CirclePointFilter(myModule->workshop());
+  }
+
+  myModule->workshop()->viewer()->addSelectionFilter(myCirclePointFilter);
+
   if (myPlaneFilter.IsNull()) 
     myPlaneFilter = new ModuleBase_ShapeInPlaneFilter();
 
   myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter);
   bool aHasPlane = false;
   std::shared_ptr<GeomAPI_Pln> aPln;
-  if (aFOperation->isEditOperation()) {
-    // If it is editing of sketch then it means that plane is already defined
-    aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
-    if (aPln.get())
-      aHasPlane = true;
-  }
+  aPln = PartSet_Tools::sketchPlane(myCurrentSketch);
   myPlaneFilter->setPlane(aPln);
 
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-  // all sketch objects should be activated in the sketch selection modes by edit operation start
-  // in case of creation operation, there is an active widget, which activates own selection mode
-  if (aFOperation->isEditOperation() && aHasPlane)
+  // all displayed objects should be activated in current selection modes according to switched
+  // plane filter
+  if (aPln.get())
     aConnector->activateModuleSelectionModes();
 }
 
@@ -886,6 +906,7 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
   myIsMouseOverWindow = false;
   myIsConstraintsShown[PartSet_Tools::Geometrical] = true;
   myIsConstraintsShown[PartSet_Tools::Dimensional] = true;
+  myIsConstraintsShown[PartSet_Tools::Expressions] = false;
 
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
 
@@ -894,6 +915,8 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
     XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
     // The sketch was aborted
     myCurrentSketch = CompositeFeaturePtr();
+    // TODO: move this outside of if-else
+    myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 
     // Erase all sketcher objects
@@ -936,6 +959,8 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
       myCurrentSketch->setDisplayed(true);
     
     myCurrentSketch = CompositeFeaturePtr();
+
+    myModule->workshop()->viewer()->removeSelectionFilter(myCirclePointFilter);
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 
     Events_Loop::loop()->flush(aDispEvent);
@@ -994,85 +1019,30 @@ void PartSet_SketcherMgr::activatePlaneFilter(const bool& toActivate)
     myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter);
 }
 
-void PartSet_SketcherMgr::operationActivatedByPreselection()
+bool PartSet_SketcherMgr::operationActivatedByPreselection()
 {
+  bool isOperationStopped = false;
   ModuleBase_Operation* anOperation = getCurrentOperation();
   if(anOperation && PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) {
     // Set final definitions if they are necessary
     //propertyPanelDefined(aOperation);
     /// Commit sketcher operations automatically
+    /// distance operation are able to show popup editor to modify the distance value
+    /// after entering the value, the operation should be committed/aborted(by Esc key)
+    bool aCanCommitOperation = true;
     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                                                             (anOperation);
-    if (aFOperation) {
-      if (PartSet_SketcherMgr::isDistanceOperation(aFOperation)) {
-        FeaturePtr aFeature = aFOperation->feature();
-        // editor is shown only if all attribute references are filled by preseletion
-        bool anAllRefAttrInitialized = true;
-
-        std::list<AttributePtr> aRefAttrs = aFeature->data()->attributes(
-                                                    ModelAPI_AttributeRefAttr::typeId());
-        std::list<AttributePtr>::const_iterator anIt = aRefAttrs.begin(), aLast = aRefAttrs.end();
-        for (; anIt != aLast && anAllRefAttrInitialized; anIt++) {
-          anAllRefAttrInitialized = (*anIt)->isInitialized();
-        }
-        if (anAllRefAttrInitialized) {
-          // Activate dimension value editing on double click
-          ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
-          QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
-          // Find corresponded widget to activate value editing
-          foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
-            if (aWgt->attributeID() == "ConstraintValue") {
-              // the featue should be displayed in order to find the AIS text position,
-              // the place where the editor will be shown
-              aFeature->setDisplayed(true);
-              /// the execute is necessary to perform in the feature compute for flyout position
-              aFeature->execute();
-
-              Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
-              Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-
-              PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
-              if (anEditor) {
-                int aX = 0, anY = 0;
-
-                ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
-                XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
-                XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
-                AISObjectPtr anAIS = aDisplayer->getAISObject(aFeature);
-                Handle(AIS_InteractiveObject) anAISIO;
-                if (anAIS.get() != NULL) {
-                  anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
-                }
-                if (anAIS.get() != NULL) {
-                  Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
-
-                  if (!anAISIO.IsNull()) {
-                    Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO);
-                    if (!aDim.IsNull()) {
-                      gp_Pnt aPosition = aDim->GetTextPosition();
-
-                      ModuleBase_IViewer* aViewer = aWorkshop->viewer();
-                      Handle(V3d_View) aView = aViewer->activeView();
-                      int aCX, aCY;
-                      aView->Convert(aPosition.X(), aPosition.Y(), aPosition.Z(), aCX, aCY);
-
-                      QWidget* aViewPort = aViewer->activeViewPort();
-                      QPoint aGlPoint = aViewPort->mapToGlobal(QPoint(aCX, aCY));
-                      aX = aGlPoint.x();
-                      anY = aGlPoint.y();
-                    }
-                  }
-                  anEditor->setCursorPosition(aX, anY);
-                  anEditor->showPopupEditor(false);
-                }
-              }
-            }
-          }
-        }
-      }
+    if (aFOperation && PartSet_SketcherMgr::isDistanceOperation(aFOperation))
+      aCanCommitOperation = setDistanceValueByPreselection(anOperation, myModule->workshop());
+
+    if (aCanCommitOperation)
+      isOperationStopped = anOperation->commit();
+    else {
+      anOperation->abort();
+      isOperationStopped = true;
     }
-    anOperation->commit();
   }
+  return isOperationStopped;
 }
 
 bool PartSet_SketcherMgr::canUndo() const
@@ -1356,6 +1326,79 @@ void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>& th
   myPlaneFilter->setPlane(thePln);
 }
 
+bool PartSet_SketcherMgr::setDistanceValueByPreselection(ModuleBase_Operation* theOperation,
+                                                         ModuleBase_IWorkshop* theWorkshop)
+{
+  bool isValueAccepted = false;
+
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                              (theOperation);
+  FeaturePtr aFeature = aFOperation->feature();
+  // editor is shown only if all attribute references are filled by preseletion
+  bool anAllRefAttrInitialized = true;
+
+  std::list<AttributePtr> aRefAttrs = aFeature->data()->attributes(
+                                              ModelAPI_AttributeRefAttr::typeId());
+  std::list<AttributePtr>::const_iterator anIt = aRefAttrs.begin(), aLast = aRefAttrs.end();
+  for (; anIt != aLast && anAllRefAttrInitialized; anIt++) {
+    anAllRefAttrInitialized = (*anIt)->isInitialized();
+  }
+  if (anAllRefAttrInitialized) {
+    // Activate dimension value editing on double click
+    ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
+    QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
+    // Find corresponded widget to activate value editing
+    foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
+      if (aWgt->attributeID() == "ConstraintValue") {
+        // the featue should be displayed in order to find the AIS text position,
+        // the place where the editor will be shown
+        aFeature->setDisplayed(true);
+        /// the execute is necessary to perform in the feature compute for flyout position
+        aFeature->execute();
+
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+
+        PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
+        if (anEditor) {
+          int aX = 0, anY = 0;
+
+          XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(theWorkshop);
+          XGUI_Displayer* aDisplayer = aWorkshop->displayer();
+          AISObjectPtr anAIS = aDisplayer->getAISObject(aFeature);
+          Handle(AIS_InteractiveObject) anAISIO;
+          if (anAIS.get() != NULL) {
+            anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+          }
+          if (anAIS.get() != NULL) {
+            Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+
+            if (!anAISIO.IsNull()) {
+              Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(anAISIO);
+              if (!aDim.IsNull()) {
+                gp_Pnt aPosition = aDim->GetTextPosition();
+
+                ModuleBase_IViewer* aViewer = aWorkshop->viewer();
+                Handle(V3d_View) aView = aViewer->activeView();
+                int aCX, aCY;
+                aView->Convert(aPosition.X(), aPosition.Y(), aPosition.Z(), aCX, aCY);
+
+                QWidget* aViewPort = aViewer->activeViewPort();
+                QPoint aGlPoint = aViewPort->mapToGlobal(QPoint(aCX, aCY));
+                aX = aGlPoint.x();
+                anY = aGlPoint.y();
+              }
+            }
+            anEditor->setCursorPosition(aX, anY);
+            isValueAccepted = anEditor->showPopupEditor(false);
+          }
+        }
+      }
+    }
+  }
+  return isValueAccepted;
+}
+
 void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature,
                                               const FeaturePtr& theSketch,
                                               ModuleBase_IWorkshop* theWorkshop,
@@ -1502,6 +1545,15 @@ void PartSet_SketcherMgr::widgetStateChanged(int thePreviousState)
   }
 }
 
+void PartSet_SketcherMgr::customizePresentation(const ObjectPtr& theObject)
+{
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                           (getCurrentOperation());
+  if (aFOperation && (PartSet_SketcherMgr::isSketchOperation(aFOperation) ||
+                      PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)))
+    SketcherPrs_Tools::sendExpressionShownEvent(myIsConstraintsShown[PartSet_Tools::Expressions]);
+}
+
 ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const
 {
   return myModule->workshop()->currentOperation();
@@ -1560,9 +1612,12 @@ void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature,
 
 void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
 {
+  if (!myCurrentSketch.get())
+    return;
+
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   ModuleBase_ISelection* aSelect = aWorkshop->selection();
-  QList<ModuleBase_ViewerPrs> aHighlighted = aSelect->getHighlighted();
+  QList<ModuleBase_ViewerPrsPtr> aHighlighted = aSelect->getHighlighted();
 
   QList<FeaturePtr> aFeatureList;
   if (theHighlightedOnly) {
@@ -1571,7 +1626,7 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
   else {
     fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList);
 
-    QList<ModuleBase_ViewerPrs> aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls);
+    QList<ModuleBase_ViewerPrsPtr> aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls);
     fillFeatureList(aSelected, myCurrentSketch, aFeatureList);
   }
 
@@ -1586,6 +1641,9 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
 
 void PartSet_SketcherMgr::restoreSelection()
 {
+  if (!myCurrentSketch.get())
+    return;
+
   //qDebug(QString("restoreSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
@@ -1603,24 +1661,45 @@ void PartSet_SketcherMgr::restoreSelection()
 void PartSet_SketcherMgr::onShowConstraintsToggle(int theType, bool theState)
 {
   PartSet_Tools::ConstraintVisibleState aType = (PartSet_Tools::ConstraintVisibleState)theType;
-  if (myIsConstraintsShown.contains(aType) && myIsConstraintsShown[aType] == theState)
-    return;
-  if (myCurrentSketch.get() == NULL)
-    return;
 
-  myIsConstraintsShown[aType] = theState;
+  updateBySketchParameters(aType, theState);
+}
 
-  ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+void PartSet_SketcherMgr::updateBySketchParameters(
+                                   const PartSet_Tools::ConstraintVisibleState& theType,
+                                   bool theState)
+{
+  if (myCurrentSketch.get() == NULL)
+    return;
 
-  for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
-    FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
-    bool aProcessed = false;
-    bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, aType, aProcessed);
-    if (aProcessed)
-      aSubFeature->setDisplayed(aConstraintDisplayed);
+  bool aPrevState = myIsConstraintsShown[theType];
+  myIsConstraintsShown[theType] = theState;
+
+  switch (theType) {
+    case PartSet_Tools::Geometrical:
+    case PartSet_Tools::Dimensional: {
+      if (aPrevState != theState) {
+        ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
+        XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
+        for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) {
+          FeaturePtr aSubFeature = myCurrentSketch->subFeature(i);
+          bool aProcessed = false;
+          bool aConstraintDisplayed = canDisplayConstraint(aSubFeature, theType, aProcessed);
+          if (aProcessed)
+            aSubFeature->setDisplayed(aConstraintDisplayed);
+        }
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+      }
+    }
+    break;
+    case PartSet_Tools::Expressions: {
+      /// call all sketch features redisplay, the expression state will be corrected in customize
+      /// of distance presentation
+      Events_ID anEventId = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+      PartSet_Tools::sendSubFeaturesEvent(myCurrentSketch, anEventId);
+    }
+    break;
   }
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 }
 
 XGUI_Workshop* PartSet_SketcherMgr::workshop() const