]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
[bos #35153][EDF](2023-T1) Construction grid. SketchGridExperiments
authordish <dmitrii.shvydkoi@opencascade.com>
Wed, 5 Jun 2024 09:08:45 +0000 (09:08 +0000)
committerdish <dmitrii.shvydkoi@opencascade.com>
Wed, 5 Jun 2024 09:08:45 +0000 (09:08 +0000)
Add vertex snapping of already drawn sketch primitives.

src/PartSet/PartSet_MouseProcessor.cpp
src/PartSet/PartSet_MouseProcessor.h
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_WidgetBSplinePoints.cpp
src/PartSet/PartSet_WidgetPoint2d.cpp

index 2a68166c4db39abdd5f34e3627253f7751c1e4ac..5c8dbc57ecfe5f54f9b34002168742f8f00be4af 100644 (file)
@@ -47,15 +47,16 @@ double slightlyChangeVal(double theVal)
 }
 
 
-bool PartSet_MouseProcessor::convertPointToLocal(
+/*static*/ bool PartSet_MouseProcessor::convertPointToLocal(
   ModuleBase_IWorkshop* theWorkshop,
   const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch,
   ModuleBase_IViewWindow* theWindow,
   const QPoint& theEventPos,
   double& theX, double& theY,
+  bool theSnap,
   bool theHighlight,
   bool theAddOffset
-) const {
+) {
   ModuleBase_IViewer* const viewer = theWorkshop->viewer();
   if (!viewer)
     return false;
@@ -68,7 +69,7 @@ bool PartSet_MouseProcessor::convertPointToLocal(
   const Handle(V3d_View) view = theWindow->v3dView();
 
   PartSet_PreviewSketchPlane* previewPlane = module->sketchMgr()->previewSketchPlane();
-  if (!aV3dViewer || !aV3dViewer->Grid()->IsActive() || previewPlane->getGridSnappingMode() == PartSet_PreviewSketchPlane::GridSnappingMode::Off) {
+  if (!theSnap || !aV3dViewer || !aV3dViewer->Grid()->IsActive() || previewPlane->getGridSnappingMode() == PartSet_PreviewSketchPlane::GridSnappingMode::Off) {
     const gp_Pnt mousePoint = PartSet_Tools::convertClickToPoint(theEventPos, view);
     PartSet_Tools::convertTo2D(mousePoint, theSketch, view, theX, theY);
     return true;
index 4f759249fc799fe3292a5fe38fca0d9431c87903..597ecb492baa07050f847bad79d491c4bfbad436 100644 (file)
@@ -65,23 +65,24 @@ public:
                                ModuleBase_IViewWindow* theWnd,
                                QMouseEvent* theEvent) {}
 
-  protected:
   /// \brief Converts position of mouse cursor to local coordinates on sketch plane.
   ///  Snaps on-sketch-plane-coordinates to closest construction grid node.
   /// \param theEventPos is position of mouse cursor.
   /// \param theX and \param theY are local coordinates on sketch plane.
+  /// \param theSnap theX and theY are snapped to construction grid if both theSnap == true and snapping is enabled.
   /// \param theHighlight If point is snapped, hightlight grid point.
   /// \param theAddOffset If true, serves as a remedy for odd crash during drawing of a line on a sketch.
-  /// \return true on success.
-  virtual bool convertPointToLocal(
+  /// \returns true on success.
+  static bool convertPointToLocal(
     ModuleBase_IWorkshop* theWorkshop,
     const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch, // Passing by reference is intentionally.
     ModuleBase_IViewWindow* theWindow,
     const QPoint& theEventPos,
     double& theX, double& theY,
+    bool theSnap = true,
     bool theHighlight = false,
     bool theAddOffset = false
-  ) const;
+  );
 };
 
 #endif
index 6b95b8a539176e5c303fb5ef93ef0ce03e34f5c3..feb0af9dd9849a41eb93b88cd8be9f0d8d1533d3 100644 (file)
@@ -177,6 +177,7 @@ PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule)
     myIsMouseOverWindow(false),
     myIsMouseOverViewProcessed(true),
     myIsPopupMenuActive(false),
+    myLastMouseEventType(QEvent::None),
     myPreviousUpdateViewerEnabled(true),
     myExternalPointsMgr(0),
     myNoDragMoving(false)
@@ -384,11 +385,15 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
   myMousePoint.setX(theEvent->x());
   myMousePoint.setY(theEvent->y());
 
-  if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent))
+  if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent)) {
+    myLastMouseEventType = theEvent->type();
     return;
-  //get2dPoint(theWnd, theEvent, myClickedPoint);
-  if (!(theEvent->buttons() & Qt::LeftButton))
+  }
+  //get2dPoint(theWnd, theEvent->pos(), myClickedPoint);
+  if (!(theEvent->buttons() & Qt::LeftButton)) {
+    myLastMouseEventType = theEvent->type();
     return;
+  }
 
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   ModuleBase_IViewer* aViewer = aWorkshop->viewer();
@@ -397,8 +402,10 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
 
   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                                                (getCurrentOperation());
