]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
#26454 [EDF] (2021) SMESH: interactive mesh modification: interactive part
authorrnv <rnv@opencascade.com>
Sat, 5 Feb 2022 13:06:37 +0000 (16:06 +0300)
committerrnv <rnv@opencascade.com>
Sat, 5 Feb 2022 13:06:37 +0000 (16:06 +0300)
_stash [deleted file]
src/SMESHGUI/CMakeLists.txt
src/SMESHGUI/SMESHGUI_AddNodeOnFaceDlg.cxx
src/SMESHGUI/SMESHGUI_AddNodeOnFaceDlg.h
src/SMESHGUI/SMESHGUI_AddNodeOnSegmentDlg.cxx
src/SMESHGUI/SMESHGUI_AddNodeOnSegmentDlg.h
src/SMESHGUI/SMESHGUI_InteractiveOp.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_InteractiveOp.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h
src/SMESHGUI/SMESH_msg_en.ts

diff --git a/_stash b/_stash
deleted file mode 100644 (file)
index 2cb3cde..0000000
--- a/_stash
+++ /dev/null
@@ -1,3 +0,0 @@
-1) partial Fix of QuadFromMedialAxis algo
-2) Begin fix 19982 EDF 21954 - Compute mesh fails
-        
\ No newline at end of file
index 16eda3a3d0d7b9a50b2ae0b6ff4a068229c3b720..bc45073664b71545f7eb0ed91a7dee6cfe47d3c0 100644 (file)
@@ -156,6 +156,7 @@ SET(_moc_HEADERS
   SMESHGUI_RemoveNodeReconnectionDlg.h
   SMESHGUI_AddNodeOnSegmentDlg.h
   SMESHGUI_AddNodeOnFaceDlg.h
+  SMESHGUI_InteractiveOp.h
 )
 
 # header files / no moc processing
@@ -281,6 +282,7 @@ SET(_other_SOURCES
   SMESHGUI_RemoveNodeReconnectionDlg.cxx
   SMESHGUI_AddNodeOnSegmentDlg.cxx
   SMESHGUI_AddNodeOnFaceDlg.cxx
+  SMESHGUI_InteractiveOp.cxx
 )
 
 # sources / to compile
index 975c5363ca15c125f8953bba2fd07b7cea28789a..58f029612eaeba351c7f544842c5a4f3ce84c5c1 100644 (file)
@@ -37,6 +37,7 @@
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
 #include <SMESH_TypeDefs.hxx>
+#include <SMESH_MeshAlgos.hxx>
 
 // SALOME GUI includes
 #include <LightApp_SelectionMgr.h>
@@ -49,6 +50,9 @@
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_MessageBox.h>
+#include <SVTK_RenderWindowInteractor.h>
+#include <SVTK_Renderer.h>
+#include <SVTK_Event.h>
 
 // Qt includes
 #include <QApplication>
 
 // VTK includes
 #include <vtkProperty.h>
+#include <vtkCellPicker.h>
+#include <vtkInteractorStyle.h>
+#include <vtkGenericRenderWindowInteractor.h>
+#include <vtkInteractorObserver.h>
+
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -74,6 +83,8 @@
 #define SPACING 6
 #define MARGIN  11
 
+#define TOLERANCE 1e-3
+
 //=======================================================================
 /*!
  * \brief Dialog to publish a sub-shape of the mesh main shape
@@ -147,6 +158,8 @@ QWidget* SMESHGUI_AddNodeOnFaceDlg::createMainFrame (QWidget* theParent)
   myDestinationY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
   myDestinationZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
+  myPointOnFace = new QCheckBox(tr("XYZ_NODE_ON_FACE"), xyzGrp);
+
   QGridLayout* aDestLayout = new QGridLayout(xyzGrp);
   aDestLayout->setMargin(MARGIN);
   aDestLayout->setSpacing(SPACING);
@@ -160,9 +173,9 @@ QWidget* SMESHGUI_AddNodeOnFaceDlg::createMainFrame (QWidget* theParent)
   aDestLayout->setColumnStretch(2, 1);
   aDestLayout->setColumnStretch(4, 1);
   aDestLayout->setColumnStretch(6, 1);
+  aDestLayout->addWidget(myPointOnFace, 1, 0, 1, 6);
 
   // Preview
-
   myPreviewChkBox = new QCheckBox( tr("PREVIEW"), aFrame);
   myPreviewChkBox->setChecked( true );
 
@@ -209,7 +222,8 @@ void SMESHGUI_AddNodeOnFaceDlg::ButtonToggled (bool on)
 */
 //================================================================================
 
