+++ /dev/null
-1) partial Fix of QuadFromMedialAxis algo
-2) Begin fix 19982 EDF 21954 - Compute mesh fails
-
\ No newline at end of file
SMESHGUI_RemoveNodeReconnectionDlg.h
SMESHGUI_AddNodeOnSegmentDlg.h
SMESHGUI_AddNodeOnFaceDlg.h
+ SMESHGUI_InteractiveOp.h
)
# header files / no moc processing
SMESHGUI_RemoveNodeReconnectionDlg.cxx
SMESHGUI_AddNodeOnSegmentDlg.cxx
SMESHGUI_AddNodeOnFaceDlg.cxx
+ SMESHGUI_InteractiveOp.cxx
)
# sources / to compile
#include <SMESH_Actor.h>
#include <SMESH_ActorUtils.h>
#include <SMESH_TypeDefs.hxx>
+#include <SMESH_MeshAlgos.hxx>
// SALOME GUI includes
#include <LightApp_SelectionMgr.h>
#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>
#define SPACING 6
#define MARGIN 11
+#define TOLERANCE 1e-3
+
//=======================================================================
/*!
* \brief Dialog to publish a sub-shape of the mesh main shape
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);
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 );
*/
//================================================================================
-SMESHGUI_AddNodeOnFaceOp::SMESHGUI_AddNodeOnFaceOp()
+SMESHGUI_AddNodeOnFaceOp::SMESHGUI_AddNodeOnFaceOp() :
+ SMESHGUI_InteractiveOp()
{
mySimulation = 0;
mySMESHGUI = 0;
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();
+
}
//================================================================================
}
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
{
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();
disconnect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
disconnect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
SMESHGUI_SelectionOp::stopOperation();
+ removeObserver();
}
//================================================================================
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);
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 (...) {
}
{
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();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
//================================================================================
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();
+ }
+ }
+ }
+}
#include "SMESH_SMESHGUI.hxx"
#include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
class QButtonGroup;
class QCheckBox;
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
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();
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;
bool myNoPreview;
bool myUpdateDestination;
bool myDestCoordChanged;
+ vtkCellPicker* myFacePicker;
};
/*!
SMESHGUI_SpinBox* myDestinationX;
SMESHGUI_SpinBox* myDestinationY;
SMESHGUI_SpinBox* myDestinationZ;
+ QCheckBox* myPointOnFace;
QCheckBox* myPreviewChkBox;
QString myHelpFileName;
#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>
#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
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);
*/
//================================================================================
-SMESHGUI_AddNodeOnSegmentOp::SMESHGUI_AddNodeOnSegmentOp()
+SMESHGUI_AddNodeOnSegmentOp::SMESHGUI_AddNodeOnSegmentOp() :
+ SMESHGUI_InteractiveOp()
{
mySimulation = 0;
mySMESHGUI = 0;
}
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
{
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
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
*/
//================================================================================
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
#define SMESHGUI_AddNodeOnSegmentDLG_H
#include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
class QButtonGroup;
class QCheckBox;
/*!
* \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
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();
--- /dev/null
+// 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
--- /dev/null
+// 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;
+};
#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>
enum { MANUAL_MODE = 0, SEARCH_MODE, INTERACTIVE_MODE };
}
+//#define SELECTION_PRECISION 4
+
//=======================================================================
/*!
* \brief Dialog to publish a sub-shape of the mesh main shape
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 ) );
break;
}
}
-
QApplication::instance()->processEvents();
myMainFrame->hide();
myMainFrame->show();
*/
//================================================================================
-SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp(int defaultConstructor)
+SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp(int defaultConstructor) :
+ SMESHGUI_InteractiveOp()
{
myDefaultConstructor = defaultConstructor;
mySimulation = 0;
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
myDestCoordChanged = true;
}
+
//=======================================================================
// function : startOperation()
// purpose : Init dialog fields, connect signals and slots, show dialog
// 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();
// 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);
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();
disconnect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
selectionMgr()->removeFilter( myFilter );
SMESHGUI_SelectionOp::stopOperation();
+ removeObserver();
}
//================================================================================
}
}
+//=================================================================================
+/*!
+ * \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
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();
+ }
+ }
+ }*/
+}
#include "SMESH_SMESHGUI.hxx"
#include "SMESHGUI_Dialog.h"
-#include "SMESHGUI_SelectionOp.h"
+#include "SMESHGUI_InteractiveOp.h"
+
+#include <vtkSmartPointer.h>
class QButtonGroup;
class QCheckBox;
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
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();
void onDestCoordChanged();
void onOpenView();
void onCloseView();
+ void constructorChanged();
private:
int GetConstructorId();
<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>