-  if (!aFOperation)
+  if (!aFOperation) {
+    myLastMouseEventType = theEvent->type();
     return;
+  }
 
   bool isEditing = aFOperation->isEditOperation();
   bool aCanDrag = aViewer->canDragByMouse();
@@ -412,21 +419,26 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
     // If the current widget is a selector, do nothing, it processes the mouse press
     ModuleBase_ModelWidget* anActiveWidget = getActiveWidget();
     if(anActiveWidget && anActiveWidget->isViewerSelector()) {
+      myLastMouseEventType = theEvent->type();
       return;
     }
   }
 
   // Use only for sketch operations
   if (myCurrentSketch) {
-    if (!PartSet_Tools::sketchPlane(myCurrentSketch))
+    if (!PartSet_Tools::sketchPlane(myCurrentSketch)) {
+      myLastMouseEventType = theEvent->type();
       return;
+    }
 
     bool isSketcher = isSketchOperation(aFOperation);
     bool isSketchOpe = isNestedSketchOperation(aFOperation);
 
     // Avoid non-sketch operations
-    if ((!isSketchOpe) && (!isSketcher))
+    if ((!isSketchOpe) && (!isSketcher)) {
+      myLastMouseEventType = theEvent->type();
       return;
+    }
 
     // Ignore creation sketch operation
     if ((!isSketcher) && (!isEditing)) {
@@ -445,6 +457,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
             aProcessor->mouseReleased(theWnd, theEvent);
         }
       }
+      myLastMouseEventType = theEvent->type();
       return;
     }
     bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
@@ -455,11 +468,13 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
         // commit previous operation
         if (!aFOperation->commit())
           aFOperation->abort();
+
+      myLastMouseEventType = theEvent->type();
       return;
     }
     // Init flyout point for radius rotation
     FeaturePtr aFeature = myCurrentSelection.begin().key();
-    get2dPoint(theWnd, theEvent, myCurrentPoint);
+    get2dPoint(theWnd, theEvent->pos(), myCurrentPoint);
     if (isSketcher) {
       if (aCanDrag) {
         myIsDragging = true;
@@ -523,6 +538,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE
       }
     }
   }
+
+  myLastMouseEventType = theEvent->type();
 }
 
 void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
@@ -535,12 +552,16 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
   bool aWasDragging = myIsDragging;
   myIsDragging = false;
 
-  if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent))
+  if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent)) {
+    myLastMouseEventType = theEvent->type();
     return;
+  }
 
   // if mouse is pressed when it was over view and at release the mouse is out of view, do nothing
-  if (!myIsMouseOverViewProcessed)
+  if (!myIsMouseOverViewProcessed) {
+    myLastMouseEventType = theEvent->type();
     return;
+  }
 
   ModuleBase_OperationFeature* aOp =
     dynamic_cast<ModuleBase_OperationFeature*>(getCurrentOperation());
@@ -555,8 +576,10 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
       else
         myNoDragMoving = false;
 
-      if (myNoDragMoving)
+      if (myNoDragMoving) {
+        myLastMouseEventType = theEvent->type();
         return;
+      }
       else {
         ModuleBase_OperationFeature* aOp =
         dynamic_cast<ModuleBase_OperationFeature*>(getCurrentOperation());
@@ -571,8 +594,10 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
               myNoDragMoving = !myNoDragMoving;
             else
               myNoDragMoving = false;
-            if (myNoDragMoving)
+            if (myNoDragMoving) {
+              myLastMouseEventType = theEvent->type();
               return;
+            }
             else {
               restoreSelection(myCurrentSelection);
               myCurrentSelection.clear();
@@ -627,13 +652,16 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
   if (MyModeByDrag && aOp) {
     aViewer->enableMultiselection(true);
     QString aOpId = aOp->id();
-    if (aOpId == "Sketch")
+    if (aOpId == "Sketch") {
+      myLastMouseEventType = theEvent->type();
       return;
+    }
 
     QPoint aPnt(theEvent->x(), theEvent->y());
     anActiveWidget = getActiveWidget();
     if ((aPnt == myMousePoint) && anActiveWidget) {
       aOp->abort();
+      myLastMouseEventType = theEvent->type();
       return;
     }
     bool aCanRestart = !anActiveWidget && !isEditing;
@@ -641,6 +669,7 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
       module()->launchOperation(aOpId, true);
     }
   }
+  myLastMouseEventType = theEvent->type();
 }
 
 void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