-SMESHGUI_AddNodeOnFaceOp::SMESHGUI_AddNodeOnFaceOp()
+SMESHGUI_AddNodeOnFaceOp::SMESHGUI_AddNodeOnFaceOp() : 
+  SMESHGUI_InteractiveOp()
 {
   mySimulation = 0;
   mySMESHGUI = 0;
@@ -217,15 +231,22 @@ SMESHGUI_AddNodeOnFaceOp::SMESHGUI_AddNodeOnFaceOp()
   myHelpFileName = "add_node_on_face.html";
 
   myNoPreview = false;
+  myUpdateDestination = false;
 
   // connect signals and slots
-  connect(myDlg->myDestinationX,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myDlg->myDestinationY,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myDlg->myDestinationZ,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myDestinationX,  SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
+  connect(myDlg->myDestinationY,  SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
+  connect(myDlg->myDestinationZ,  SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
   connect(myDlg->myId,            SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
   connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),              SLOT(redisplayPreview()));
   connect(myDlg,                  SIGNAL (selTypeChanged() ),          SLOT(onSelTypeChange()));
   connect(myDlg->myId,            SIGNAL (textChanged(const QString&)),SLOT(onTextChange(const QString&)));
+  connect(myDlg->myPointOnFace,   SIGNAL(toggled(bool)),               SLOT(pointLocationChanged(bool)));
+
+  myFacePicker = vtkCellPicker::New();
+  myFacePicker->SetTolerance(0.005);
+  myFacePicker->PickFromListOn();
+
 }
 
 //================================================================================
@@ -242,7 +263,14 @@ void SMESHGUI_AddNodeOnFaceOp::onSelTypeChange()
   }
   else if ( myDlg->myDestBtn->isChecked() )
   {
-    // TODO: activate picking a point on a selected face
+    QString msg;
+    if (isValid(msg)) {
+      //Disconnect selectionChanged to keep selected element
+      disconnect(selectionMgr(), SIGNAL(selectionChanged()), this, SLOT(onSelectionDone()));
+      // Set selection mode to ActorSelection to avoid element's prehighlight during interactive selection
+      setSelectionMode(ActorSelection);
+      connect(selectionMgr(), SIGNAL(selectionChanged()), SLOT(onSelectionDone()));
+    }
   }
   else
   {
@@ -275,10 +303,15 @@ void SMESHGUI_AddNodeOnFaceOp::startOperation()
   aProp->Delete();
 
   SMESHGUI_SelectionOp::startOperation();
+  SMESHGUI_InteractiveOp::startOperation();
   myDlg->myId->setText("");
+  myUpdateDestination = true;
   myDlg->myDestinationX->SetValue(0);
   myDlg->myDestinationY->SetValue(0);
   myDlg->myDestinationZ->SetValue(0);
+  myUpdateDestination = false;
+
+  addObserver();
 
   myDlg->show();
 
@@ -309,6 +342,7 @@ void SMESHGUI_AddNodeOnFaceOp::stopOperation()
   disconnect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
   disconnect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   SMESHGUI_SelectionOp::stopOperation();
+  removeObserver();
 }
 
 //================================================================================
@@ -429,6 +463,8 @@ void SMESHGUI_AddNodeOnFaceOp::onSelectionDone()
       return;
     Handle(SALOME_InteractiveObject) anIO = aList.First();
     myMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
+    myFacePicker->InitializePickList();
+    myFacePicker->AddPickList(myMeshActor);
 
     QString aString;
     int nbElems = SMESH::GetNameOfSelectedElements(selector(),anIO, aString);
@@ -442,9 +478,11 @@ void SMESHGUI_AddNodeOnFaceOp::onSelectionDone()
           for ( int i = 0; i < face->NbCornerNodes(); ++i )
             faceGC += SMESH_NodeXYZ( face->GetNode( i ));
           faceGC /= face->NbCornerNodes();
+          myUpdateDestination = true;
           myDlg->myDestinationX->SetValue(faceGC.X());
           myDlg->myDestinationY->SetValue(faceGC.Y());
           myDlg->myDestinationZ->SetValue(faceGC.Z());
+          myUpdateDestination = false;
         }
   } catch (...) {
   }
