1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : SMESHGUI_ReorientFacesDlg.cxx
24 // Author : Edward AGAPOV, Open CASCADE S.A.S.
27 #include "SMESHGUI_ReorientFacesDlg.h"
30 #include "SMESHGUI_IdValidator.h"
31 #include "SMESHGUI_MeshUtils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_SpinBox.h"
34 #include "SMESHGUI_MeshEditPreview.h"
36 #include <SMDS_Mesh.hxx>
37 #include <SMESH_Actor.h>
38 #include <SMESH_ActorUtils.h>
39 #include <SMESH_NumberFilter.hxx>
40 #include <SMESH_LogicalFilter.hxx>
41 #include <SMESH_TypeFilter.hxx>
43 // SALOME GEOM includes
46 // SALOME GUI includes
47 #include <LightApp_SelectionMgr.h>
48 #include <SALOME_ListIO.hxx>
49 #include <SUIT_Desktop.h>
50 #include <SUIT_MessageBox.h>
51 #include <SUIT_OverrideCursor.h>
52 #include <SUIT_ResourceMgr.h>
53 #include <SVTK_ViewModel.h>
54 #include <SVTK_ViewWindow.h>
55 #include <SalomeApp_Tools.h>
56 #include <SalomeApp_TypeFilter.h>
58 // SALOME KERNEL includes
59 #include <SALOMEDS_SObject.hxx>
62 #include <BRep_Tool.hxx>
63 #include <TColStd_MapOfInteger.hxx>
64 #include <TColgp_SequenceOfXYZ.hxx>
65 #include <TopoDS_Vertex.hxx>
70 #include <QGridLayout>
71 #include <QHBoxLayout>
72 #include <QVBoxLayout>
74 #include <QPushButton>
76 #include <QRadioButton>
78 #include <QButtonGroup>
81 #include <vtkProperty.h>
84 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
92 enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_FACE_GROUPS, CONSTRUCTOR_VOLUME,
93 EObject, EPoint, EFace, EDirection, ERefGroups };
95 //=======================================================================
97 * \brief Dialog to reorient faces according to vector
99 //=======================================================================
101 SMESHGUI_ReorientFacesDlg::SMESHGUI_ReorientFacesDlg()
102 : SMESHGUI_Dialog( 0, false, true )
104 setWindowTitle(tr("CAPTION"));
106 QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
107 aDlgLay->setMargin(0);
108 aDlgLay->setSpacing(SPACING);
110 QWidget* aMainFrame = createMainFrame (mainFrame());
112 aDlgLay->addWidget(aMainFrame);
114 aDlgLay->setStretchFactor(aMainFrame, 1);
117 //================================================================================
119 * \brief Create frame containing dialog's input fields
121 //================================================================================
123 QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent)
125 QWidget* aFrame = new QWidget(theParent);
129 QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT")));
130 QPixmap iconReoriFace (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE")));
131 QPixmap iconReoriGroups(resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_GROUPS")));
132 QPixmap iconReoriVolum (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_VOLUME")));
134 QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame);
135 myConstructorGrp = new QButtonGroup(aConstructorBox);
136 QHBoxLayout* aConstructorGrpLayout = new QHBoxLayout(aConstructorBox);
137 aConstructorGrpLayout->setMargin(MARGIN);
138 aConstructorGrpLayout->setSpacing(SPACING);
140 QRadioButton* aPntBut = new QRadioButton(aConstructorBox);
141 aPntBut->setIcon(iconReoriPoint);
142 aPntBut->setChecked(true);
143 aConstructorGrpLayout->addWidget(aPntBut);
144 myConstructorGrp->addButton(aPntBut, CONSTRUCTOR_POINT);
146 QRadioButton* aFaceBut= new QRadioButton(aConstructorBox);
147 aFaceBut->setIcon(iconReoriFace);
148 aConstructorGrpLayout->addWidget(aFaceBut);
149 myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE);
151 QRadioButton* aGroupBut= new QRadioButton(aConstructorBox);
152 aGroupBut->setIcon(iconReoriGroups);
153 aConstructorGrpLayout->addWidget(aGroupBut);
154 myConstructorGrp->addButton(aGroupBut, CONSTRUCTOR_FACE_GROUPS);
156 QRadioButton* aVolBut= new QRadioButton(aConstructorBox);
157 aVolBut->setIcon(iconReoriVolum);
158 aConstructorGrpLayout->addWidget(aVolBut);
159 myConstructorGrp->addButton(aVolBut, CONSTRUCTOR_VOLUME);
161 // Create other controls
163 setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
165 createObject( tr("OBJECT") , aFrame, EObject );
166 createObject( tr("POINT") , aFrame, EPoint );
167 createObject( tr("FACE") , aFrame, EFace );
168 createObject( tr("DIRECTION"), aFrame, EDirection );
169 createObject( tr("VOLUMES"), aFrame, ERefGroups );
170 setNameIndication( EObject, ListOfNames );
171 setNameIndication( EFace, OneName );
172 setNameIndication( ERefGroups, ListOfNames );
173 setReadOnly( EFace, false );
174 if ( QLineEdit* le = qobject_cast<QLineEdit*>( objectWg( EFace, Control ) ))
175 le->setValidator( new SMESHGUI_IdValidator( this,1 ));
177 int width = aFaceBut->fontMetrics().width( tr("DIRECTION"));
178 objectWg( EDirection, Label )->setFixedWidth( width );
179 objectWg( EObject , Label )->setFixedWidth( width );
180 objectWg( EPoint , Label )->setFixedWidth( width );
181 objectWg( EFace , Label )->setFixedWidth( width );
183 myOutsideChk = new QCheckBox( tr("OUTSIDE_VOLUME_NORMAL"), aFrame);
184 myOutsideChk->setChecked( true );
186 QLabel* aXLabel = new QLabel(tr("SMESH_X"), aFrame);
187 myX = new SMESHGUI_SpinBox(aFrame);
188 QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aFrame);
189 myY = new SMESHGUI_SpinBox(aFrame);
190 QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aFrame);
191 myZ = new SMESHGUI_SpinBox(aFrame);
193 myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
194 myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
195 myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
200 QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aFrame);
201 myDX = new SMESHGUI_SpinBox(aFrame);
202 QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aFrame);
203 myDY = new SMESHGUI_SpinBox(aFrame);
204 QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aFrame);
205 myDZ = new SMESHGUI_SpinBox(aFrame);
210 myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision");
211 myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision");
212 myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision");
214 width = Max( aFaceBut->fontMetrics().width( tr("SMESH_X")),
215 aFaceBut->fontMetrics().width( tr("SMESH_DX")));
216 aXLabel->setFixedWidth( width );
217 aYLabel->setFixedWidth( width );
218 aZLabel->setFixedWidth( width );
219 aDXLabel->setFixedWidth( width );
220 aDYLabel->setFixedWidth( width );
221 aDZLabel->setFixedWidth( width );
225 QGroupBox* anObjectGrp = new QGroupBox(tr("FACES"), aFrame);
226 QHBoxLayout* anObjectGrpLayout = new QHBoxLayout(anObjectGrp);
227 anObjectGrpLayout->setMargin(MARGIN);
228 anObjectGrpLayout->setSpacing(SPACING);
229 anObjectGrpLayout->addWidget( objectWg( EObject, Label ));
230 anObjectGrpLayout->addWidget( objectWg( EObject, Btn ));
231 anObjectGrpLayout->addWidget( objectWg( EObject, Control ));
233 myPointFrm = new QFrame(aFrame);
234 QHBoxLayout* aPointGrpLayout = new QHBoxLayout(myPointFrm);
235 aPointGrpLayout->setMargin(0);
236 objectWg( EPoint, Control )->hide();
237 aPointGrpLayout->addWidget( objectWg( EPoint, Label ) );
238 aPointGrpLayout->addWidget( objectWg( EPoint, Btn ) );
239 aPointGrpLayout->addWidget( aXLabel, 0 );
240 aPointGrpLayout->addWidget( myX, 1 );
241 aPointGrpLayout->addWidget( aYLabel, 0 );
242 aPointGrpLayout->addWidget( myY, 1 );
243 aPointGrpLayout->addWidget( aZLabel, 0 );
244 aPointGrpLayout->addWidget( myZ, 1 );
246 myFaceFrm = new QFrame(aFrame);
247 QHBoxLayout* aFaceGrpLayout = new QHBoxLayout(myFaceFrm);
248 aFaceGrpLayout->setMargin(0);
249 aFaceGrpLayout->addWidget( objectWg( EFace, Label ) );
250 aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) );
251 aFaceGrpLayout->addWidget( objectWg( EFace, Control ) );
253 myRefGroupFrm = new QFrame(aFrame);
254 QGridLayout* aRefGrpLayout = new QGridLayout(myRefGroupFrm);
255 aRefGrpLayout->setMargin(0);
256 aRefGrpLayout->setSpacing(SPACING);
257 aRefGrpLayout->addWidget( objectWg( ERefGroups, Label ), 0, 0 );
258 aRefGrpLayout->addWidget( objectWg( ERefGroups, Btn ), 0, 1 );
259 aRefGrpLayout->addWidget( objectWg( ERefGroups, Control ), 0, 2 );
260 aRefGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 );
262 myDirFrm = new QFrame(aFrame);
263 QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(myDirFrm);
264 aDirectGrpLayout->setMargin(0);
265 objectWg( EDirection, Control )->hide();
266 aDirectGrpLayout->addWidget( objectWg( EDirection, Label ) );
267 aDirectGrpLayout->addWidget( objectWg( EDirection, Btn ) );
268 aDirectGrpLayout->addWidget( aDXLabel, 0 );
269 aDirectGrpLayout->addWidget( myDX, 1 );
270 aDirectGrpLayout->addWidget( aDYLabel, 0 );
271 aDirectGrpLayout->addWidget( myDY, 1 );
272 aDirectGrpLayout->addWidget( aDZLabel, 0 );
273 aDirectGrpLayout->addWidget( myDZ, 1 );
276 QGroupBox* anOrientGrp = new QGroupBox(tr("ORIENTATION"), aFrame);
277 QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp );
278 anOrientGrpLayout->addWidget(myPointFrm);
279 anOrientGrpLayout->addWidget(myFaceFrm);
280 anOrientGrpLayout->addWidget(myRefGroupFrm);
281 anOrientGrpLayout->addWidget(myDirFrm);
284 QVBoxLayout* aLay = new QVBoxLayout(aFrame);
285 aLay->addWidget(aConstructorBox);
286 aLay->addWidget(anObjectGrp);
287 aLay->addWidget(anOrientGrp);
289 connect( myConstructorGrp, SIGNAL(buttonClicked (int)), this, SLOT(constructorChange(int)));
294 //================================================================================
296 * \brief Show point or face
298 //================================================================================
300 void SMESHGUI_ReorientFacesDlg::constructorChange(int id)
302 if ( id == CONSTRUCTOR_FACE )
305 myRefGroupFrm->hide();
308 activateObject( EFace );
310 else if ( id == CONSTRUCTOR_POINT )
313 myRefGroupFrm->hide();
316 activateObject( EPoint );
318 else // CONSTRUCTOR_VOLUME || CONSTRUCTOR_FACE_GROUPS
323 myOutsideChk->setVisible( id == CONSTRUCTOR_VOLUME );
324 myRefGroupFrm->show();
325 QAbstractButton* refButton = qobject_cast<QAbstractButton*>( objectWg( ERefGroups, Btn ));
326 refButton->setChecked( false ); // force ERefGroups activation
327 activateObject( ERefGroups );
328 setLabel( ERefGroups, id == CONSTRUCTOR_VOLUME ? "VOLUMES" : "REF_GROUPS" );
331 // minimize width of labels
332 QFontMetrics font = objectWg( EDirection, Label )->fontMetrics();
334 for ( int obj = EObject; obj <= ERefGroups; ++obj )
336 QLabel* label = qobject_cast< QLabel* >( objectWg( obj, Label ));
337 if ( label->isVisible() )
338 width = std::max( width, font.width( label->text() ));
341 for ( int obj = EObject; obj <= ERefGroups; ++obj )
343 QWidget* label = objectWg( obj, Label );
344 if ( label->isVisible() )
345 label->setFixedWidth( width );
349 //================================================================================
351 * \brief Set object label
353 //================================================================================
355 void SMESHGUI_ReorientFacesDlg::setLabel( int object, const char* text )
357 qobject_cast< QLabel* >( objectWg( object, Label ))->setText( tr( text ));
360 //================================================================================
364 //================================================================================
366 SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp()
367 :SMESHGUI_SelectionOp( ActorSelection )
369 //myVectorPreview = 0;
370 myHelpFileName = "reorient_faces.html";
372 myDlg = new SMESHGUI_ReorientFacesDlg;
373 myDlg->constructorChange( CONSTRUCTOR_POINT );
375 myRefGroupFilter = new SMESH_TypeFilter( SMESH::GROUP_VOLUME );
376 myRefSubMeshFilter = new SMESH_TypeFilter( SMESH::SUBMESH_SOLID );
377 myRefMeshFilter = new SMESH_TypeFilter( SMESH::MESH );
379 myObjects = new SMESH::ListOfIDSources();
380 myRefGroups = new SMESH::ListOfIDSources();
382 // connect signals and slots
383 connect( myDlg->objectWg( EFace, LightApp_Dialog::Control ), SIGNAL(textChanged(const QString&)),
384 this, SLOT(onTextChange(const QString&)));
387 //=======================================================================
388 // function : startOperation()
389 // purpose : Init dialog fields, connect signals and slots, show dialog
390 //=======================================================================
392 void SMESHGUI_ReorientFacesOp::startOperation()
396 SMESHGUI_SelectionOp::startOperation();
400 mySelectionMode = EObject;
401 myDlg->activateObject( EObject );
406 //================================================================================
408 * \brief Stops operation
410 //================================================================================
412 void SMESHGUI_ReorientFacesOp::stopOperation()
416 myObjectActor->SetPointRepresentation(false);
417 SMESH::RepaintCurrentView();
420 SMESHGUI_SelectionOp::stopOperation();
421 myDlg->deactivateAll();
424 //================================================================================
426 * \brief Set selection mode corresponding to a pressed selection button
428 //================================================================================
430 void SMESHGUI_ReorientFacesOp::onActivateObject( int what )
432 if ( what == mySelectionMode )
434 if ( what == ERefGroups )
435 setRefFiltersByConstructor();
439 mySelectionMode = what;
440 switch ( mySelectionMode )
444 SMESH::SetPointRepresentation(true);
445 setSelectionMode( NodeSelection );
446 SMESH::SetPickable();
449 SMESH::SetPointRepresentation(false);
450 setSelectionMode( ActorSelection );
453 SMESH::SetPointRepresentation(false);
454 setSelectionMode( ActorSelection );
455 setRefFiltersByConstructor();
458 SMESH::SetPointRepresentation(false);
459 setSelectionMode( FaceSelection );
461 SMESH::SetPickable( myObjectActor );
463 SMESH::SetPickable();
467 SMESHGUI_SelectionOp::onActivateObject( what );
469 myDlg->setLabel( EObject, onlyOneObjAllowed() ? "OBJECT" : "OBJECTS" );
472 //================================================================================
474 * \brief Creates a filter corresponding to a pressed selection button
476 //================================================================================
478 SUIT_SelectionFilter* SMESHGUI_ReorientFacesOp::createFilter( const int what ) const
484 QList<SUIT_SelectionFilter*> filters;
485 filters.append( new SMESH_TypeFilter( SMESH::MESH ));
486 filters.append( new SMESH_TypeFilter( SMESH::SUBMESH_FACE ));
487 filters.append( new SMESH_TypeFilter( SMESH::GROUP_FACE ));
488 return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
492 QList<SUIT_SelectionFilter*> filters;
493 filters << myRefGroupFilter << myRefSubMeshFilter << myRefMeshFilter;
494 return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
498 QList<SUIT_SelectionFilter*> filters;
499 filters.append( new SMESH_TypeFilter( SMESH::IDSOURCE ));
500 filters.append( new SMESH_NumberFilter( "GEOM",TopAbs_VERTEX, 1, TopAbs_VERTEX ));
501 return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
506 return new SMESH_TypeFilter( SMESH::IDSOURCE );
512 //================================================================================
514 * \brief Switch between selection of faces and volumes according to the constructor
516 //================================================================================
518 void SMESHGUI_ReorientFacesOp::setRefFiltersByConstructor()
520 if ( constructorID() == CONSTRUCTOR_VOLUME )
522 myRefMeshFilter ->setType( SMESH::MESH );// SMESH::NB_SMESH_TYPES
523 myRefGroupFilter ->setType( SMESH::GROUP_VOLUME );
524 myRefSubMeshFilter->setType( SMESH::SUBMESH_SOLID );
528 myRefMeshFilter ->setType( SMESH::NB_SMESH_TYPES ); // mesh not allowed
529 myRefGroupFilter ->setType( SMESH::GROUP_FACE );
530 myRefSubMeshFilter->setType( SMESH::SUBMESH_FACE );
534 //================================================================================
536 * \brief get data from selection
538 //================================================================================
540 void SMESHGUI_ReorientFacesOp::selectionDone()
542 if ( !myDlg->isVisible() || !myDlg->isEnabled() )
545 myDlg->clearSelection( mySelectionMode );
548 selectionMgr()->selectedObjects(aList);
549 const int nbSelected = aList.Extent();
550 if ( nbSelected == 0 )
553 if ( onlyOneObjAllowed() && nbSelected != 1 )
556 if ( mySelectionMode == ERefGroups )
558 SMESHGUI_SelectionOp::selectionDone();
562 Handle(SALOME_InteractiveObject) anIO = aList.First();
566 switch ( mySelectionMode )
568 case EObject: { // get an actor of object
570 SMESHGUI_SelectionOp::selectionDone();
571 myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
574 case EFace: { // get a face ID
576 SVTK_TIndexedMapOfVtkId faceIndices;
577 selector()->GetIndex( anIO, faceIndices );
578 if ( faceIndices.Extent() == 1 )
580 SMESH_Actor* savedActor = myObjectActor;
581 myObjectActor = 0; // to prevent work of onTextChange()
582 myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) ));
583 myObjectActor = savedActor;
585 if ( !myObjectActor )
587 myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
588 // typeById( aList.First()->getEntry(),
589 // SMESHGUI_SelectionOp::Object ),
590 myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
596 case EDirection: { // set XYZ by selected nodes or vertices
598 TColgp_SequenceOfXYZ points;
599 for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
602 GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
603 if ( !geom->_is_nil() ) {
604 TopoDS_Vertex aShape;
605 if ( GEOMBase::GetShape(geom, aShape) && aShape.ShapeType() == TopAbs_VERTEX ) {
606 gp_Pnt P = BRep_Tool::Pnt(aShape);
607 points.Append( P.XYZ() );
612 SVTK_TIndexedMapOfVtkId nodeIndices;
613 selector()->GetIndex( anIO, nodeIndices );
614 if ( nodeIndices.Extent() > 0 && nodeIndices.Extent() <=2 )
616 if ( SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry()))
617 if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh())
619 if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(1)))
620 points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z()));
621 if ( nodeIndices.Extent() == 2 )
622 if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(2)))
623 points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z()));
629 if ( points.Length() == 1 )
631 else if ( points.Length() == 2 )
632 xyz = points(2) - points(1);
635 if ( points.Length() == 1 && mySelectionMode == EPoint )
637 myDlg->myX->SetValue( xyz.X() );
638 myDlg->myY->SetValue( xyz.Y() );
639 myDlg->myZ->SetValue( xyz.Z() );
642 if ( mySelectionMode == EDirection )
644 myDlg->myDX->SetValue( xyz.X() );
645 myDlg->myDY->SetValue( xyz.Y() );
646 myDlg->myDZ->SetValue( xyz.Z() );
650 } // case EPoint || EDirection
658 //================================================================================
660 * \brief SLOT called when the face id is changed
662 //================================================================================
664 void SMESHGUI_ReorientFacesOp::onTextChange( const QString& theText )
668 sender()->blockSignals( true );
669 if ( mySelectionMode != EFace )
671 myDlg->activateObject( EFace );
672 myDlg->setObjectText( EFace, theText );
675 if ( !theText.isEmpty() && theText.toInt() > 0 )
676 ids.Add( theText.toInt() );
678 SMESHGUI_SelectionOp::addOrRemoveIndex( myObjectActor->getIO(), ids, false );
679 SMESHGUI_SelectionOp::highlight( myObjectActor->getIO(), true, true );
680 sender()->blockSignals( false );
684 //================================================================================
686 * \brief perform it's intention action: reorient faces of myObject
688 //================================================================================
690 bool SMESHGUI_ReorientFacesOp::onApply()
692 if( SMESHGUI::isStudyLocked() )
696 if ( !isValid( msg ) ) { // node id is invalid
698 SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), msg );
703 QStringList aParameters;
704 aParameters << myDlg->myDX->text();
705 aParameters << myDlg->myDY->text();
706 aParameters << myDlg->myDZ->text();
707 aParameters << myDlg->myX->text();
708 aParameters << myDlg->myY->text();
709 aParameters << myDlg->myZ->text();
712 SUIT_OverrideCursor wc;
714 SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh();
715 if ( aMesh->_is_nil() ) return false;
717 SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
718 if (aMeshEditor->_is_nil()) return false;
721 switch ( constructorID() )
723 case CONSTRUCTOR_VOLUME:
725 bool outsideNormal = myDlg->myOutsideChk->isChecked();
727 aResult = aMeshEditor->Reorient2DBy3D( myObjects, myRefGroups[0], outsideNormal );
731 case CONSTRUCTOR_FACE_GROUPS:
733 aResult = aMeshEditor->Reorient2DByNeighbours( myObjects, myRefGroups );
739 SMESH::DirStruct direction;
740 direction.PS.x = myDlg->myDX->GetValue();
741 direction.PS.y = myDlg->myDY->GetValue();
742 direction.PS.z = myDlg->myDZ->GetValue();
744 long face = myDlg->objectText( EFace ).toInt();
745 if ( constructorID() == CONSTRUCTOR_POINT )
748 SMESH::PointStruct point;
749 point.x = myDlg->myX->GetValue();
750 point.y = myDlg->myY->GetValue();
751 point.z = myDlg->myZ->GetValue();
753 aMesh->SetParameters( aParameters.join(":").toUtf8().constData() );
755 aResult = aMeshEditor->Reorient2D( myObjects[0], direction, face, point );
762 selectionMgr()->setSelectedObjects(aList,false);
764 SMESHGUI::Modified();
767 SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
768 tr("NB_REORIENTED").arg(aResult));
770 catch (const SALOME::SALOME_Exception& S_ex) {
771 SalomeApp_Tools::QtCatchCorbaException(S_ex);
779 //================================================================================
781 * \brief Check data validity
783 //================================================================================
785 bool SMESHGUI_ReorientFacesOp::isValid( QString& msg )
789 QStringList objectEntries;
790 myDlg->selectedObject( EObject, objectEntries );
791 if ( objectEntries.size() == 0 )
793 msg = tr("NO_OBJECT_SELECTED");
796 myObjects->length( objectEntries.size() );
798 for ( QString & entry : objectEntries )
800 SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry );
801 if ( !obj->_is_nil() )
803 bool hasFaces = false;
804 SMESH::array_of_ElementType_var types = obj->GetTypes();
805 for ( size_t i = 0; i < types->length() && !hasFaces; ++i )
806 hasFaces = ( types[i] == SMESH::FACE );
808 myObjects[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj );
813 msg = tr("NO_FACES");
816 myObjects->length( nbObj );
818 // Check volume object or ref faces
820 int constructorType = constructorID();
821 if ( constructorType >= CONSTRUCTOR_FACE_GROUPS )
823 objectEntries.clear();
824 myDlg->selectedObject( ERefGroups, objectEntries );
825 myRefGroups->length( objectEntries.size() );
827 for ( QString & entry : objectEntries )
829 SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry );
830 if ( !obj->_is_nil() )
832 bool hasElems = false;
833 SMESH::ElementType elemType =
834 ( constructorType == CONSTRUCTOR_VOLUME ? SMESH::VOLUME : SMESH::FACE );
835 SMESH::array_of_ElementType_var types = obj->GetTypes();
836 for ( size_t i = 0; i < types->length() && !hasElems; ++i )
837 hasElems = ( types[i] == elemType );
839 myRefGroups[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj );
842 if ( nbObj == 0 && constructorType == CONSTRUCTOR_VOLUME )
844 msg = tr("NO_VOLUMES");
847 myRefGroups->length( nbObj );
852 gp_Vec vec( myDlg->myDX->GetValue(),
853 myDlg->myDY->GetValue(),
854 myDlg->myDZ->GetValue() );
855 if ( vec.Magnitude() < std::numeric_limits<double>::min() )
857 msg = tr("ZERO_SIZE_VECTOR");
863 if ( constructorID() == CONSTRUCTOR_FACE )
865 int faceID = myDlg->objectText( EFace ).toInt();
866 bool faceOK = ( faceID > 0 );
871 faceOK = ( myObjectActor->GetObject()->GetElemDimension( faceID ) == 2 );
875 SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh();
876 if ( !aMesh->_is_nil() )
877 faceOK = ( aMesh->GetElementType( faceID, true ) == SMESH::FACE );
882 msg = tr("INVALID_FACE");
890 //================================================================================
894 //================================================================================
896 SMESHGUI_ReorientFacesOp::~SMESHGUI_ReorientFacesOp()
898 if ( myDlg ) delete myDlg;
899 //if ( myVectorPreview ) delete myVectorPreview;
902 //================================================================================
904 * \brief Gets dialog of this operation
905 * \retval LightApp_Dialog* - pointer to dialog of this operation
907 //================================================================================
909 LightApp_Dialog* SMESHGUI_ReorientFacesOp::dlg() const
914 //================================================================================
916 * \brief ID of a current constructor: CONSTRUCTOR_FACE, CONSTRUCTOR_POINT etc.
918 //================================================================================
920 int SMESHGUI_ReorientFacesOp::constructorID()
922 return myDlg->myConstructorGrp->checkedId();
925 //================================================================================
927 * \brief Check if selection of multiple objects allowed
929 //================================================================================
931 bool SMESHGUI_ReorientFacesOp::onlyOneObjAllowed()
933 return (( constructorID() <= CONSTRUCTOR_FACE ) ||
934 ( constructorID() == CONSTRUCTOR_VOLUME && mySelectionMode == ERefGroups ));
937 //================================================================================
939 * \brief update preview
941 //================================================================================
943 void SMESHGUI_ReorientFacesOp::redisplayPreview()