@@ -659,15 +688,16 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
   }
 #endif
 
-  if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent))
+  if (myModule->sketchReentranceMgr()->processMouseMoved(theWnd, theEvent)) {
+    myLastMouseEventType = theEvent->type();
     return;
+  }
 
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
   XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
 
   if (isNestedCreateOperation(getCurrentOperation(), activeSketch())) {
-
 #ifdef DRAGGING_DEBUG
     QTime t;
     t.start();
@@ -707,9 +737,11 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     // deselected). This flag should be restored in the slot, processed the mouse release signal.
     ModuleBase_Operation* aCurrentOperation = getCurrentOperation();
     if (!aCurrentOperation) {
+      myLastMouseEventType = theEvent->type();
       return;
     }
     if (isSketchOperation(aCurrentOperation)) {
+      myLastMouseEventType = theEvent->type();
       return; // No edit operation activated
     }
 
@@ -719,13 +751,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
 #endif
 
     Handle(V3d_View) aView = theWnd->v3dView();
-    Point aMousePnt;
-    get2dPoint(theWnd, theEvent, aMousePnt);
+    Point aMousePnt, aHoverPnt;
+    get2dPoint(theWnd, theEvent->pos(), aMousePnt, true /*theSnap*/);
+    get2dPoint(theWnd, theEvent->pos(), aHoverPnt, myLastMouseEventType == QEvent::MouseMove /*theSnap*/);
 
-    std::shared_ptr<GeomAPI_Pnt2d> anOriginalPosition = std::shared_ptr<GeomAPI_Pnt2d>(
-      new GeomAPI_Pnt2d(myCurrentPoint.myCurX, myCurrentPoint.myCurY));
-    std::shared_ptr<GeomAPI_Pnt2d> aCurrentPosition = std::shared_ptr<GeomAPI_Pnt2d>(
-      new GeomAPI_Pnt2d(aMousePnt.myCurX, aMousePnt.myCurY));
+    auto anOriginalPosition = std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(myCurrentPoint.myCurX, myCurrentPoint.myCurY));
+    auto aCurrentPosition   = std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aMousePnt.myCurX, aMousePnt.myCurY));
 
     // 3. the flag to disable the update viewer should be set in order to avoid blinking in the
     // viewer happens by deselect/select the modified objects. The flag should be restored after
@@ -748,8 +779,10 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
           anAttLast = anAttributes.end();
         for (; anAttIt != anAttLast; anAttIt++) {
           AttributePtr anAttr = anAttIt->first;
+
           if (anAttr.get() == NULL)
             continue;
+
           std::string aAttrId = anAttr->id();
           DataPtr aData = aFeature->data();
           if (aData->isValid()) {
@@ -758,8 +791,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
                 aPoint->attributeType() == GeomDataAPI_Point2DArray::typeId()) {
               bool isImmutable = aPoint->setImmutable(true);
 
-              std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage = std::shared_ptr
-                <ModelAPI_ObjectMovedMessage>(new ModelAPI_ObjectMovedMessage(this));
+              auto aMessage = std::shared_ptr<ModelAPI_ObjectMovedMessage>(new ModelAPI_ObjectMovedMessage(this));
               aMessage->setMovedAttribute(aPoint, anAttIt->second);
               aMessage->setOriginalPosition(anOriginalPosition);
               aMessage->setCurrentPosition(aCurrentPosition);
@@ -771,13 +803,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
           }
         }
       }
-      else {
+      else
+      {
         // Process selection by feature
-        std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
-          std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+        auto aSketchFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
         if (aSketchFeature) {
-          std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage = std::shared_ptr
-            <ModelAPI_ObjectMovedMessage>(new ModelAPI_ObjectMovedMessage(this));
+          auto aMessage = std::shared_ptr<ModelAPI_ObjectMovedMessage>(new ModelAPI_ObjectMovedMessage(this));
           aMessage->setMovedObject(aFeature);
           aMessage->setOriginalPosition(anOriginalPosition);
           aMessage->setCurrentPosition(aCurrentPosition);
@@ -806,8 +837,10 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
 #endif
 
     myDragDone = true;
-    myCurrentPoint = aMousePnt;
+    myCurrentPoint = aHoverPnt;
   }
+
+  myLastMouseEventType = theEvent->type();
 }
 
 void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
@@ -830,11 +863,15 @@ void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMo
           PartSet_WidgetEditor* anEditor = dynamic_cast<PartSet_WidgetEditor*>(aWgt);
           if (anEditor)
             anEditor->showPopupEditor();
+
+          myLastMouseEventType = theEvent->type();
           return;
         }
       }
     }
   }
