1 // SMESH SMESHGUI : GUI for SMESH component
3 // Copyright (C) 2003 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.
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESHGUI_MultiEditDlg.cxx
25 // Author : Sergey LITONIN
28 #include "SMESHGUI_MultiEditDlg.h"
29 #include "SMESHGUI_FilterDlg.h"
30 #include "SMESHGUI_Filter.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
37 #include "QAD_Desktop.h"
38 #include "QAD_RightFrame.h"
40 #include "VTKViewer_ViewFrame.h"
42 #include "SMESH_Actor.h"
43 #include "SMDS_Mesh.hxx"
44 #include "SMDS_MeshElement.hxx"
46 #include "SALOME_Selection.h"
47 #include "SALOME_ListIteratorOfListIO.hxx"
48 #include "VTKViewer_InteractorStyleSALOME.h"
50 #include <vtkCell3D.h>
52 #include <vtkTriangle.h>
53 #include <vtkIdList.h>
54 #include <vtkIntArray.h>
55 #include <vtkCellArray.h>
56 #include <vtkUnsignedCharArray.h>
57 #include <vtkUnstructuredGrid.h>
58 #include <vtkDataSetMapper.h>
60 #include <TColStd_IndexedMapOfInteger.hxx>
61 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
62 #include <Precision.hxx>
63 #include <TColStd_DataMapOfIntegerInteger.hxx>
65 #include <qcheckbox.h>
67 #include <qgroupbox.h>
70 #include <qlineedit.h>
72 #include <qpushbutton.h>
73 #include <qapplication.h>
74 #include <qhbuttongroup.h>
75 #include <qradiobutton.h>
78 #include "SALOMEconfig.h"
79 #include CORBA_SERVER_HEADER(SMESH_Group)
85 Class : SMESHGUI_MultiEditDlg
86 Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
87 2 neighboring triangles with 1 common edge
90 //=======================================================================
91 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
92 // Purpose : Constructor
93 //=======================================================================
94 SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg( QWidget* theParent,
95 SALOME_Selection* theSelection,
99 : QDialog( theParent, theName, false,
100 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
103 mySubmeshFilter = new SMESH_TypeFilter( SUBMESH );
104 myGroupFilter = new SMESH_TypeFilter( GROUP );
108 myFilterType = theMode;
109 QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
111 QFrame* aMainFrame = createMainFrame ( this, the3d2d );
112 QFrame* aBtnFrame = createButtonFrame( this );
114 aDlgLay->addWidget( aMainFrame );
115 aDlgLay->addWidget( aBtnFrame );
117 aDlgLay->setStretchFactor( aMainFrame, 1 );
118 aDlgLay->setStretchFactor( aBtnFrame, 0 );
119 Init( theSelection ) ;
122 //=======================================================================
123 // name : SMESHGUI_MultiEditDlg::createMainFrame
124 // Purpose : Create frame containing dialog's input fields
125 //=======================================================================
126 QFrame* SMESHGUI_MultiEditDlg::createMainFrame( QWidget* theParent, const bool the3d2d )
128 QGroupBox* aMainGrp = new QGroupBox( 1, Qt::Horizontal, theParent );
129 aMainGrp->setFrameStyle( QFrame::NoFrame );
130 aMainGrp->setInsideMargin( 0 );
132 QPixmap aPix( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
134 // "Selected cells" group
135 mySelGrp = new QGroupBox( 1, Qt::Horizontal, aMainGrp );
139 myEntityTypeGrp = new QHButtonGroup( tr("SMESH_ELEMENTS_TYPE"), mySelGrp );
140 (new QRadioButton( tr("SMESH_FACE"), myEntityTypeGrp ))->setChecked( true );
141 (new QRadioButton( tr("SMESH_VOLUME"), myEntityTypeGrp ));
142 myEntityType = myEntityTypeGrp->id( myEntityTypeGrp->selected() );
145 QFrame* aFrame = new QFrame( mySelGrp );
147 myListBox = new QListBox( aFrame );
148 myListBox->setSelectionMode( QListBox::Extended );
149 myListBox->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
150 // myListBox->setColumnMode( QListBox::FitToHeight );
151 myListBox->installEventFilter( this );
153 myFilterBtn = new QPushButton( tr( "FILTER" ) , aFrame );
154 myAddBtn = new QPushButton( tr( "ADD" ) , aFrame );
155 myRemoveBtn = new QPushButton( tr( "REMOVE" ) , aFrame );
156 mySortBtn = new QPushButton( tr( "SORT_LIST" ), aFrame );
158 QGridLayout* aLay = new QGridLayout( aFrame, 5, 2, 0, 5 );
159 aLay->addMultiCellWidget( myListBox, 0, 4, 0, 0 );
160 aLay->addWidget( myFilterBtn, 0, 1 );
161 aLay->addWidget( myAddBtn, 1, 1 );
162 aLay->addWidget( myRemoveBtn, 2, 1 );
163 aLay->addWidget( mySortBtn, 3, 1 );
165 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
166 aLay->addItem( aSpacer, 4, 1 );
168 myToAllChk = new QCheckBox( tr( "TO_ALL" ), mySelGrp );
170 // "Select from" group
171 QGroupBox* aGrp = new QGroupBox( 3, Qt::Horizontal, tr( "SELECT_FROM" ), aMainGrp );
173 mySubmeshChk = new QCheckBox( tr( "SMESH_SUBMESH" ), aGrp );
174 mySubmeshBtn = new QPushButton( aGrp );
175 mySubmesh = new QLineEdit( aGrp );
176 mySubmesh->setReadOnly( true );
177 mySubmeshBtn->setPixmap( aPix );
179 myGroupChk = new QCheckBox( tr( "GROUP" ), aGrp );
180 myGroupBtn = new QPushButton( aGrp );
181 myGroup = new QLineEdit( aGrp );
182 myGroup->setReadOnly( true );
183 myGroupBtn->setPixmap( aPix );
188 //=======================================================================
189 // name : SMESHGUI_MultiEditDlg::createButtonFrame
190 // Purpose : Create frame containing buttons
191 //=======================================================================
192 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame( QWidget* theParent )
194 QFrame* aFrame = new QFrame( theParent );
195 aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken );
197 myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aFrame );
198 myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aFrame );
199 myCloseBtn = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aFrame );
201 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
203 QHBoxLayout* aLay = new QHBoxLayout( aFrame, MARGIN, SPACING );
205 aLay->addWidget( myOkBtn );
206 aLay->addWidget( myApplyBtn );
207 aLay->addItem( aSpacer);
208 aLay->addWidget( myCloseBtn );
213 //=======================================================================
214 // name : SMESHGUI_MultiEditDlg::isValid
215 // Purpose : Verify validity of input data
216 //=======================================================================
217 bool SMESHGUI_MultiEditDlg::isValid( const bool /*theMess*/ )
219 SMESH::long_array_var anIds = getIds();
220 return (!myMesh->_is_nil() &&
221 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)) && anIds->length() > 0);
224 //=======================================================================
225 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
226 // Purpose : Destructor
227 //=======================================================================
228 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
230 if ( myFilterDlg != 0 )
232 myFilterDlg->reparent( 0, QPoint() );
237 //=======================================================================
238 // name : SMESHGUI_MultiEditDlg::eventFilter
239 // Purpose : event filter
240 //=======================================================================
241 bool SMESHGUI_MultiEditDlg::eventFilter( QObject* object, QEvent* event )
243 if ( object == myListBox && event->type() == QEvent::KeyPress ) {
244 QKeyEvent* ke = (QKeyEvent*)event;
245 if ( ke->key() == Key_Delete )
248 return QDialog::eventFilter( object, event );
251 //=======================================================================
252 // name : SMESHGUI_MultiEditDlg::Init
253 // Purpose : Init dialog fields, connect signals and slots, show dialog
254 //=======================================================================
255 void SMESHGUI_MultiEditDlg::Init( SALOME_Selection* theSelection )
257 SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
258 mySelection = theSelection;
259 aSMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
264 emit ListContensChanged();
267 connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
268 connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
269 connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
271 // selection and SMESHGUI
272 connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
273 connect( aSMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
274 connect( aSMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
277 connect( myFilterBtn, SIGNAL( clicked() ), SLOT( onFilterBtn() ) );
278 connect( myAddBtn , SIGNAL( clicked() ), SLOT( onAddBtn() ) );
279 connect( myRemoveBtn, SIGNAL( clicked() ), SLOT( onRemoveBtn() ) );
280 connect( mySortBtn , SIGNAL( clicked() ), SLOT( onSortListBtn() ) );
282 connect( mySubmeshChk, SIGNAL( stateChanged( int ) ), SLOT( onSubmeshChk() ) );
283 connect( myGroupChk , SIGNAL( stateChanged( int ) ), SLOT( onGroupChk() ) );
284 connect( myToAllChk , SIGNAL( stateChanged( int ) ), SLOT( onToAllChk() ) );
286 if ( myEntityTypeGrp )
287 connect( myEntityTypeGrp, SIGNAL( clicked(int) ), SLOT( on3d2dChanged(int) ) );
289 connect( myListBox, SIGNAL( selectionChanged() ), SLOT( onListSelectionChanged() ) );
291 int nbSel = mySelection->IObjectCount();
293 myIO = mySelection->firstIObject();
295 // set selection mode
304 //=======================================================================
305 // name : SMESHGUI_MultiEditDlg::onOk
306 // Purpose : SLOT called when "Ok" button pressed.
307 // Assign filters VTK viewer and close dialog
308 //=======================================================================
309 void SMESHGUI_MultiEditDlg::onOk()
315 //=======================================================================
316 // name : SMESHGUI_MultiEditDlg::getIds
317 // Purpose : Retrive identifiers from list box
318 //=======================================================================
319 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
321 SMESH::long_array_var anIds = new SMESH::long_array;
323 if ( myToAllChk->isChecked() )
328 TVisualObjPtr aVisualObj = myActor->GetObject();
329 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
332 for ( int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++ )
334 vtkCell* aCell = aGrid->GetCell( i );
337 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
338 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
339 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
341 if ( aTri && myFilterType == SMESHGUI_TriaFilter ||
342 aQua && myFilterType == SMESHGUI_QuadFilter ||
343 ( aTri || aQua ) && myFilterType == SMESHGUI_FaceFilter ||
344 a3d && myFilterType == SMESHGUI_VolumeFilter )
346 int anObjId = aVisualObj->GetElemObjId( i );
347 myIds.Add( anObjId );
355 anIds->length( myIds.Extent() );
356 TColStd_MapIteratorOfMapOfInteger anIter( myIds );
357 for ( int i = 0; anIter.More(); anIter.Next() )
359 anIds[ i++ ] = anIter.Key();
361 return anIds._retn();
364 //=======================================================================
365 // name : SMESHGUI_MultiEditDlg::onClose
366 // Purpose : SLOT called when "Close" button pressed. Close dialog
367 //=======================================================================
368 void SMESHGUI_MultiEditDlg::onClose()
370 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
371 disconnect( mySelection, 0, this, 0 );
372 disconnect( SMESHGUI::GetSMESHGUI(), 0, this, 0 );
373 SMESHGUI::GetSMESHGUI()->ResetState();
375 SMESH::RemoveFilter(SMESHGUI_EdgeFilter);
376 SMESH::RemoveFilter(SMESHGUI_FaceFilter);
377 SMESH::RemoveFilter(SMESHGUI_VolumeFilter);
378 SMESH::RemoveFilter(SMESHGUI_QuadFilter);
379 SMESH::RemoveFilter(SMESHGUI_TriaFilter);
380 SMESH::SetPickable();
382 mySelection->ClearIObjects();
383 mySelection->ClearFilters();
388 //=======================================================================
389 // name : SMESHGUI_MultiEditDlg::onSelectionDone
390 // Purpose : SLOT called when selection changed
391 //=======================================================================
392 void SMESHGUI_MultiEditDlg::onSelectionDone()
394 if ( myBusy || !isEnabled() ) return;
397 myMesh = SMESH::SMESH_Mesh::_nil();
400 int nbSel = mySelection->IObjectCount();
401 myListBox->clearSelection();
403 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
405 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
406 int nbSel = mySelection->IObjectCount();
409 Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
410 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText( anIO->getName() );
412 if ( mySubmeshChk->isChecked() )
414 SMESH::SMESH_subMesh_var aSubMesh =
415 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIO );
416 if ( !aSubMesh->_is_nil() )
417 myMesh = aSubMesh->GetFather();
421 SMESH::SMESH_GroupBase_var aGroup =
422 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIO );
423 if ( !aGroup->_is_nil() )
424 myMesh = aGroup->GetMesh();
427 else if ( nbSel > 1 )
429 QString aStr = mySubmeshChk->isChecked() ?
430 tr( "SMESH_SUBMESH_SELECTED" ) : tr( "SMESH_GROUP_SELECTED" );
431 aNameEdit->setText( aStr.arg( nbSel ) );
436 else if ( nbSel == 1 )
438 QString aListStr = "";
439 int aNbItems = SMESH::GetNameOfSelectedElements(mySelection, aListStr);
442 QStringList anElements = QStringList::split(" ", aListStr);
443 QListBoxItem* anItem = 0;
444 for ( QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it)
446 anItem = myListBox->findItem( *it, Qt::ExactMatch );
447 if (anItem) myListBox->setSelected( anItem, true );
451 myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
455 myActor = SMESH::FindActorByEntry(mySelection->firstIObject()->getEntry());
456 //if ( !myActor && !myMesh->_is_nil() )
457 // myActor = SMESH::FindActorByObject( myMesh );
458 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
459 Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter( myFilterType );
461 if ( !aFilter.IsNull() ) {
462 aFilter->SetActor( myActor );
463 //SMESH::SetPickable( myActor );
464 myIO = myActor->getIO();
476 //=======================================================================
477 // name : SMESHGUI_MultiEditDlg::onDeactivate
478 // Purpose : SLOT called when dialog must be deativated
479 //=======================================================================
480 void SMESHGUI_MultiEditDlg::onDeactivate()
485 //=======================================================================
486 // name : SMESHGUI_MultiEditDlg::enterEvent
487 // Purpose : Event filter
488 //=======================================================================
489 void SMESHGUI_MultiEditDlg::enterEvent( QEvent* )
491 if ( !isEnabled() ) {
492 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
499 //=================================================================================
500 // function : closeEvent()
502 //=================================================================================
503 void SMESHGUI_MultiEditDlg::closeEvent( QCloseEvent* e )
507 //=======================================================================
508 //function : hideEvent
509 //purpose : caused by ESC key
510 //=======================================================================
512 void SMESHGUI_MultiEditDlg::hideEvent ( QHideEvent * e )
514 if ( !isMinimized() )
518 //=======================================================================
519 // name : SMESHGUI_MultiEditDlg::onFilterBtn
520 // Purpose : SLOT. Called when "Filter" button pressed.
521 // Start "Selection filters" dialog
522 //=======================================================================
523 void SMESHGUI_MultiEditDlg::onFilterBtn()
525 if ( myFilterDlg == 0 )
527 myFilterDlg = new SMESHGUI_FilterDlg( (QWidget*)parent(), entityType() ? SMESH::VOLUME : SMESH::FACE );
528 connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
531 myFilterDlg->Init( entityType() ? SMESH::VOLUME : SMESH::FACE );
533 myFilterDlg->SetSelection( mySelection );
534 myFilterDlg->SetMesh( myMesh );
535 myFilterDlg->SetSourceWg( myListBox );
540 //=================================================================================
541 // function : onFilterAccepted()
542 // purpose : SLOT. Called when Filter dlg closed with OK button.
543 // Uncheck "Select submesh" and "Select group" checkboxes
544 //=================================================================================
545 void SMESHGUI_MultiEditDlg::onFilterAccepted()
548 for ( int i = 0, n = myListBox->count(); i < n; i++ )
549 myIds.Add( myListBox->text( i ).toInt() );
551 emit ListContensChanged();
553 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
555 mySubmeshChk->blockSignals( true );
556 myGroupChk->blockSignals( true );
557 mySubmeshChk->setChecked( false );
558 myGroupChk->setChecked( false );
559 mySubmeshChk->blockSignals( false );
560 myGroupChk->blockSignals( false );
565 //=======================================================================
566 // name : SMESHGUI_MultiEditDlg::isIdValid
567 // Purpose : Verify whether Id of element satisfies to filters from viewer
568 //=======================================================================
569 bool SMESHGUI_MultiEditDlg::isIdValid( const int theId ) const
571 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
572 Handle(SMESHGUI_Filter) aFilter =
573 Handle(SMESHGUI_Filter)::DownCast( aStyle->GetFilter( myFilterType ) );
574 return ( !aFilter.IsNull() && aFilter->IsObjValid( theId ) );
577 //=======================================================================
578 // name : SMESHGUI_MultiEditDlg::onAddBtn
579 // Purpose : SLOT. Called when "Add" button pressed.
580 // Add selected in viewer entities in list box
581 //=======================================================================
582 void SMESHGUI_MultiEditDlg::onAddBtn()
584 int nbSelected = mySelection->IObjectCount();
585 if ( nbSelected == 0 )
588 TColStd_IndexedMapOfInteger toBeAdded;
590 if ( !mySubmeshChk->isChecked() && !myGroupChk->isChecked() )
592 if ( nbSelected == 1 )
593 SMESH::GetSelected( mySelection, toBeAdded );
595 else if ( mySubmeshChk->isChecked() )
597 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
598 for ( ; anIter.More(); anIter.Next() )
600 SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIter.Value() );
601 if ( !aSubMesh->_is_nil() )
603 if ( !myMesh->_is_nil() && aSubMesh->GetFather()->GetId() == myMesh->GetId() )
605 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
606 for ( int i = 0, n = anIds->length(); i < n; i++ )
608 if ( isIdValid( anIds[ i ] ) )
609 toBeAdded.Add( anIds[ i ] );
615 else if ( myGroupChk->isChecked() )
617 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
618 for ( ; anIter.More(); anIter.Next() )
620 SMESH::SMESH_GroupBase_var aGroup =
621 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Value() );
622 if ( !aGroup->_is_nil() && ( aGroup->GetType() == SMESH::FACE || aGroup->GetType() == SMESH::VOLUME ) )
624 if ( !myMesh->_is_nil() && aGroup->GetMesh()->GetId() == myMesh->GetId() )
626 SMESH::long_array_var anIds = aGroup->GetListOfID();
627 for ( int i = 0, n = anIds->length(); i < n; i++ )
629 if ( isIdValid( anIds[ i ] ) )
630 toBeAdded.Add( anIds[ i ] );
638 bool isGroupOrSubmesh = ( mySubmeshChk->isChecked() || myGroupChk->isChecked() );
639 mySubmeshChk->setChecked( false );
640 myGroupChk->setChecked( false );
641 for( int i = 1; i <= toBeAdded.Extent(); i++ )
642 if ( myIds.Add( toBeAdded(i) ) ) {
643 QListBoxItem * item = new QListBoxText( QString( "%1" ).arg( toBeAdded(i) ));
644 myListBox->insertItem( item );
645 myListBox->setSelected( item, true );
649 emit ListContensChanged();
651 if ( isGroupOrSubmesh )
652 onListSelectionChanged();
657 //=======================================================================
658 // name : SMESHGUI_MultiEditDlg::updateButtons
659 // Purpose : Enable/disable buttons of dialog in accordance with current state
660 //=======================================================================
661 void SMESHGUI_MultiEditDlg::updateButtons()
663 bool isOk = isValid(false);
664 myOkBtn->setEnabled( isOk );
665 myApplyBtn->setEnabled( isOk );
667 bool isListBoxNonEmpty = myListBox->count() > 0;
668 bool isToAll = myToAllChk->isChecked();
669 myFilterBtn->setEnabled( !isToAll );
670 myRemoveBtn->setEnabled( isListBoxNonEmpty && !isToAll );
671 mySortBtn->setEnabled( isListBoxNonEmpty &&!isToAll );
675 mySelection->IObjectCount() != 1 ||
676 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( mySelection->firstIObject() )->_is_nil() &&
677 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( mySelection->firstIObject() )->_is_nil() &&
678 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( mySelection->firstIObject() )->_is_nil()) )
679 myAddBtn->setEnabled( false );
681 myAddBtn->setEnabled( true );
683 mySubmeshChk->setEnabled( !isToAll );
684 mySubmeshBtn->setEnabled( mySubmeshChk->isChecked() );
685 mySubmesh->setEnabled( mySubmeshChk->isChecked() );
687 myGroupChk->setEnabled( !isToAll );
688 myGroupBtn->setEnabled( myGroupChk->isChecked() );
689 myGroup->setEnabled( myGroupChk->isChecked() );
691 if ( !mySubmeshChk->isChecked() )
693 if ( !myGroupChk->isChecked() )
698 //=======================================================================
699 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
700 // Purpose : SLOT. Called when "Remove" button pressed.
701 // Remove selected in list box entities
702 //=======================================================================
703 void SMESHGUI_MultiEditDlg::onRemoveBtn()
707 for ( int i = 0, n = myListBox->count(); i < n; i++ )
709 for ( int i = myListBox->count(); i > 0; i--) {
710 if ( myListBox->isSelected( i - 1 ) )
712 int anId = myListBox->text( i - 1 ).toInt();
713 myIds.Remove( anId );
714 myIds.Remove( anId );
715 myListBox->removeItem( i-1 );
721 emit ListContensChanged();
725 //=======================================================================
726 // name : SMESHGUI_MultiEditDlg::onSortListBtn
727 // Purpose : SLOT. Called when "Sort list" button pressed.
728 // Sort entities of list box
729 //=======================================================================
730 void SMESHGUI_MultiEditDlg::onSortListBtn()
734 int i, k = myListBox->count();
737 QStringList aSelected;
738 std::vector<int> anArray( k );
739 QListBoxItem* anItem;
740 for ( anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
742 anArray[ i ] = anItem->text().toInt();
743 if ( anItem->isSelected() )
744 aSelected.append( anItem->text() );
747 std::sort( anArray.begin(), anArray.end() );
749 for ( i = 0; i < k; i++ )
750 myListBox->insertItem( QString::number( anArray[ i ] ) );
752 for ( QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it )
754 anItem = myListBox->findItem( *it, Qt::ExactMatch );
756 myListBox->setSelected( anItem, true );
762 //=======================================================================
763 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
764 // Purpose : SLOT. Called when selection in list box changed.
765 // Highlight in selected entities
766 //=======================================================================
767 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
769 if ( myActor == 0 || myBusy )
772 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
775 SMESH_Actor * anActor = SMESH::FindActorByObject( myMesh );
778 TVisualObjPtr anObj = anActor->GetObject();
780 TColStd_MapOfInteger anIndexes;
781 for ( QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next() )
783 if ( anItem->isSelected() )
785 int anId = anItem->text().toInt();
786 if ( anObj->GetElemVTKId( anId ) >= 0 ) // avoid exception in hilight
791 mySelection->ClearIObjects();
792 mySelection->AddOrRemoveIndex( anActor->getIO(), anIndexes, false, false );
793 mySelection->AddIObject( anActor->getIO() );
796 //=======================================================================
797 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
798 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
799 // Activate/deactivate selection of submeshes
800 //=======================================================================
801 void SMESHGUI_MultiEditDlg::onSubmeshChk()
803 bool isChecked = mySubmeshChk->isChecked();
804 mySubmeshBtn->setEnabled( isChecked );
805 mySubmesh->setEnabled( isChecked );
808 if ( isChecked && myGroupChk->isChecked() )
809 myGroupChk->setChecked( false );
814 //=======================================================================
815 // name : SMESHGUI_MultiEditDlg::onGroupChk
816 // Purpose : SLOT. Called when state of "Group" check box changed.
817 // Activate/deactivate selection of groupes
818 //=======================================================================
819 void SMESHGUI_MultiEditDlg::onGroupChk()
821 bool isChecked = myGroupChk->isChecked();
822 myGroupBtn->setEnabled( isChecked );
823 myGroup->setEnabled( isChecked );
826 if ( isChecked && mySubmeshChk->isChecked() )
827 mySubmeshChk->setChecked( false );
832 //=======================================================================
833 // name : SMESHGUI_MultiEditDlg::onToAllChk
834 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
835 // Activate/deactivate selection
836 //=======================================================================
837 void SMESHGUI_MultiEditDlg::onToAllChk()
839 bool isChecked = myToAllChk->isChecked();
846 emit ListContensChanged();
850 //if ( !myIO.IsNull() )
851 //mySelection->AddIObject( myIO, true );
856 //=======================================================================
857 // name : SMESHGUI_MultiEditDlg::setSelectionMode
858 // Purpose : Set selection mode
859 //=======================================================================
860 void SMESHGUI_MultiEditDlg::setSelectionMode()
862 SMESH::RemoveFilter(SMESHGUI_EdgeFilter);
863 SMESH::RemoveFilter(SMESHGUI_FaceFilter);
864 SMESH::RemoveFilter(SMESHGUI_VolumeFilter);
865 SMESH::RemoveFilter(SMESHGUI_QuadFilter);
866 SMESH::RemoveFilter(SMESHGUI_TriaFilter);
867 SMESH::SetPickable();
869 mySelection->ClearIObjects();
870 mySelection->ClearFilters();
872 if ( mySubmeshChk->isChecked() )
874 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
875 mySelection->AddFilter( mySubmeshFilter );
877 else if ( myGroupChk->isChecked() )
879 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
880 mySelection->AddFilter( myGroupFilter );
882 if ( myFilterType == SMESHGUI_VolumeFilter ) {
883 QAD_Application::getDesktop()->SetSelectionMode( VolumeSelection, true );
884 SMESH::SetFilter( new SMESHGUI_VolumesFilter() );
887 QAD_Application::getDesktop()->SetSelectionMode( FaceSelection, true );
888 if ( myFilterType == SMESHGUI_TriaFilter )
889 SMESH::SetFilter( new SMESHGUI_TriangleFilter() );
890 else if ( myFilterType == SMESHGUI_QuadFilter )
891 SMESH::SetFilter( new SMESHGUI_QuadrangleFilter() );
893 SMESH::SetFilter( new SMESHGUI_FacesFilter() );
895 if ( !myIO.IsNull() )
896 mySelection->AddIObject( myIO, true );
899 //=======================================================================
900 // name : SMESHGUI_MultiEditDlg::onApply
901 // Purpose : SLOT. Called when "Apply" button clicked.
902 //=======================================================================
903 bool SMESHGUI_MultiEditDlg::onApply()
905 if ( SMESHGUI::GetSMESHGUI()->ActiveStudyLocked() )
907 if ( !isValid( true ) )
910 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
911 if ( aMeshEditor->_is_nil() )
916 SMESH::long_array_var anIds = getIds();
918 bool aResult = process( aMeshEditor, anIds.inout() );
923 mySelection->ClearIObjects();
925 mySelection->AddIObject( myActor->getIO(), false );
930 emit ListContensChanged();
939 //=======================================================================
940 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
942 //=======================================================================
943 void SMESHGUI_MultiEditDlg::on3d2dChanged(int type)
945 if ( myEntityType != type ) {
951 emit ListContensChanged();
954 myFilterType = SMESHGUI_VolumeFilter;
956 myFilterType = SMESHGUI_FaceFilter;
965 //=======================================================================
966 // name : SMESHGUI_MultiEditDlg::entityType
968 //=======================================================================
970 int SMESHGUI_MultiEditDlg::entityType()
976 Class : SMESHGUI_ChangeOrientationDlg
977 Description : Modification of orientation of faces
980 SMESHGUI_ChangeOrientationDlg::SMESHGUI_ChangeOrientationDlg( QWidget* theParent,
981 SALOME_Selection* theSelection,
982 const char* theName )
983 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_FaceFilter, true, theName )
985 setCaption( tr( "CAPTION" ) );
988 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
992 bool SMESHGUI_ChangeOrientationDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
993 const SMESH::long_array& theIds )
995 return theEditor->Reorient( theIds );
999 Class : SMESHGUI_UnionOfTrianglesDlg
1000 Description : Construction of quadrangles by automatic association of triangles
1003 SMESHGUI_UnionOfTrianglesDlg::SMESHGUI_UnionOfTrianglesDlg( QWidget* theParent,
1004 SALOME_Selection* theSelection,
1005 const char* theName )
1006 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_TriaFilter, false, theName )
1008 setCaption( tr( "CAPTION" ) );
1011 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1015 bool SMESHGUI_UnionOfTrianglesDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
1016 const SMESH::long_array& theIds )
1018 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1. );
1022 Class : SMESHGUI_CuttingOfQuadsDlg
1023 Description : Construction of quadrangles by automatic association of triangles
1026 SMESHGUI_CuttingOfQuadsDlg::SMESHGUI_CuttingOfQuadsDlg( QWidget* theParent,
1027 SALOME_Selection* theSelection,
1028 const char* theName )
1029 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_QuadFilter, false, theName )
1032 setCaption( tr( "CAPTION" ) );
1035 myUseDiagChk = new QCheckBox( tr( "USE_DIAGONAL_2_4" ), mySelGrp );
1036 myPreviewChk = new QCheckBox( tr( "PREVIEW" ), mySelGrp );
1038 connect( myPreviewChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
1039 connect( myUseDiagChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
1040 connect( this, SIGNAL( ListContensChanged() ), this, SLOT( onPreviewChk() ) );
1043 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1047 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1050 SMESHGUI_MultiEditDlg::onClose();
1053 bool SMESHGUI_CuttingOfQuadsDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
1054 const SMESH::long_array& theIds )
1056 return theEditor->SplitQuad( theIds, !myUseDiagChk->isChecked() );
1059 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1061 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1064 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1066 if ( myPreviewActor == 0 )
1069 if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
1071 vf->RemoveActor(myPreviewActor);
1074 myPreviewActor->Delete();
1078 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1083 if ( myPreviewActor != 0 )
1086 // get Ids of elements
1087 SMESH::long_array_var anElemIds = getIds();
1088 if ( getIds()->length() == 0 )
1091 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1095 bool isDiag24 = myUseDiagChk->isChecked();
1098 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1100 vtkIdType aNbCells = anElemIds->length() * 2;
1101 vtkIdType aCellsSize = 4 * aNbCells;
1102 vtkCellArray* aConnectivity = vtkCellArray::New();
1103 aConnectivity->Allocate( aCellsSize, 0 );
1105 vtkPoints* aPoints = vtkPoints::New();
1106 aPoints->SetNumberOfPoints( anElemIds->length() * 4 );
1108 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1109 aCellTypesArray->SetNumberOfComponents( 1 );
1110 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
1112 vtkIdList *anIdList = vtkIdList::New();
1113 anIdList->SetNumberOfIds( 3 );
1115 TColStd_DataMapOfIntegerInteger anIdToVtk;
1119 for ( int i = 0, n = anElemIds->length(); i < n; i++ )
1121 const SMDS_MeshElement* anElem = aMesh->FindElement( anElemIds[ i ] );
1122 if ( anElem == 0 || anElem->NbNodes() != 4 )
1125 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1127 while( anIter->more() )
1128 if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() )
1130 if ( !anIdToVtk.IsBound( aNode->GetID() ) )
1132 aPoints->SetPoint( ++nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
1133 anIdToVtk.Bind( aNode->GetID(), nbPoints );
1136 aNodes[ k++ ] = aNode->GetID();
1144 anIdList->SetId( 0, anIdToVtk( aNodes[ 0 ] ) );
1145 anIdList->SetId( 1, anIdToVtk( aNodes[ 1 ] ) );
1146 anIdList->SetId( 2, anIdToVtk( aNodes[ 2 ] ) );
1147 aConnectivity->InsertNextCell( anIdList );
1148 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1150 anIdList->SetId( 0, anIdToVtk( aNodes[ 2 ] ) );
1151 anIdList->SetId( 1, anIdToVtk( aNodes[ 3 ] ) );
1152 anIdList->SetId( 2, anIdToVtk( aNodes[ 0 ] ) );
1153 aConnectivity->InsertNextCell( anIdList );
1154 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1158 anIdList->SetId( 0, anIdToVtk( aNodes[ 1 ] ) );
1159 anIdList->SetId( 1, anIdToVtk( aNodes[ 2 ] ) );
1160 anIdList->SetId( 2, anIdToVtk( aNodes[ 3 ] ) );
1161 aConnectivity->InsertNextCell( anIdList );
1162 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1164 anIdList->SetId( 0, anIdToVtk( aNodes[ 3 ] ) );
1165 anIdList->SetId( 1, anIdToVtk( aNodes[ 0 ] ) );
1166 anIdList->SetId( 2, anIdToVtk( aNodes[ 1 ] ) );
1167 aConnectivity->InsertNextCell( anIdList );
1168 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1172 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1173 aCellLocationsArray->SetNumberOfComponents( 1 );
1174 aCellLocationsArray->SetNumberOfTuples( aNbCells );
1176 aConnectivity->InitTraversal();
1177 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
1178 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
1180 aGrid->SetPoints( aPoints );
1181 aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
1183 // Create and display actor
1184 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1185 aMapper->SetInput( aGrid );
1187 myPreviewActor = SALOME_Actor::New();
1188 myPreviewActor->PickableOff();
1189 myPreviewActor->SetMapper( aMapper );
1191 vtkProperty* aProp = vtkProperty::New();
1192 aProp->SetRepresentationToWireframe();
1193 aProp->SetColor( 250, 0, 250 );
1194 aProp->SetLineWidth( myActor->GetLineWidth() + 1 );
1195 myPreviewActor->SetProperty( aProp );
1197 SMESH::GetCurrentVtkView()->AddActor( myPreviewActor );
1198 SMESH::GetCurrentVtkView()->Repaint();
1202 aConnectivity->Delete();
1206 aCellTypesArray->Delete();
1207 aCellLocationsArray->Delete();