@@ -590,6 +628,54 @@ SMESHGUI_AddNodeOnFaceOp::~SMESHGUI_AddNodeOnFaceOp()
 {
   if ( myDlg )        delete myDlg;
   if ( mySimulation ) delete mySimulation;
+  myFacePicker->Delete();
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when destination coordinates are changed
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnFaceOp::onDestCoordChanged() 
+{
+  if (myUpdateDestination)
+    return;
+  pointLocationChanged(myDlg->myPointOnFace->isChecked());
+  redisplayPreview();
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Node on face' checkbox is changed
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnFaceOp::pointLocationChanged(bool onFace) {
+  if (onFace) {
+    QString msg;
+    if (myMeshActor && isValid(msg)) {
+      SMESH::smIdType id = myDlg->myId->text().toLong();
+      if (id > 0) {
+        if (SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) {
+          if (const SMDS_MeshElement* face = aMesh->FindElement(id))
+          {
+            if (face->GetType() == SMDSAbs_Face) {
+              gp_Pnt point(myDlg->myDestinationX->GetValue(), myDlg->myDestinationY->GetValue(),myDlg->myDestinationZ->GetValue());
+              gp_XYZ closestPnt;
+              double dist = SMESH_MeshAlgos::GetDistance( face, point, &closestPnt);
+              if (dist > TOLERANCE) {
+                myUpdateDestination = true;
+                myDlg->myDestinationX->SetValue(closestPnt.X());
+                myDlg->myDestinationY->SetValue(closestPnt.Y());
+                myDlg->myDestinationZ->SetValue(closestPnt.Z());
+                myUpdateDestination = false;
+                redisplayPreview();
+              }
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
 //================================================================================
@@ -604,3 +690,97 @@ LightApp_Dialog* SMESHGUI_AddNodeOnFaceOp::dlg() const
   return myDlg;
 }
 
+//================================================================================
+/*
+* \brief Process InteractiveSelectionChanged event
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnFaceOp::processStyleEvents(unsigned long theEvent, void* theCallData)
+{
+  (void*)theCallData;
+  QString msg;
+  if (isValid(msg)) {
+    if (theEvent == SVTK::InteractiveSelectionChanged) {
+      if (myDlg->myPointOnFace->isChecked()) {
+        // Pick point on a mesh surface
+        QString msg;
+        if (myMeshActor && isValid(msg)) {
+          SMESH::smIdType id = myDlg->myId->text().toLong();
+          if (id > 0) {
+            if (SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) {
+              if (const SMDS_MeshElement* face = aMesh->FindElement(id))
+              {
+                if (face->GetType() == SMDSAbs_Face) {
+                  int xClick, yClick; // Last event (move or left button bown) position
+                  myRWInteractor->GetDevice()->GetEventPosition(xClick, yClick);
+                  gp_XYZ faceNode(0, 0, 0);
+                  SMDS_Mesh tmp;
+                  double Ni[3];
+                  std::vector<const SMDS_MeshNode*> tmpNodes;
+                  for (int i = 0; i < face->NbCornerNodes(); ++i) {
+                    faceNode = SMESH_NodeXYZ(face->GetNode(i));
+                    vtkInteractorObserver::ComputeWorldToDisplay(myRWInteractor->GetRenderer()->GetDevice(),
+                      faceNode.X(), faceNode.Y(), faceNode.Z(), Ni);
+                    tmpNodes.push_back(tmp.AddNode(Ni[0], Ni[1], 0));
+                  }
+                  SMDS_MeshFace* face2D = tmp.AddPolygonalFace(tmpNodes);
+                  gp_Pnt point(double(xClick), double(yClick), 0);
+                  gp_XYZ closestPnt;
+                  double dist = SMESH_MeshAlgos::GetDistance(face2D, point, &closestPnt);
+                  double xPick = 0, yPick = 0;
+                  if (dist < TOLERANCE) {
+                    xPick = xClick;
+                    yPick = yClick;
+                  }
+                  else {
+                    xPick = closestPnt.X();
+                    yPick = closestPnt.Y();
+                  }
+                  myFacePicker->Pick(xPick, yPick, 0.0, myRWInteractor->GetRenderer()->GetDevice());
+                  double closest[3];
+                  myFacePicker->GetPickPosition(closest);
+                  myUpdateDestination = true;
+                  myDlg->myDestinationX->SetValue(closest[0]);
+                  myDlg->myDestinationY->SetValue(closest[1]);
+                  myDlg->myDestinationZ->SetValue(closest[2]);
+                  myUpdateDestination = false;
+                  redisplayPreview();
+                }
+              }
+            }
+          }
+        }
+      }
+      else {
+        double* aCoord = (double*)theCallData;
+        myUpdateDestination = true;
+        myDlg->myDestinationX->SetValue(aCoord[0]);
+        myDlg->myDestinationY->SetValue(aCoord[1]);
+        myDlg->myDestinationZ->SetValue(aCoord[2]);
+        myUpdateDestination = false;
+        redisplayPreview();
+      }
+    }
+  }
+}
+
+//================================================================================
+/*
+* \brief Process LeftButtonPressEvent event: activate interactive selection
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnFaceOp::processInteractorEvents(unsigned long theEvent, void* theCallData)
+{
+  (void*)theCallData;
+  if (theEvent == vtkCommand::LeftButtonPressEvent && myDlg->myDestBtn->isChecked()) {
+    bool control = myRWInteractor->GetDevice()->GetControlKey();
+    bool shift = myRWInteractor->GetDevice()->GetControlKey();
+    SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(mySMESHGUI);
+    if (svtkViewWindow && !shift && !control) {
+      QString msg;
+      if (isValid(msg)) {
+        svtkViewWindow->activateInteractiveSelection();
+      }
+    }
+  }
+}
index 7dc88647acc842513d1af9e469b0cc9f2af19c9d..b7c5a1e83437e71cc7b05a62942d2ca548dfd089 100644 (file)
@@ -30,7 +30,7 @@
 #include "SMESH_SMESHGUI.hxx"
 
 #include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
 
 class QButtonGroup;
 class QCheckBox;
@@ -41,12 +41,13 @@ class QRadioButton;
 class SMESHGUI_SpinBox;
 class SMESHGUI_MeshEditPreview;
 class SMESHGUI_AddNodeOnFaceDlg;
+class vtkCellPicker;
 
 /*!
  * \brief Operation to split a face into triangles by creating a new node
  *        on the face and connecting it to the face nodes
  */
-class SMESHGUI_EXPORT SMESHGUI_AddNodeOnFaceOp: public SMESHGUI_SelectionOp
+class SMESHGUI_EXPORT SMESHGUI_AddNodeOnFaceOp: public SMESHGUI_InteractiveOp
 {
   Q_OBJECT
 
@@ -58,13 +59,20 @@ public:
 
 protected:
 
-  virtual void                  startOperation();
-  virtual void                  stopOperation();
+  virtual void                  startOperation() override;
+  virtual void                  stopOperation() override;
 
-  virtual void                  activateSelection();
+  virtual void                  activateSelection() override;
 
   bool                          isValid( QString& );
 
+  virtual void                   processStyleEvents(unsigned long event,
+                                                    void* calldata)  override;
+
+  virtual void                   processInteractorEvents(unsigned long event,
+                                                         void* calldata) override;
+
+
 protected slots:
   virtual bool                  onApply();
 
@@ -73,9 +81,11 @@ private slots:
   void                          redisplayPreview();
   void                          onSelTypeChange();
   void                          onTextChange( const QString& );
-  void                          onDestCoordChanged();
+//  void                          onDestCoordChanged();
   void                          onOpenView();
   void                          onCloseView();
+  void                          pointLocationChanged(bool);
+  void                          onDestCoordChanged();
 
 private:
   SMESHGUI_AddNodeOnFaceDlg*    myDlg;
@@ -87,6 +97,7 @@ private:
   bool                          myNoPreview;
   bool                          myUpdateDestination;
   bool                          myDestCoordChanged;
+  vtkCellPicker*                myFacePicker;      
 };
 
 /*!
@@ -112,6 +123,7 @@ private:
   SMESHGUI_SpinBox*             myDestinationX;
   SMESHGUI_SpinBox*             myDestinationY;
   SMESHGUI_SpinBox*             myDestinationZ;
+  QCheckBox*                    myPointOnFace;
   QCheckBox*                    myPreviewChkBox;
 
   QString                       myHelpFileName;
index 81aac2703377a261ceb8539654d795304927c95c..d400b45c728d0af836bcc28db79af5443027ad04 100644 (file)
@@ -44,6 +44,9 @@
 #include <SUIT_ResourceMgr.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
+#include <SVTK_RenderWindowInteractor.h>
+#include <SVTK_Renderer.h>
+#include <SVTK_Event.h>
 #include <SalomeApp_Tools.h>
 
 // Qt includes
 
 // VTK includes
 #include <vtkProperty.h>
+#include <vtkInteractorStyle.h>
+#include <vtkGenericRenderWindowInteractor.h>
+#include <vtkInteractorObserver.h>
+#include <vtkLine.h>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -70,6 +77,8 @@
 #define SPACING 6
 #define MARGIN  11
 
+#define SPIN_TOLERANCE 1e-3
+
 //=======================================================================
 /*!
  * \brief Dialog to split a diagonal of a quadrangle formed by two adjacent triangles
@@ -135,8 +144,7 @@ QWidget* SMESHGUI_AddNodeOnSegmentDlg::createMainFrame (QWidget* theParent)
 
   myPositionSpin = new SMESHGUI_SpinBox(positionGrp);
   myPositionSpin->setReadOnly(false);
-  const double tol = 1e-3;
-  myPositionSpin->RangeStepAndValidator( tol, 1-tol, 0.1, "length_precision");
+  myPositionSpin->RangeStepAndValidator(SPIN_TOLERANCE, 1- SPIN_TOLERANCE, 0.1, "length_precision");
 
   QGridLayout* positionLayout = new QGridLayout(positionGrp);
   positionLayout->setMargin(MARGIN);
@@ -193,7 +201,8 @@ void SMESHGUI_AddNodeOnSegmentDlg::ButtonToggled (bool on)
  */
 //================================================================================
 
-SMESHGUI_AddNodeOnSegmentOp::SMESHGUI_AddNodeOnSegmentOp()
+SMESHGUI_AddNodeOnSegmentOp::SMESHGUI_AddNodeOnSegmentOp() :
+  SMESHGUI_InteractiveOp()
 {
   mySimulation = 0;
   mySMESHGUI = 0;
@@ -224,7 +233,17 @@ void SMESHGUI_AddNodeOnSegmentOp::onSelTypeChange()
   }
   else if ( myDlg->myPositionBtn->isChecked() )
   {
-    // TODO: activate picking a point on a selected segment
+    if (SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
+      QString msg;
+      SMESH::smIdType node1 = 0, node2 = 0;
+      if (isValid(msg, node1, node2)) {
+        //Disconnect selectionChanged to keep selected element
+        disconnect(selectionMgr(), SIGNAL(selectionChanged()), this, SLOT(onSelectionDone()));
+        // Set selection mode to ActorSelection to avoid element's prehighlight during interactive selection
+        setSelectionMode(ActorSelection);
+        connect(selectionMgr(), SIGNAL(selectionChanged()), SLOT(onSelectionDone()));
+      }      
+    }
   }
   else
   {
@@ -257,10 +276,13 @@ void SMESHGUI_AddNodeOnSegmentOp::startOperation()
   aProp->Delete();
 
   SMESHGUI_SelectionOp::startOperation(); // this method should be called only after filter creation
+  SMESHGUI_InteractiveOp::startOperation();
   myDlg->mySegment->setText("");
   myDlg->myPositionSpin->SetValue(0.5);
   myDlg->myPositionSpin->setReadOnly(false);
 
+  addObserver();
+
   myDlg->show();
 
   onSelectionDone(); // init myMeshActor
@@ -291,11 +313,12 @@ void SMESHGUI_AddNodeOnSegmentOp::stopOperation()
   disconnect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   //selectionMgr()->removeFilter( myFilter );
   SMESHGUI_SelectionOp::stopOperation();
+  removeObserver();
 }
 
 //================================================================================
 /*!
- * \brief perform it's intention action: move or create a node
+ * \brief perform it's intention action: create a node on a segment
  */
 //================================================================================
 
@@ -603,3 +626,76 @@ LightApp_Dialog* SMESHGUI_AddNodeOnSegmentOp::dlg() const
   return myDlg;
 }
 
+//================================================================================
+/*
+* \brief Process InteractiveSelectionChanged event
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnSegmentOp::processStyleEvents(unsigned long theEvent, void* theCallData) 
+{
+  (void*)theCallData;
+  QString msg;
+  SMESH::smIdType node1 = 0, node2 = 0;
+  if (isValid(msg, node1, node2)) {
+    if (theEvent == SVTK::InteractiveSelectionChanged) {
+      if (SMDS_Mesh* mesh = myMeshActor->GetObject()->GetMesh())
+        if(myRWInteractor && myRWInteractor->GetDevice() && myInteractorStyle) {
+        {
+          double N1[3];
+          double N2[3];
+          double pos;
+          double N1_SC[3];
+          double N2_SC[3];
+          double xyz[3];
+          double closest[3];
+
+          const SMDS_MeshNode* n1 = mesh->FindNode(node1);
+          const SMDS_MeshNode* n2 = mesh->FindNode(node2);
+          int xClick, yClick; // Last event (move or left button down) position
+          myRWInteractor->GetDevice()->GetEventPosition(xClick, yClick);
+
+          n1->GetXYZ(N1);
+          n2->GetXYZ(N2);
+          // Get 2D screen coordinates of each node
+          vtkInteractorObserver::ComputeWorldToDisplay(myRWInteractor->GetRenderer()->GetDevice(),
+            N1[0], N1[1], N1[2], N1_SC);
+          vtkInteractorObserver::ComputeWorldToDisplay(myRWInteractor->GetRenderer()->GetDevice(),
+            N2[0], N2[1], N2[2], N2_SC);
+          N1_SC[2] = N2_SC[2] = xyz[2] = 0;
+          xyz[0] = static_cast<double>(xClick);
+          xyz[1] = static_cast<double>(yClick);
+          // Parametric position of selected point on a line
+          vtkLine::DistanceToLine(xyz, N1_SC, N2_SC, pos, closest);
+          if (pos < 0)
+            pos = SPIN_TOLERANCE;
+          else if (pos > 1.0)
+            pos = 1.0 - SPIN_TOLERANCE;
+          myDlg->myPositionSpin->SetValue(pos);
+          redisplayPreview();
+        }
+      }
+    }
+  }
+}
+
+//================================================================================
+/*
+* \brief Process LeftButtonPressEvent event: activate interactive selection
+*/
+//================================================================================
+void SMESHGUI_AddNodeOnSegmentOp::processInteractorEvents(unsigned long theEvent, void* theCallData) 
+{
+  (void*)theCallData;
+  if (theEvent == vtkCommand::LeftButtonPressEvent && myDlg->myPositionBtn->isChecked()) {
+    bool control = myRWInteractor->GetDevice()->GetControlKey();
+    bool shift = myRWInteractor->GetDevice()->GetControlKey();
+    SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(mySMESHGUI);
+    if (svtkViewWindow  && !shift && ! control) {
+      QString msg;
+      SMESH::smIdType node1 = 0, node2 = 0;
+      if (isValid(msg, node1, node2)) {
+        svtkViewWindow->activateInteractiveSelection();
+      }
+    }
+  }
+}
\ No newline at end of file
index 7c9caaca8e9e932ea27f2f50f5552258a60fd9ad..bdf7569552b47458ac77b5d87c9740d1ea0737cb 100644 (file)
@@ -27,7 +27,7 @@
 #define SMESHGUI_AddNodeOnSegmentDLG_H
 
 #include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
 
 class QButtonGroup;
 class QCheckBox;
@@ -42,7 +42,7 @@ class SMESHGUI_AddNodeOnSegmentDlg;
 /*!
  * \brief Operation to make a mesh pass through a point
  */
-class SMESHGUI_EXPORT SMESHGUI_AddNodeOnSegmentOp: public SMESHGUI_SelectionOp
+class SMESHGUI_EXPORT SMESHGUI_AddNodeOnSegmentOp: public SMESHGUI_InteractiveOp
 {
   Q_OBJECT
 
@@ -54,22 +54,28 @@ public:
 
 protected:
 
-  virtual void                   startOperation();
-  virtual void                   stopOperation();
+  virtual void                   startOperation() override;
+  virtual void                   stopOperation() override;
 
   virtual void                   activateSelection();
 
   bool                           isValid( QString&, SMESH::smIdType& n1, SMESH::smIdType& n2 );
 
+  virtual void                   processStyleEvents(unsigned long event,
+    void* calldata)  override;
+
+  virtual void                   processInteractorEvents(unsigned long event,
+    void* calldata) override;
+
+
 protected slots:
-  virtual bool                   onApply();
+  virtual bool                   onApply() override;
+
 
 private slots:
   void                           onSelectionDone();
   void                           redisplayPreview();
   void                           onTextChange( const QString& );
-  void                           onPositionClick();
-  void                           onPositionChanged();
   void                           onSelTypeChange();
   void                           onOpenView();
   void                           onCloseView();
diff --git a/src/SMESHGUI/SMESHGUI_InteractiveOp.cxx b/src/SMESHGUI/SMESHGUI_InteractiveOp.cxx
new file mode 100644 (file)
index 0000000..565fa3d
--- /dev/null
@@ -0,0 +1,181 @@
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+
+// File   : SMESHGUI_InteractiveOp.cxx
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S.
+
+// SMESH includes
+//
+#include "SMESHGUI.h"
+#include "SMESHGUI_InteractiveOp.h"
+#include "SMESHGUI_VTKUtils.h"
+
+// GUI includes
+#include <SVTK_ViewWindow.h>
+#include <SVTK_RenderWindowInteractor.h>
+#include <SVTK_Event.h>
+
+// VTK includes
+#include <vtkInteractorStyle.h>
+#include <vtkCallbackCommand.h>
+#include <vtkGenericRenderWindowInteractor.h>
+#include <vtkInteractorObserver.h>
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_InteractiveOp::SMESHGUI_InteractiveOp() :
+  SMESHGUI_SelectionOp(),
+  myInteractorStyle(0),
+  myRWInteractor(0),
+  myStyleEventCallbackCommand(vtkCallbackCommand::New()),
+  myInteractorStypePriority(0.0),
+  myInteractorEventCallbackCommand(vtkCallbackCommand::New()),
+  myInteractorPriority(1.0)
+{
+  myStyleEventCallbackCommand->Delete();
+  myStyleEventCallbackCommand->SetClientData(this);
+  myStyleEventCallbackCommand->SetCallback(SMESHGUI_InteractiveOp::ProcessStyleEvents);
+
+  myInteractorEventCallbackCommand->Delete();
+  myInteractorEventCallbackCommand->SetClientData(this);
+  myInteractorEventCallbackCommand->SetCallback(SMESHGUI_InteractiveOp::ProcessInteractorEvents);
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+SMESHGUI_InteractiveOp::~SMESHGUI_InteractiveOp() 
+{
+}
+
+//=======================================================================
+// function : addObserver()
+// purpose  : Add VTK observers to process SVTK_InteractorStyle and vtkGenericRenderWindowInteractor events
+//======================================================================
+void SMESHGUI_InteractiveOp::addObserver()
+{
+  if (myInteractorStyle && !myInteractorStyle->HasObserver(SVTK::InteractiveSelectionChanged, myStyleEventCallbackCommand.GetPointer())) {
+    myInteractorStyle->AddObserver(SVTK::InteractiveSelectionChanged, myStyleEventCallbackCommand.GetPointer(),
+      myInteractorStypePriority);
+  }
+  if (myRWInteractor && myRWInteractor->GetDevice() &&
+    !myRWInteractor->GetDevice()->HasObserver(vtkCommand::LeftButtonPressEvent, myInteractorEventCallbackCommand.GetPointer())) {
+    myRWInteractor->GetDevice()->AddObserver(vtkCommand::LeftButtonPressEvent, myInteractorEventCallbackCommand.GetPointer(),
+      myInteractorPriority);
+  }
+}
+
+//=======================================================================
+// function : removeObserver()
+// purpose  : Remove VTK observers
+//======================================================================
+void SMESHGUI_InteractiveOp::removeObserver() {
+  if (myInteractorStyle && myInteractorStyle->HasObserver(SVTK::InteractiveSelectionChanged, myStyleEventCallbackCommand.GetPointer())) {
+    myInteractorStyle->RemoveObserver(myStyleEventCallbackCommand.GetPointer());
+  }
+  if (myRWInteractor && myRWInteractor->GetDevice() &&
+    myRWInteractor->GetDevice()->HasObserver(vtkCommand::LeftButtonPressEvent, myInteractorEventCallbackCommand.GetPointer())) {
+    myRWInteractor->GetDevice()->RemoveObserver(myInteractorEventCallbackCommand.GetPointer());
+  }
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose  : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+
+void SMESHGUI_InteractiveOp::startOperation()
+{
+  SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(getSMESHGUI());
+  if (svtkViewWindow) {
+    myInteractorStyle = svtkViewWindow->GetInteractorStyle();
+    myRWInteractor = svtkViewWindow->GetInteractor();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Process interactor style events
+          Static method. Used by vtkCallbackCommand->SetCallback method.
+ */
+ //===============================================================================
+void SMESHGUI_InteractiveOp::ProcessStyleEvents(vtkObject* vtkNotUsed(theObject),
+  unsigned long theEvent,
+  void* theClientData,
+  void* theCallData) {
+  SMESHGUI_InteractiveOp* self = reinterpret_cast<SMESHGUI_InteractiveOp*>(theClientData);
+  if (self)
+    self->processStyleEvents(theEvent, theCallData);
+}
+
+//================================================================================
+/*!
+ * \brief Process Generic Render Window Interactor events.
+          Static method. Used by vtkCallbackCommand->SetCallback method.
+ */
+ //===============================================================================
+void SMESHGUI_InteractiveOp::ProcessInteractorEvents(vtkObject* vtkNotUsed(theObject),
+  unsigned long theEvent,
+  void* theClientData,
+  void* theCallData) {
+  SMESHGUI_InteractiveOp* self = reinterpret_cast<SMESHGUI_InteractiveOp*>(theClientData);
+  if (self)
+    self->processInteractorEvents(theEvent, theCallData);
+}
+
+//================================================================================
+/*!
+ * \brief Process interactor style events ()
+          Virtual method. Should be overridden in inherited classes.
+ */
+ //===============================================================================
+
+void SMESHGUI_InteractiveOp::processStyleEvents(unsigned long theEvent, void* theCallData) {
+}
+
+//================================================================================
+/*!
+ * \brief Process Generic Render Window Interactor events.
+          Virtual method. Should be overridden in inherited classes.
+ */
+ //===============================================================================
+void SMESHGUI_InteractiveOp::processInteractorEvents(unsigned long theEvent, void* theCallData)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Deactivate current operation in active VTK viewer
+ */
+ //===============================================================================
+void SMESHGUI_InteractiveOp::deactivateCurrentViewOperation() {
+  if (SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(getSMESHGUI())) {
+    svtkViewWindow->deactivateCurrectOperation();
+  }
+}
\ No newline at end of file
diff --git a/src/SMESHGUI/SMESHGUI_InteractiveOp.h b/src/SMESHGUI/SMESHGUI_InteractiveOp.h
new file mode 100644 (file)
index 0000000..65894e3
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+
+// File   : SMESHGUI_InteractiveOp.h
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S.
+//
+
+#pragma once
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_SelectionOp.h"
+
+// VTK includes
+#include <vtkSmartPointer.h>
+
+/*
+  Class       : SMESHGUI_InteractiveOp
+  Description : Base operation for all interactive operations in the VTK 3D Viewer
+*/
+
+class vtkInteractorStyle;
+class vtkCallbackCommand;
+class vtkObject;
+class SVTK_RenderWindowInteractor;
+
+class SMESHGUI_EXPORT SMESHGUI_InteractiveOp: public SMESHGUI_SelectionOp {
+  Q_OBJECT
+public:
+  SMESHGUI_InteractiveOp();
+  virtual ~SMESHGUI_InteractiveOp();
+
+  virtual void deactivateCurrentViewOperation();
+
+protected:
+  virtual void                   startOperation() override;
+
+  static void                    ProcessStyleEvents(vtkObject* object,
+                                                    unsigned long event,
+                                                    void* clientdata,
+                                                    void* calldata);
+  virtual void                   processStyleEvents(unsigned long event,
+                                                    void* calldata);
+
+  static void                    ProcessInteractorEvents(vtkObject* object,
+                                                         unsigned long event,
+                                                         void* clientdata,
+                                                          void* calldata);
+  virtual void                   processInteractorEvents(unsigned long event,
+                                                         void* calldata);
+
+  virtual void addObserver();
+  virtual void removeObserver();
+
+
+protected:
+  vtkInteractorStyle*           myInteractorStyle;
+  SVTK_RenderWindowInteractor*  myRWInteractor;
+
+  // Priority at which  events are processed:
+  //   Interactor Stype events
+  double myInteractorStypePriority;
+  //   Interactor events
+  double myInteractorPriority;
+
+  // Used to process events
+  vtkSmartPointer<vtkCallbackCommand> myStyleEventCallbackCommand;
+  vtkSmartPointer<vtkCallbackCommand> myInteractorEventCallbackCommand;
+};
index 5745d8483dacbdcd28f7c6c8b6c18e415420f08b..bf33fd2e12102b3eeff01b616784b463437cd794 100644 (file)
@@ -48,6 +48,9 @@
 #include <SUIT_Desktop.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
+#include <SVTK_Renderer.h>
+#include <SVTK_RenderWindowInteractor.h>
+#include <SVTK_Event.h>
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_TypeFilter.h>
 #include <SUIT_ResourceMgr.h>
 #include <QButtonGroup>
 
 // VTK includes
+#include <vtkObject.h>
 #include <vtkProperty.h>
+#include <vtkGenericRenderWindowInteractor.h>
+#include <vtkInteractorObserver.h>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -89,6 +95,8 @@ namespace
   enum { MANUAL_MODE = 0, SEARCH_MODE, INTERACTIVE_MODE };
 }
 
+//#define SELECTION_PRECISION 4
+
 //=======================================================================
 /*!
  * \brief Dialog to publish a sub-shape of the mesh main shape
@@ -125,7 +133,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
   QPixmap iconMoveWithoutNode (rm->loadPixmap("SMESH", tr("ICON_DLG_MOVE_WITHOUT_NODE")));
   QPixmap iconMoveInteractive (rm->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE_INTERACTIVE")));
   QPixmap iconSelect          (rm->loadPixmap("SMESH", tr("ICON_SELECT")));
-
+  
   // constructor
   QGroupBox* aPixGrp = new QGroupBox(tr("MOVE_NODE"), this);
   aPixGrp->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
@@ -349,7 +357,6 @@ void SMESHGUI_MakeNodeAtPointDlg::ConstructorsClicked (int constructorId)
       break;
     }
   }
-
   QApplication::instance()->processEvents();
   myMainFrame->hide();
   myMainFrame->show();
@@ -363,7 +370,8 @@ void SMESHGUI_MakeNodeAtPointDlg::ConstructorsClicked (int constructorId)
 */
 //================================================================================
 
-SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp(int defaultConstructor)
+SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp(int defaultConstructor) : 
+  SMESHGUI_InteractiveOp()
 {
   myDefaultConstructor = defaultConstructor;
   mySimulation = 0;
@@ -385,7 +393,7 @@ SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp(int defaultConstructor)
   connect(myDlg->myDestDZ,        SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
   connect(myDlg->myId,            SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
   connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),              SLOT(redisplayPreview()));
-  connect(myDlg->myButtonGroup,   SIGNAL (buttonClicked(int)),         SLOT(redisplayPreview()));
+  connect(myDlg->myButtonGroup,   SIGNAL (buttonClicked(int)),         SLOT(constructorChanged()));
 
   // IPAL22913: TC6.5.0: selected in "Move node" dialog box node is not highlighted
   // note: this slot seems to be lost together with removed obsolete SMESHGUI_MoveNodesDlg class
@@ -419,6 +427,7 @@ void SMESHGUI_MakeNodeAtPointOp::onDestCoordChanged()
   myDestCoordChanged = true;
 }
 
+
 //=======================================================================
 // function : startOperation()
 // purpose  : Init dialog fields, connect signals and slots, show dialog
@@ -432,7 +441,8 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
   // init simulation with a current View
   if ( mySimulation ) delete mySimulation;
   mySMESHGUI = getSMESHGUI();
-  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ) );
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow(mySMESHGUI));
+
   connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
   connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
   vtkProperty* aProp = vtkProperty::New();
@@ -455,6 +465,7 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
   // IPAL19360
   SMESHGUI_SelectionOp::startOperation(); // this method should be called only after filter creation
   //activateSelection(); // set filters   // called inside of previous statement
+  SMESHGUI_InteractiveOp::startOperation();
   myDlg->myId->setText("");
   myDlg->myDestinationX->SetValue(0);
   myDlg->myDestinationY->SetValue(0);
@@ -470,8 +481,10 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
   myDlg->myDestDZ->setReadOnly(true);
   myDlg->myRButNodeToMove->setChecked(true);
 
-  if ( myDefaultConstructor == INTERACTIVE_MODE )
+  if ( myDefaultConstructor == INTERACTIVE_MODE ) {
+    addObserver();
     myDlg->myButtonGroup->button( INTERACTIVE_MODE )->setChecked(true);
+  }
   myDlg->ConstructorsClicked( GetConstructorId() );
 
   myDlg->show();
@@ -514,6 +527,7 @@ void SMESHGUI_MakeNodeAtPointOp::stopOperation()
   disconnect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   selectionMgr()->removeFilter( myFilter );
   SMESHGUI_SelectionOp::stopOperation();
+  removeObserver();
 }
 
 //================================================================================
@@ -871,6 +885,23 @@ void SMESHGUI_MakeNodeAtPointOp::onOpenView()
   }
 }
 
+//=================================================================================
+/*!
+ * \brief SLOT called when the creation mode is changed 
+ */
+ //=================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::constructorChanged() {
+  redisplayPreview();
+  if (GetConstructorId() == INTERACTIVE_MODE) {
+    addObserver();
+  }
+  else {
+    removeObserver();
+  }
+}
+
+
 //=================================================================================
 /*!
  * \brief SLOT called when the viewer closed
@@ -951,3 +982,54 @@ LightApp_Dialog* SMESHGUI_MakeNodeAtPointOp::dlg() const
   return myDlg;
 }
 
+
+//================================================================================
+/*
+* \brief Process InteractiveSelectionChanged event
+*/
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::processStyleEvents(unsigned long theEvent, void* theCallData) {
+  if (theEvent == SVTK::InteractiveSelectionChanged) {
+    double* aCoord = (double*)theCallData;
+    myDlg->myDestinationX->SetValue(aCoord[0]);
+    myDlg->myDestinationY->SetValue(aCoord[1]);
+    myDlg->myDestinationZ->SetValue(aCoord[2]);
+    redisplayPreview();
+  }
+}
+
+//================================================================================
+/*
+* \brief Process LeftButtonPressEvent event
+*/
+//================================================================================
+void SMESHGUI_MakeNodeAtPointOp::processInteractorEvents(unsigned long theEvent, void* theCallData) {
+  (void*)theCallData;
+  if (theEvent == vtkCommand::LeftButtonPressEvent) {
+    bool control = myRWInteractor->GetDevice()->GetControlKey();
+    bool shift = myRWInteractor->GetDevice()->GetControlKey();
+    if (GetConstructorId() == INTERACTIVE_MODE && myDlg->myDestBtn->isChecked() && !shift && !control) {
+      if (SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(SMESHGUI::GetSMESHGUI())) {
+        svtkViewWindow->activateInteractiveSelection();
+      }
+    }
+  }
+   /*
+   if ( myRWInteractor && myRWInteractor->GetDevice() && myInteractorStyle ) {
+      int xClick, yClick; // Last click position
+      myRWInteractor->GetDevice()->GetEventPosition(xClick, yClick);
+      double nodeCoords[3];
+      vtkInteractorObserver::ComputeWorldToDisplay(myRWInteractor->GetRenderer()->GetDevice(),
+                                                   myDlg->myDestinationX->GetValue(),
+                                                   myDlg->myDestinationY->GetValue(),
+                                                   myDlg->myDestinationZ->GetValue(),
+                                                   nodeCoords);
+      double rad = std::sqrt(std::pow(xClick - nodeCoords[0], 2) + std::pow(yClick - nodeCoords[1], 2));
+      if (rad < SELECTION_PRECISION) {
+        if (SVTK_ViewWindow* svtkViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
+          svtkViewWindow->activateInteractiveSelection();
+        }
+      }
+  }*/
+}
index 32cb9f0c17d5491245d814230a294d0b02421ad3..945f08f6ed025dbc1e512f3071173d63dd1563b2 100644 (file)
@@ -30,7 +30,9 @@
 #include "SMESH_SMESHGUI.hxx"
 
 #include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
+
+#include <vtkSmartPointer.h>
 
 class QButtonGroup;
 class QCheckBox;
@@ -42,10 +44,11 @@ class SMESHGUI_SpinBox;
 class SMESHGUI_MeshEditPreview;
 class SMESHGUI_MakeNodeAtPointDlg;
 
+
 /*!
  * \brief Operation to make a mesh pass through a point
  */
-class SMESHGUI_EXPORT SMESHGUI_MakeNodeAtPointOp: public SMESHGUI_SelectionOp
+class SMESHGUI_EXPORT SMESHGUI_MakeNodeAtPointOp: public SMESHGUI_InteractiveOp
 {
   Q_OBJECT
 
@@ -57,13 +60,19 @@ public:
 
 protected:
 
-  virtual void                   startOperation();
-  virtual void                   stopOperation();
+  virtual void                   startOperation() override;
+  virtual void                   stopOperation() override;
 
-  virtual void                   activateSelection();
+  virtual void                   activateSelection() override;
 
   bool                           isValid( QString& );
 
+  virtual void                   processStyleEvents(unsigned long event,
+                                                    void* calldata)  override;
+
+  virtual void                   processInteractorEvents(unsigned long event,
+                                                         void* calldata) override;
+
 protected slots:
   virtual bool                   onApply();
 
@@ -75,6 +84,7 @@ private slots:
   void                           onDestCoordChanged();
   void                           onOpenView();
   void                           onCloseView();
+  void                           constructorChanged();
 
 private:
   int                           GetConstructorId();
index f5db909ea6d9ddcb8a5e676c9abb49f7a7aa6148..7c52712ec00f97ff10885a4a6a8fc923c6916f87 100644 (file)
@@ -6865,6 +6865,10 @@ Please specify them and try again</translation>
         <source>XYZ_GROUP</source>
         <translation>Node location by mouse click</translation>
     </message>
+    <message>
+        <source>XYZ_NODE_ON_FACE</source>
+        <translation>Node on face</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_AddNodeOnFaceOp</name>