+
+  myLastMouseEventType = theEvent->type();
 }
 
 void PartSet_SketcherMgr::onApplicationStarted()
@@ -892,14 +929,14 @@ void PartSet_SketcherMgr::onAfterContextMenu()
   myIsPopupMenuActive = false;
 }
 
-void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent,
-                                     Point& thePoint)
+void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, const QPoint& theEventPos, Point& thePoint, bool theSnap)
 {
-  Handle(V3d_View) aView = theWnd->v3dView();
-  gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);
-  double aX, anY;
-  PartSet_Tools::convertTo2D(aPoint, myCurrentSketch, aView, aX, anY);
-  thePoint.setValue(aX, anY);
+  double aX = 0, aY = 0; // Coords at sketch plane.
+  bool success = PartSet_MouseProcessor::convertPointToLocal(workshop()->moduleConnector(), myCurrentSketch, theWnd, theEventPos, aX, aY, theSnap, true, false);
+  if (!success)
+    return;
+
+  thePoint.setValue(aX, aY);
 }
 
 void PartSet_SketcherMgr::launchEditing()
index 312021601fa32382e60ce9edb8a2627cfddc5e6b..39bad597dee5b8c0d19d477b6dc4007d5fd6e974 100644 (file)
@@ -56,6 +56,7 @@
 #include <QList>
 #include <QMap>
 #include <QPoint>
+#include <QEvent>
 
 #include <set>
 
@@ -427,8 +428,9 @@ private:
 
   /// Converts mouse position to 2d coordinates.
   /// Member myCurrentSketch has to be correctly defined
-  void get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent,
-                  Point& thePoint);
+  /// \param theSnap If true and snapping is enabled, snaps coordinates to the grid.
+  void get2dPoint(ModuleBase_IViewWindow* theWnd, const QPoint& theEventPos,
+                  Point& thePoint, bool theSnap = false);
 
   /// Show distance value editor if it is a distance operation and all attribute references
   /// are filled by preseletion
@@ -500,6 +502,7 @@ private:
   bool myIsMouseOverWindow; /// the state that the mouse over the view
   /// the state whether the over view state is processed by mouseMove method
   bool myIsMouseOverViewProcessed;
+  QEvent::Type myLastMouseEventType;
   bool myIsPopupMenuActive; /// the state of the popup menu is shown
   Point myCurrentPoint;
   //Point myClickedPoint;
index 192078248bee8140725055456a1fff51a643ed24..a05ad5d82f6cae5784e7ec89cf87445c0d765d0f 100644 (file)
@@ -562,6 +562,7 @@ void PartSet_WidgetBSplinePoints::mouseMoved(ModuleBase_IViewWindow* theWindow,
     theWindow,
     theEvent->pos(),
     aX, aY,
+    true,
     true
   );
 
index dfaccf2ed32f0379b69a5ea51af50c7136b3af7d..f097f9591d83e994d3de3944155bd6d7bd2b7648 100644 (file)
@@ -366,8 +366,10 @@ bool PartSet_WidgetPoint2D::restoreValueCustom()
   std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
   AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aData->attribute(attributeID()));
+
   double aValueX = aPoint->isInitialized() ? aPoint->x() : 0.;
   double aValueY = aPoint->isInitialized() ? aPoint->y() : 0.;
+
   myXSpin->setValue(aValueX);
   myYSpin->setValue(aValueY);
 
@@ -571,7 +573,7 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo
     }
   }
   if (!aHasPoint) {
-    bool success = convertPointToLocal(myWorkshop, mySketch, theWindow, theEvent->pos(), aX, aY, false);
+    bool success = PartSet_MouseProcessor::convertPointToLocal(myWorkshop, mySketch, theWindow, theEvent->pos(), aX, aY, true, false);
     if (!success)
       return;
   }
@@ -742,7 +744,7 @@ void PartSet_WidgetPoint2D::mouseMoved(ModuleBase_IViewWindow* theWindow, QMouse
     return;
 
   double aX = 0, aY = 0; // Coords at sketch plane.
-  bool success = convertPointToLocal(myWorkshop, mySketch, theWindow, theEvent->pos(), aX, aY, true, true);
+  bool success = PartSet_MouseProcessor::convertPointToLocal(myWorkshop, mySketch, theWindow, theEvent->pos(), aX, aY, true, true, true);
   if (!success)
     return;