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"
51 #include <vtkIdList.h>
52 #include <vtkIntArray.h>
53 #include <vtkCellArray.h>
54 #include <vtkUnsignedCharArray.h>
55 #include <vtkUnstructuredGrid.h>
56 #include <vtkDataSetMapper.h>
58 #include <TColStd_IndexedMapOfInteger.hxx>
59 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
60 #include <Precision.hxx>
61 #include <TColStd_DataMapOfIntegerInteger.hxx>
63 #include <qcheckbox.h>
65 #include <qgroupbox.h>
68 #include <qlineedit.h>
70 #include <qpushbutton.h>
71 #include <qapplication.h>
74 #include "SALOMEconfig.h"
75 #include CORBA_SERVER_HEADER(SMESH_Group)
81 Class : SMESHGUI_MultiEditDlg
82 Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
83 2 neighboring triangles with 1 common edge
86 //=======================================================================
87 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
88 // Purpose : Constructor
89 //=======================================================================
90 SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg( QWidget* theParent,
91 SALOME_Selection* theSelection,
94 : QDialog( theParent, theName, false,
95 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
98 mySubmeshFilter = new SMESH_TypeFilter( SUBMESH );
99 myGroupFilter = new SMESH_TypeFilter( GROUP );
101 myFilterType = theMode;
102 QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
104 QFrame* aMainFrame = createMainFrame ( this );
105 QFrame* aBtnFrame = createButtonFrame( this );
107 aDlgLay->addWidget( aMainFrame );
108 aDlgLay->addWidget( aBtnFrame );
110 aDlgLay->setStretchFactor( aMainFrame, 1 );
111 aDlgLay->setStretchFactor( aBtnFrame, 0 );
112 Init( theSelection ) ;
115 //=======================================================================
116 // name : SMESHGUI_MultiEditDlg::createMainFrame
117 // Purpose : Create frame containing dialog's input fields
118 //=======================================================================
119 QFrame* SMESHGUI_MultiEditDlg::createMainFrame( QWidget* theParent )
121 QGroupBox* aMainGrp = new QGroupBox( 1, Qt::Horizontal, theParent );
122 aMainGrp->setFrameStyle( QFrame::NoFrame );
123 aMainGrp->setInsideMargin( 0 );
125 QPixmap aPix( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
127 // "Selected cells" group
128 mySelGrp = new QGroupBox( 1, Qt::Horizontal, aMainGrp );
129 QFrame* aFrame = new QFrame( mySelGrp );
131 myListBox = new QListBox( aFrame );
132 myListBox->setSelectionMode( QListBox::Extended );
133 myListBox->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
134 // myListBox->setColumnMode( QListBox::FitToHeight );
136 myFilterBtn = new QPushButton( tr( "FILTER" ) , aFrame );
137 myAddBtn = new QPushButton( tr( "ADD" ) , aFrame );
138 myRemoveBtn = new QPushButton( tr( "REMOVE" ) , aFrame );
139 mySortBtn = new QPushButton( tr( "SORT_LIST" ), aFrame );
141 QGridLayout* aLay = new QGridLayout( aFrame, 5, 2, 0, 5 );
142 aLay->addMultiCellWidget( myListBox, 0, 4, 0, 0 );
143 aLay->addWidget( myFilterBtn, 0, 1 );
144 aLay->addWidget( myAddBtn, 1, 1 );
145 aLay->addWidget( myRemoveBtn, 2, 1 );
146 aLay->addWidget( mySortBtn, 3, 1 );
148 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
149 aLay->addItem( aSpacer, 4, 1 );
151 myToAllChk = new QCheckBox( tr( "TO_ALL" ), mySelGrp );
153 // "Select from" group
154 QGroupBox* aGrp = new QGroupBox( 3, Qt::Horizontal, tr( "SELECT_FROM" ), aMainGrp );
156 mySubmeshChk = new QCheckBox( tr( "SMESH_SUBMESH" ), aGrp );
157 mySubmeshBtn = new QPushButton( aGrp );
158 mySubmesh = new QLineEdit( aGrp );
159 mySubmesh->setReadOnly( true );
160 mySubmeshBtn->setPixmap( aPix );
162 myGroupChk = new QCheckBox( tr( "GROUP" ), aGrp );
163 myGroupBtn = new QPushButton( aGrp );
164 myGroup = new QLineEdit( aGrp );
165 myGroup->setReadOnly( true );
166 myGroupBtn->setPixmap( aPix );
171 //=======================================================================
172 // name : SMESHGUI_MultiEditDlg::createButtonFrame
173 // Purpose : Create frame containing buttons
174 //=======================================================================
175 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame( QWidget* theParent )
177 QFrame* aFrame = new QFrame( theParent );
178 aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken );
180 myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aFrame );
181 myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aFrame );
182 myCloseBtn = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aFrame );
184 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
186 QHBoxLayout* aLay = new QHBoxLayout( aFrame, MARGIN, SPACING );
188 aLay->addWidget( myOkBtn );
189 aLay->addWidget( myApplyBtn );
190 aLay->addItem( aSpacer);
191 aLay->addWidget( myCloseBtn );
196 //=======================================================================
197 // name : SMESHGUI_MultiEditDlg::isValid
198 // Purpose : Verify validity of input data
199 //=======================================================================
200 bool SMESHGUI_MultiEditDlg::isValid( const bool /*theMess*/ ) const
202 return (!myMesh->_is_nil() &&
203 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
206 //=======================================================================
207 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
208 // Purpose : Destructor
209 //=======================================================================
210 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
212 if ( myFilterDlg != 0 )
214 myFilterDlg->reparent( 0, QPoint() );
219 //=======================================================================
220 // name : SMESHGUI_MultiEditDlg::Init
221 // Purpose : Init dialog fields, connect signals and slots, show dialog
222 //=======================================================================
223 void SMESHGUI_MultiEditDlg::Init( SALOME_Selection* theSelection )
225 SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
226 mySelection = theSelection;
227 aSMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
232 emit ListContensChanged();
235 connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
236 connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
237 connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
239 // selection and SMESHGUI
240 connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
241 connect( aSMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
242 connect( aSMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
245 connect( myFilterBtn, SIGNAL( clicked() ), SLOT( onFilterBtn() ) );
246 connect( myAddBtn , SIGNAL( clicked() ), SLOT( onAddBtn() ) );
247 connect( myRemoveBtn, SIGNAL( clicked() ), SLOT( onRemoveBtn() ) );
248 connect( mySortBtn , SIGNAL( clicked() ), SLOT( onSortListBtn() ) );
250 connect( mySubmeshChk, SIGNAL( stateChanged( int ) ), SLOT( onSubmeshChk() ) );
251 connect( myGroupChk , SIGNAL( stateChanged( int ) ), SLOT( onGroupChk() ) );
252 connect( myToAllChk , SIGNAL( stateChanged( int ) ), SLOT( onToAllChk() ) );
254 connect( myListBox, SIGNAL( selectionChanged() ), SLOT( onListSelectionChanged() ) );
258 // set selection mode
263 //=======================================================================
264 // name : SMESHGUI_MultiEditDlg::onOk
265 // Purpose : SLOT called when "Ok" button pressed.
266 // Assign filters VTK viewer and close dialog
267 //=======================================================================
268 void SMESHGUI_MultiEditDlg::onOk()
274 //=======================================================================
275 // name : SMESHGUI_MultiEditDlg::getIds
276 // Purpose : Retrive identifiers from list box
277 //=======================================================================
278 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
280 SMESH::long_array_var anIds = new SMESH::long_array;
282 if ( myToAllChk->isChecked() )
287 TVisualObjPtr aVisualObj = myActor->GetObject();
288 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
291 for ( int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++ )
293 vtkCell* aCell = aGrid->GetCell( i );
296 int nbNodes = aCell->GetNumberOfPoints();
297 if ( nbNodes == 3 && myFilterType == SMESHGUI_TriaFilter ||
298 nbNodes == 4 && myFilterType == SMESHGUI_QuadFilter ||
299 ( nbNodes == 4 || nbNodes == 3 ) && myFilterType == SMESHGUI_UnknownFilter )
301 int anObjId = aVisualObj->GetElemObjId( i );
302 myIds.Add( anObjId );
310 anIds->length( myIds.Extent() );
311 TColStd_MapIteratorOfMapOfInteger anIter( myIds );
312 for ( int i = 0; anIter.More(); anIter.Next() )
314 anIds[ i++ ] = anIter.Key();
316 return anIds._retn();
319 //=======================================================================
320 // name : SMESHGUI_MultiEditDlg::onClose
321 // Purpose : SLOT called when "Close" button pressed. Close dialog
322 //=======================================================================
323 void SMESHGUI_MultiEditDlg::onClose()
325 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
326 disconnect( mySelection, 0, this, 0 );
327 disconnect( SMESHGUI::GetSMESHGUI(), 0, this, 0 );
328 SMESHGUI::GetSMESHGUI()->ResetState();
330 SMESH::RemoveFilter(SMESHGUI_EdgeFilter);
331 SMESH::RemoveFilter(SMESHGUI_FaceFilter);
332 SMESH::RemoveFilter(SMESHGUI_QuadFilter);
333 SMESH::RemoveFilter(SMESHGUI_TriaFilter);
334 SMESH::SetPickable();
336 mySelection->ClearIObjects();
337 mySelection->ClearFilters();
342 //=======================================================================
343 // name : SMESHGUI_MultiEditDlg::onSelectionDone
344 // Purpose : SLOT called when selection changed
345 //=======================================================================
346 void SMESHGUI_MultiEditDlg::onSelectionDone()
348 if ( myBusy || !isEnabled() ) return;
351 int nbSel = mySelection->IObjectCount();
352 myListBox->clearSelection();
354 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
356 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
357 int nbSel = mySelection->IObjectCount();
360 Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
361 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText( anIO->getName() );
363 if ( mySubmeshChk->isChecked() )
365 SMESH::SMESH_subMesh_var aSubMesh =
366 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIO );
367 if ( !aSubMesh->_is_nil() )
368 myMesh = aSubMesh->GetFather();
372 SMESH::SMESH_GroupBase_var aGroup =
373 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIO );
374 if ( !aGroup->_is_nil() )
375 myMesh = aGroup->GetMesh();
378 else if ( nbSel > 1 )
380 QString aStr = mySubmeshChk->isChecked() ?
381 tr( "SMESH_SUBMESH_SELECTED" ) : tr( "SMESH_GROUP_SELECTED" );
382 aNameEdit->setText( aStr.arg( nbSel ) );
387 else if ( nbSel == 1 )
389 QString aListStr = "";
390 int aNbItems = SMESH::GetNameOfSelectedElements(mySelection, aListStr);
393 QStringList anElements = QStringList::split(" ", aListStr);
394 QListBoxItem* anItem = 0;
395 for ( QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it)
397 anItem = myListBox->findItem( *it, Qt::ExactMatch );
398 if (anItem) myListBox->setSelected( anItem, true );
402 myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
406 myActor = SMESH::FindActorByEntry(mySelection->firstIObject()->getEntry());
408 myActor = SMESH::FindActorByObject( myMesh );
409 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
410 Handle(VTKViewer_Filter) aFilter1 = aStyle->GetFilter( myFilterType );
411 Handle(VTKViewer_Filter) aFilter2 = aStyle->GetFilter( SMESHGUI_FaceFilter );
412 if ( !aFilter1.IsNull() )
413 aFilter1->SetActor( myActor );
414 if ( !aFilter2.IsNull() )
415 aFilter2->SetActor( myActor );
417 SMESH::SetPickable(myActor);
424 //=======================================================================
425 // name : SMESHGUI_MultiEditDlg::onDeactivate
426 // Purpose : SLOT called when dialog must be deativated
427 //=======================================================================
428 void SMESHGUI_MultiEditDlg::onDeactivate()
433 //=======================================================================
434 // name : SMESHGUI_MultiEditDlg::enterEvent
435 // Purpose : Event filter
436 //=======================================================================
437 void SMESHGUI_MultiEditDlg::enterEvent( QEvent* )
439 if ( !isEnabled() ) {
440 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
447 //=================================================================================
448 // function : closeEvent()
450 //=================================================================================
451 void SMESHGUI_MultiEditDlg::closeEvent( QCloseEvent* e )
455 //=======================================================================
456 //function : hideEvent
457 //purpose : caused by ESC key
458 //=======================================================================
460 void SMESHGUI_MultiEditDlg::hideEvent ( QHideEvent * e )
462 if ( !isMinimized() )
466 //=======================================================================
467 // name : SMESHGUI_MultiEditDlg::onFilterBtn
468 // Purpose : SLOT. Called when "Filter" button pressed.
469 // Start "Selection filters" dialog
470 //=======================================================================
471 void SMESHGUI_MultiEditDlg::onFilterBtn()
473 if ( myFilterDlg == 0 )
475 myFilterDlg = new SMESHGUI_FilterDlg( (QWidget*)parent(), SMESH::FACE );
476 connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
479 myFilterDlg->Init( SMESH::FACE );
481 myFilterDlg->SetSelection( mySelection );
482 myFilterDlg->SetMesh( myMesh );
483 myFilterDlg->SetSourceWg( myListBox );
488 //=================================================================================
489 // function : onFilterAccepted()
490 // purpose : SLOT. Called when Filter dlg closed with OK button.
491 // Uncheck "Select submesh" and "Select group" checkboxes
492 //=================================================================================
493 void SMESHGUI_MultiEditDlg::onFilterAccepted()
496 for ( int i = 0, n = myListBox->count(); i < n; i++ )
497 myIds.Add( myListBox->text( i ).toInt() );
499 emit ListContensChanged();
501 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
503 mySubmeshChk->blockSignals( true );
504 myGroupChk->blockSignals( true );
505 mySubmeshChk->setChecked( false );
506 myGroupChk->setChecked( false );
507 mySubmeshChk->blockSignals( false );
508 myGroupChk->blockSignals( false );
513 //=======================================================================
514 // name : SMESHGUI_MultiEditDlg::onAddBtn
515 // Purpose : Verify whether Id of element satisfies to filters from viewer
516 //=======================================================================
517 bool SMESHGUI_MultiEditDlg::isIdValid( const int theId ) const
519 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
520 Handle(SMESHGUI_Filter) aFilter1 =
521 Handle(SMESHGUI_Filter)::DownCast( aStyle->GetFilter( myFilterType ) );
522 Handle(SMESHGUI_Filter) aFilter2 =
523 Handle(SMESHGUI_Filter)::DownCast( aStyle->GetFilter( SMESHGUI_FaceFilter ) );
524 return ( aFilter1.IsNull() || aFilter1->IsObjValid( theId ) ) &&
525 ( aFilter2.IsNull() || aFilter2->IsObjValid( theId ) );
528 //=======================================================================
529 // name : SMESHGUI_MultiEditDlg::onAddBtn
530 // Purpose : SLOT. Called when "Add" button pressed.
531 // Add selected in viewer entities in list box
532 //=======================================================================
533 void SMESHGUI_MultiEditDlg::onAddBtn()
535 int nbSelected = mySelection->IObjectCount();
536 if ( nbSelected == 0 )
539 TColStd_IndexedMapOfInteger toBeAdded;
541 if ( !mySubmeshChk->isChecked() && !myGroupChk->isChecked() )
543 if ( nbSelected == 1 )
544 SMESH::GetSelected( mySelection, toBeAdded );
546 else if ( mySubmeshChk->isChecked() )
548 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
549 for ( ; anIter.More(); anIter.Next() )
551 SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIter.Value() );
552 if ( !aSubMesh->_is_nil() )
554 if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
556 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
557 for ( int i = 0, n = anIds->length(); i < n; i++ )
559 if ( isIdValid( anIds[ i ] ) )
560 toBeAdded.Add( anIds[ i ] );
566 else if ( myGroupChk->isChecked() )
568 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
569 for ( ; anIter.More(); anIter.Next() )
571 SMESH::SMESH_GroupBase_var aGroup =
572 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Value() );
573 if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::FACE )
575 if ( aGroup->GetMesh()->GetId() == myMesh->GetId() )
577 SMESH::long_array_var anIds = aGroup->GetListOfID();
578 for ( int i = 0, n = anIds->length(); i < n; i++ )
580 if ( isIdValid( anIds[ i ] ) )
581 toBeAdded.Add( anIds[ i ] );
589 bool isGroupOrSubmesh = ( mySubmeshChk->isChecked() || myGroupChk->isChecked() );
590 mySubmeshChk->setChecked( false );
591 myGroupChk->setChecked( false );
592 for( int i = 1; i <= toBeAdded.Extent(); i++ )
593 if ( myIds.Add( toBeAdded(i) ) ) {
594 QListBoxItem * item = new QListBoxText( QString( "%1" ).arg( toBeAdded(i) ));
595 myListBox->insertItem( item );
596 myListBox->setSelected( item, true );
600 emit ListContensChanged();
602 if ( isGroupOrSubmesh )
603 onListSelectionChanged();
608 //=======================================================================
609 // name : SMESHGUI_MultiEditDlg::updateButtons
610 // Purpose : Enable/disable buttons of dialog in accordance with current state
611 //=======================================================================
612 void SMESHGUI_MultiEditDlg::updateButtons()
614 bool isOk = isValid(false);
615 myOkBtn->setEnabled( isOk );
616 myApplyBtn->setEnabled( isOk );
618 bool isListBoxNonEmpty = myListBox->count() > 0;
619 bool isToAll = myToAllChk->isChecked();
620 myFilterBtn->setEnabled( !isToAll );
621 myRemoveBtn->setEnabled( isListBoxNonEmpty && !isToAll );
622 mySortBtn->setEnabled( isListBoxNonEmpty &&!isToAll );
626 mySelection->IObjectCount() != 1 ||
627 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( mySelection->firstIObject() )->_is_nil() &&
628 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( mySelection->firstIObject() )->_is_nil() &&
629 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( mySelection->firstIObject() )->_is_nil()) )
630 myAddBtn->setEnabled( false );
632 myAddBtn->setEnabled( true );
634 mySubmeshChk->setEnabled( !isToAll );
635 mySubmeshBtn->setEnabled( mySubmeshChk->isChecked() );
636 mySubmesh->setEnabled( mySubmeshChk->isChecked() );
638 myGroupChk->setEnabled( !isToAll );
639 myGroupBtn->setEnabled( myGroupChk->isChecked() );
640 myGroup->setEnabled( myGroupChk->isChecked() );
642 if ( !mySubmeshChk->isChecked() )
644 if ( !myGroupChk->isChecked() )
649 //=======================================================================
650 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
651 // Purpose : SLOT. Called when "Remove" button pressed.
652 // Remove selected in list box entities
653 //=======================================================================
654 void SMESHGUI_MultiEditDlg::onRemoveBtn()
658 for ( int i = 0, n = myListBox->count(); i < n; i++ )
660 for ( int i = myListBox->count(); i > 0; i--) {
661 if ( myListBox->isSelected( i - 1 ) )
663 int anId = myListBox->text( i - 1 ).toInt();
664 myIds.Remove( anId );
665 myIds.Remove( anId );
666 myListBox->removeItem( i-1 );
672 emit ListContensChanged();
676 //=======================================================================
677 // name : SMESHGUI_MultiEditDlg::onSortListBtn
678 // Purpose : SLOT. Called when "Sort list" button pressed.
679 // Sort entities of list box
680 //=======================================================================
681 void SMESHGUI_MultiEditDlg::onSortListBtn()
685 int i, k = myListBox->count();
688 QStringList aSelected;
689 std::vector<int> anArray( k );
690 QListBoxItem* anItem;
691 for ( anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
693 anArray[ i ] = anItem->text().toInt();
694 if ( anItem->isSelected() )
695 aSelected.append( anItem->text() );
698 std::sort( anArray.begin(), anArray.end() );
700 for ( i = 0; i < k; i++ )
701 myListBox->insertItem( QString::number( anArray[ i ] ) );
703 for ( QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it )
705 anItem = myListBox->findItem( *it, Qt::ExactMatch );
707 myListBox->setSelected( anItem, true );
713 //=======================================================================
714 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
715 // Purpose : SLOT. Called when selection in list box changed.
716 // Highlight in selected entities
717 //=======================================================================
718 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
720 if ( myActor == 0 || myBusy )
723 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
726 SMESH_Actor * anActor = SMESH::FindActorByObject( myMesh );
729 TVisualObjPtr anObj = anActor->GetObject();
731 TColStd_MapOfInteger anIndexes;
732 for ( QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next() )
734 if ( anItem->isSelected() )
736 int anId = anItem->text().toInt();
737 if ( anObj->GetElemVTKId( anId ) >= 0 ) // avoid exception in hilight
742 mySelection->ClearIObjects();
743 mySelection->AddOrRemoveIndex( anActor->getIO(), anIndexes, false, false );
744 mySelection->AddIObject( anActor->getIO() );
747 //=======================================================================
748 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
749 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
750 // Activate/deactivate selection of submeshes
751 //=======================================================================
752 void SMESHGUI_MultiEditDlg::onSubmeshChk()
754 bool isChecked = mySubmeshChk->isChecked();
755 mySubmeshBtn->setEnabled( isChecked );
756 mySubmesh->setEnabled( isChecked );
759 if ( isChecked && myGroupChk->isChecked() )
760 myGroupChk->setChecked( false );
765 //=======================================================================
766 // name : SMESHGUI_MultiEditDlg::onGroupChk
767 // Purpose : SLOT. Called when state of "Group" check box changed.
768 // Activate/deactivate selection of groupes
769 //=======================================================================
770 void SMESHGUI_MultiEditDlg::onGroupChk()
772 bool isChecked = myGroupChk->isChecked();
773 myGroupBtn->setEnabled( isChecked );
774 myGroup->setEnabled( isChecked );
777 if ( isChecked && mySubmeshChk->isChecked() )
778 mySubmeshChk->setChecked( false );
783 //=======================================================================
784 // name : SMESHGUI_MultiEditDlg::onToAllChk
785 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
786 // Activate/deactivate selection
787 //=======================================================================
788 void SMESHGUI_MultiEditDlg::onToAllChk()
790 bool isChecked = myToAllChk->isChecked();
797 emit ListContensChanged();
803 mySelection->AddIObject( myActor->getIO(), true );
807 //=======================================================================
808 // name : SMESHGUI_MultiEditDlg::setSelectionMode
809 // Purpose : Set selection mode
810 //=======================================================================
811 void SMESHGUI_MultiEditDlg::setSelectionMode()
813 mySelection->ClearIObjects();
814 mySelection->ClearFilters();
816 if ( mySubmeshChk->isChecked() )
818 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
819 mySelection->AddFilter( mySubmeshFilter );
821 else if ( myGroupChk->isChecked() )
823 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
824 mySelection->AddFilter( myGroupFilter );
828 QAD_Application::getDesktop()->SetSelectionMode( FaceSelection, true );
829 if ( myFilterType == SMESHGUI_TriaFilter )
830 SMESH::SetFilter( new SMESHGUI_TriangleFilter() );
831 else if ( myFilterType == SMESHGUI_QuadFilter )
832 SMESH::SetFilter( new SMESHGUI_QuadrangleFilter() );
836 //=======================================================================
837 // name : SMESHGUI_MultiEditDlg::onApply
838 // Purpose : SLOT. Called when "Apply" button clicked.
839 //=======================================================================
840 bool SMESHGUI_MultiEditDlg::onApply()
842 if ( SMESHGUI::GetSMESHGUI()->ActiveStudyLocked() )
844 if ( !isValid( true ) )
847 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
848 if ( aMeshEditor->_is_nil() )
851 SMESH::long_array_var anIds = getIds();
853 bool aResult = process( aMeshEditor, anIds.inout() );
858 mySelection->ClearIObjects();
860 mySelection->AddIObject( myActor->getIO(), false );
865 emit ListContensChanged();
874 Class : SMESHGUI_ChangeOrientationDlg
875 Description : Modification of orientation of faces
878 SMESHGUI_ChangeOrientationDlg::SMESHGUI_ChangeOrientationDlg( QWidget* theParent,
879 SALOME_Selection* theSelection,
880 const char* theName )
881 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_UnknownFilter, theName )
883 setCaption( tr( "CAPTION" ) );
886 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
890 bool SMESHGUI_ChangeOrientationDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
891 const SMESH::long_array& theIds )
893 return theEditor->Reorient( theIds );
897 Class : SMESHGUI_UnionOfTrianglesDlg
898 Description : Construction of quadrangles by automatic association of triangles
901 SMESHGUI_UnionOfTrianglesDlg::SMESHGUI_UnionOfTrianglesDlg( QWidget* theParent,
902 SALOME_Selection* theSelection,
903 const char* theName )
904 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_TriaFilter, theName )
906 setCaption( tr( "CAPTION" ) );
909 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
913 bool SMESHGUI_UnionOfTrianglesDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
914 const SMESH::long_array& theIds )
916 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1. );
920 Class : SMESHGUI_CuttingOfQuadsDlg
921 Description : Construction of quadrangles by automatic association of triangles
924 SMESHGUI_CuttingOfQuadsDlg::SMESHGUI_CuttingOfQuadsDlg( QWidget* theParent,
925 SALOME_Selection* theSelection,
926 const char* theName )
927 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_QuadFilter, theName )
930 setCaption( tr( "CAPTION" ) );
933 myUseDiagChk = new QCheckBox( tr( "USE_DIAGONAL_2_4" ), mySelGrp );
934 myPreviewChk = new QCheckBox( tr( "PREVIEW" ), mySelGrp );
936 connect( myPreviewChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
937 connect( myUseDiagChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
938 connect( this, SIGNAL( ListContensChanged() ), this, SLOT( onPreviewChk() ) );
941 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
945 void SMESHGUI_CuttingOfQuadsDlg::onClose()
948 SMESHGUI_MultiEditDlg::onClose();
951 bool SMESHGUI_CuttingOfQuadsDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
952 const SMESH::long_array& theIds )
954 return theEditor->SplitQuad( theIds, !myUseDiagChk->isChecked() );
957 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
959 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
962 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
964 if ( myPreviewActor == 0 )
967 if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
969 vf->RemoveActor(myPreviewActor);
972 myPreviewActor->Delete();
976 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
981 if ( myPreviewActor != 0 )
984 // get Ids of elements
985 SMESH::long_array_var anElemIds = getIds();
986 if ( getIds()->length() == 0 )
989 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
993 bool isDiag24 = myUseDiagChk->isChecked();
996 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
998 vtkIdType aNbCells = anElemIds->length() * 2;
999 vtkIdType aCellsSize = 4 * aNbCells;
1000 vtkCellArray* aConnectivity = vtkCellArray::New();
1001 aConnectivity->Allocate( aCellsSize, 0 );
1003 vtkPoints* aPoints = vtkPoints::New();
1004 aPoints->SetNumberOfPoints( anElemIds->length() * 4 );
1006 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1007 aCellTypesArray->SetNumberOfComponents( 1 );
1008 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
1010 vtkIdList *anIdList = vtkIdList::New();
1011 anIdList->SetNumberOfIds( 3 );
1013 TColStd_DataMapOfIntegerInteger anIdToVtk;
1017 for ( int i = 0, n = anElemIds->length(); i < n; i++ )
1019 const SMDS_MeshElement* anElem = aMesh->FindElement( anElemIds[ i ] );
1020 if ( anElem == 0 || anElem->NbNodes() != 4 )
1023 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1025 while( anIter->more() )
1026 if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() )
1028 if ( !anIdToVtk.IsBound( aNode->GetID() ) )
1030 aPoints->SetPoint( ++nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
1031 anIdToVtk.Bind( aNode->GetID(), nbPoints );
1034 aNodes[ k++ ] = aNode->GetID();
1042 anIdList->SetId( 0, anIdToVtk( aNodes[ 0 ] ) );
1043 anIdList->SetId( 1, anIdToVtk( aNodes[ 1 ] ) );
1044 anIdList->SetId( 2, anIdToVtk( aNodes[ 2 ] ) );
1045 aConnectivity->InsertNextCell( anIdList );
1046 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1048 anIdList->SetId( 0, anIdToVtk( aNodes[ 2 ] ) );
1049 anIdList->SetId( 1, anIdToVtk( aNodes[ 3 ] ) );
1050 anIdList->SetId( 2, anIdToVtk( aNodes[ 0 ] ) );
1051 aConnectivity->InsertNextCell( anIdList );
1052 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1056 anIdList->SetId( 0, anIdToVtk( aNodes[ 1 ] ) );
1057 anIdList->SetId( 1, anIdToVtk( aNodes[ 2 ] ) );
1058 anIdList->SetId( 2, anIdToVtk( aNodes[ 3 ] ) );
1059 aConnectivity->InsertNextCell( anIdList );
1060 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1062 anIdList->SetId( 0, anIdToVtk( aNodes[ 3 ] ) );
1063 anIdList->SetId( 1, anIdToVtk( aNodes[ 0 ] ) );
1064 anIdList->SetId( 2, anIdToVtk( aNodes[ 1 ] ) );
1065 aConnectivity->InsertNextCell( anIdList );
1066 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1070 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1071 aCellLocationsArray->SetNumberOfComponents( 1 );
1072 aCellLocationsArray->SetNumberOfTuples( aNbCells );
1074 aConnectivity->InitTraversal();
1075 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
1076 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
1078 aGrid->SetPoints( aPoints );
1079 aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
1081 // Create and display actor
1082 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1083 aMapper->SetInput( aGrid );
1085 myPreviewActor = SALOME_Actor::New();
1086 myPreviewActor->PickableOff();
1087 myPreviewActor->SetMapper( aMapper );
1089 vtkProperty* aProp = vtkProperty::New();
1090 aProp->SetRepresentationToWireframe();
1091 aProp->SetColor( 250, 0, 250 );
1092 aProp->SetLineWidth( myActor->GetLineWidth() + 1 );
1093 myPreviewActor->SetProperty( aProp );
1095 SMESH::GetCurrentVtkView()->AddActor( myPreviewActor );
1096 SMESH::GetCurrentVtkView()->Repaint();
1100 aConnectivity->Delete();
1104 aCellTypesArray->Delete();
1105 aCellLocationsArray->Delete();