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 <vtkPolygon.h>
54 #include <vtkConvexPointSet.h>
55 #include <vtkIdList.h>
56 #include <vtkIntArray.h>
57 #include <vtkCellArray.h>
58 #include <vtkUnsignedCharArray.h>
59 #include <vtkUnstructuredGrid.h>
60 #include <vtkDataSetMapper.h>
62 #include <TColStd_IndexedMapOfInteger.hxx>
63 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
64 #include <Precision.hxx>
65 #include <TColStd_DataMapOfIntegerInteger.hxx>
67 #include <qcheckbox.h>
69 #include <qgroupbox.h>
72 #include <qlineedit.h>
74 #include <qpushbutton.h>
75 #include <qapplication.h>
76 #include <qhbuttongroup.h>
77 #include <qradiobutton.h>
80 #include "SALOMEconfig.h"
81 #include CORBA_SERVER_HEADER(SMESH_Group)
87 Class : SMESHGUI_MultiEditDlg
88 Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
89 2 neighboring triangles with 1 common edge
92 //=======================================================================
93 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
94 // Purpose : Constructor
95 //=======================================================================
96 SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg( QWidget* theParent,
97 SALOME_Selection* theSelection,
100 const char* theName )
101 : QDialog( theParent, theName, false,
102 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
105 mySubmeshFilter = new SMESH_TypeFilter( SUBMESH );
106 myGroupFilter = new SMESH_TypeFilter( GROUP );
110 myFilterType = theMode;
111 QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
113 QFrame* aMainFrame = createMainFrame ( this, the3d2d );
114 QFrame* aBtnFrame = createButtonFrame( this );
116 aDlgLay->addWidget( aMainFrame );
117 aDlgLay->addWidget( aBtnFrame );
119 aDlgLay->setStretchFactor( aMainFrame, 1 );
120 aDlgLay->setStretchFactor( aBtnFrame, 0 );
121 Init( theSelection ) ;
124 //=======================================================================
125 // name : SMESHGUI_MultiEditDlg::createMainFrame
126 // Purpose : Create frame containing dialog's input fields
127 //=======================================================================
128 QFrame* SMESHGUI_MultiEditDlg::createMainFrame( QWidget* theParent, const bool the3d2d )
130 QGroupBox* aMainGrp = new QGroupBox( 1, Qt::Horizontal, theParent );
131 aMainGrp->setFrameStyle( QFrame::NoFrame );
132 aMainGrp->setInsideMargin( 0 );
134 QPixmap aPix( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
136 // "Selected cells" group
137 mySelGrp = new QGroupBox( 1, Qt::Horizontal, aMainGrp );
141 myEntityTypeGrp = new QHButtonGroup( tr("SMESH_ELEMENTS_TYPE"), mySelGrp );
142 (new QRadioButton( tr("SMESH_FACE"), myEntityTypeGrp ))->setChecked( true );
143 (new QRadioButton( tr("SMESH_VOLUME"), myEntityTypeGrp ));
144 myEntityType = myEntityTypeGrp->id( myEntityTypeGrp->selected() );
147 QFrame* aFrame = new QFrame( mySelGrp );
149 myListBox = new QListBox( aFrame );
150 myListBox->setSelectionMode( QListBox::Extended );
151 myListBox->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
152 // myListBox->setColumnMode( QListBox::FitToHeight );
153 myListBox->installEventFilter( this );
155 myFilterBtn = new QPushButton( tr( "FILTER" ) , aFrame );
156 myAddBtn = new QPushButton( tr( "ADD" ) , aFrame );
157 myRemoveBtn = new QPushButton( tr( "REMOVE" ) , aFrame );
158 mySortBtn = new QPushButton( tr( "SORT_LIST" ), aFrame );
160 QGridLayout* aLay = new QGridLayout( aFrame, 5, 2, 0, 5 );
161 aLay->addMultiCellWidget( myListBox, 0, 4, 0, 0 );
162 aLay->addWidget( myFilterBtn, 0, 1 );
163 aLay->addWidget( myAddBtn, 1, 1 );
164 aLay->addWidget( myRemoveBtn, 2, 1 );
165 aLay->addWidget( mySortBtn, 3, 1 );
167 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
168 aLay->addItem( aSpacer, 4, 1 );
170 myToAllChk = new QCheckBox( tr( "TO_ALL" ), mySelGrp );
172 // "Select from" group
173 QGroupBox* aGrp = new QGroupBox( 3, Qt::Horizontal, tr( "SELECT_FROM" ), aMainGrp );
175 mySubmeshChk = new QCheckBox( tr( "SMESH_SUBMESH" ), aGrp );
176 mySubmeshBtn = new QPushButton( aGrp );
177 mySubmesh = new QLineEdit( aGrp );
178 mySubmesh->setReadOnly( true );
179 mySubmeshBtn->setPixmap( aPix );
181 myGroupChk = new QCheckBox( tr( "GROUP" ), aGrp );
182 myGroupBtn = new QPushButton( aGrp );
183 myGroup = new QLineEdit( aGrp );
184 myGroup->setReadOnly( true );
185 myGroupBtn->setPixmap( aPix );
190 //=======================================================================
191 // name : SMESHGUI_MultiEditDlg::createButtonFrame
192 // Purpose : Create frame containing buttons
193 //=======================================================================
194 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame( QWidget* theParent )
196 QFrame* aFrame = new QFrame( theParent );
197 aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken );
199 myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aFrame );
200 myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aFrame );
201 myCloseBtn = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aFrame );
203 QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
205 QHBoxLayout* aLay = new QHBoxLayout( aFrame, MARGIN, SPACING );
207 aLay->addWidget( myOkBtn );
208 aLay->addWidget( myApplyBtn );
209 aLay->addItem( aSpacer);
210 aLay->addWidget( myCloseBtn );
215 //=======================================================================
216 // name : SMESHGUI_MultiEditDlg::isValid
217 // Purpose : Verify validity of input data
218 //=======================================================================
219 bool SMESHGUI_MultiEditDlg::isValid( const bool /*theMess*/ ) const
221 return (!myMesh->_is_nil() &&
222 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
225 //=======================================================================
226 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
227 // Purpose : Destructor
228 //=======================================================================
229 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
231 if ( myFilterDlg != 0 )
233 myFilterDlg->reparent( 0, QPoint() );
238 //=======================================================================
239 // name : SMESHGUI_MultiEditDlg::eventFilter
240 // Purpose : event filter
241 //=======================================================================
242 bool SMESHGUI_MultiEditDlg::eventFilter( QObject* object, QEvent* event )
244 if ( object == myListBox && event->type() == QEvent::KeyPress ) {
245 QKeyEvent* ke = (QKeyEvent*)event;
246 if ( ke->key() == Key_Delete )
249 return QDialog::eventFilter( object, event );
252 //=======================================================================
253 // name : SMESHGUI_MultiEditDlg::Init
254 // Purpose : Init dialog fields, connect signals and slots, show dialog
255 //=======================================================================
256 void SMESHGUI_MultiEditDlg::Init( SALOME_Selection* theSelection )
258 SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
259 mySelection = theSelection;
260 aSMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
265 emit ListContensChanged();
268 connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
269 connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
270 connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
272 // selection and SMESHGUI
273 connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
274 connect( aSMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
275 connect( aSMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
278 connect( myFilterBtn, SIGNAL( clicked() ), SLOT( onFilterBtn() ) );
279 connect( myAddBtn , SIGNAL( clicked() ), SLOT( onAddBtn() ) );
280 connect( myRemoveBtn, SIGNAL( clicked() ), SLOT( onRemoveBtn() ) );
281 connect( mySortBtn , SIGNAL( clicked() ), SLOT( onSortListBtn() ) );
283 connect( mySubmeshChk, SIGNAL( stateChanged( int ) ), SLOT( onSubmeshChk() ) );
284 connect( myGroupChk , SIGNAL( stateChanged( int ) ), SLOT( onGroupChk() ) );
285 connect( myToAllChk , SIGNAL( stateChanged( int ) ), SLOT( onToAllChk() ) );
287 if ( myEntityTypeGrp )
288 connect( myEntityTypeGrp, SIGNAL( clicked(int) ), SLOT( on3d2dChanged(int) ) );
290 connect( myListBox, SIGNAL( selectionChanged() ), SLOT( onListSelectionChanged() ) );
294 // set selection mode
299 //=======================================================================
300 // name : SMESHGUI_MultiEditDlg::onOk
301 // Purpose : SLOT called when "Ok" button pressed.
302 // Assign filters VTK viewer and close dialog
303 //=======================================================================
304 void SMESHGUI_MultiEditDlg::onOk()
310 //=======================================================================
311 // name : SMESHGUI_MultiEditDlg::getIds
312 // Purpose : Retrive identifiers from list box
313 //=======================================================================
314 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
316 SMESH::long_array_var anIds = new SMESH::long_array;
318 if ( myToAllChk->isChecked() )
321 SMESH_Actor * anActor = SMESH::FindActorByObject( myMesh );
326 TVisualObjPtr aVisualObj = anActor->GetObject();
327 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
330 for ( int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++ )
332 vtkCell* aCell = aGrid->GetCell( i );
335 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
336 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
337 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
339 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
340 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
342 if ( aTri && myFilterType == SMESHGUI_TriaFilter ||
343 aQua && myFilterType == SMESHGUI_QuadFilter ||
344 ( aTri || aQua || aPG ) && myFilterType == SMESHGUI_FaceFilter ||
345 ( a3d || aPH ) && myFilterType == SMESHGUI_VolumeFilter )
347 int anObjId = aVisualObj->GetElemObjId( i );
348 myIds.Add( anObjId );
356 anIds->length( myIds.Extent() );
357 TColStd_MapIteratorOfMapOfInteger anIter( myIds );
358 for ( int i = 0; anIter.More(); anIter.Next() )
360 anIds[ i++ ] = anIter.Key();
362 return anIds._retn();
365 //=======================================================================
366 // name : SMESHGUI_MultiEditDlg::onClose
367 // Purpose : SLOT called when "Close" button pressed. Close dialog
368 //=======================================================================
369 void SMESHGUI_MultiEditDlg::onClose()
371 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
372 disconnect( mySelection, 0, this, 0 );
373 disconnect( SMESHGUI::GetSMESHGUI(), 0, this, 0 );
374 SMESHGUI::GetSMESHGUI()->ResetState();
376 SMESH::RemoveFilters();
377 SMESH::SetPickable();
379 mySelection->ClearIObjects();
380 mySelection->ClearFilters();
385 //=======================================================================
386 // name : SMESHGUI_MultiEditDlg::onSelectionDone
387 // Purpose : SLOT called when selection changed
388 //=======================================================================
389 void SMESHGUI_MultiEditDlg::onSelectionDone()
391 if ( myBusy || !isEnabled() ) return;
394 int nbSel = mySelection->IObjectCount();
395 myListBox->clearSelection();
397 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
399 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
400 int nbSel = mySelection->IObjectCount();
403 Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
404 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText( anIO->getName() );
406 if ( mySubmeshChk->isChecked() )
408 SMESH::SMESH_subMesh_var aSubMesh =
409 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIO );
410 if ( !aSubMesh->_is_nil() )
411 myMesh = aSubMesh->GetFather();
415 SMESH::SMESH_GroupBase_var aGroup =
416 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIO );
417 if ( !aGroup->_is_nil() )
418 myMesh = aGroup->GetMesh();
421 else if ( nbSel > 1 )
423 QString aStr = mySubmeshChk->isChecked() ?
424 tr( "SMESH_SUBMESH_SELECTED" ) : tr( "SMESH_GROUP_SELECTED" );
425 aNameEdit->setText( aStr.arg( nbSel ) );
430 else if ( nbSel == 1 )
432 QString aListStr = "";
433 int aNbItems = SMESH::GetNameOfSelectedElements(mySelection, aListStr);
436 QStringList anElements = QStringList::split(" ", aListStr);
437 QListBoxItem* anItem = 0;
438 for ( QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it)
440 anItem = myListBox->findItem( *it, Qt::ExactMatch );
441 if (anItem) myListBox->setSelected( anItem, true );
445 myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
449 myActor = SMESH::FindActorByEntry(mySelection->firstIObject()->getEntry());
451 myActor = SMESH::FindActorByObject( myMesh );
452 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
453 Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter( myFilterType );
454 if ( !aFilter.IsNull() )
455 aFilter->SetActor( myActor );
457 // SMESH::SetPickable(myActor);
464 //=======================================================================
465 // name : SMESHGUI_MultiEditDlg::onDeactivate
466 // Purpose : SLOT called when dialog must be deativated
467 //=======================================================================
468 void SMESHGUI_MultiEditDlg::onDeactivate()
473 //=======================================================================
474 // name : SMESHGUI_MultiEditDlg::enterEvent
475 // Purpose : Event filter
476 //=======================================================================
477 void SMESHGUI_MultiEditDlg::enterEvent( QEvent* )
479 if ( !isEnabled() ) {
480 SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
487 //=================================================================================
488 // function : closeEvent()
490 //=================================================================================
491 void SMESHGUI_MultiEditDlg::closeEvent( QCloseEvent* e )
495 //=======================================================================
496 //function : hideEvent
497 //purpose : caused by ESC key
498 //=======================================================================
500 void SMESHGUI_MultiEditDlg::hideEvent ( QHideEvent * e )
502 if ( !isMinimized() )
506 //=======================================================================
507 // name : SMESHGUI_MultiEditDlg::onFilterBtn
508 // Purpose : SLOT. Called when "Filter" button pressed.
509 // Start "Selection filters" dialog
510 //=======================================================================
511 void SMESHGUI_MultiEditDlg::onFilterBtn()
513 if ( myFilterDlg == 0 )
515 myFilterDlg = new SMESHGUI_FilterDlg( (QWidget*)parent(), entityType() ? SMESH::VOLUME : SMESH::FACE );
516 connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
519 myFilterDlg->Init( entityType() ? SMESH::VOLUME : SMESH::FACE );
521 myFilterDlg->SetSelection( mySelection );
522 myFilterDlg->SetMesh( myMesh );
523 myFilterDlg->SetSourceWg( myListBox );
528 //=================================================================================
529 // function : onFilterAccepted()
530 // purpose : SLOT. Called when Filter dlg closed with OK button.
531 // Uncheck "Select submesh" and "Select group" checkboxes
532 //=================================================================================
533 void SMESHGUI_MultiEditDlg::onFilterAccepted()
536 for ( int i = 0, n = myListBox->count(); i < n; i++ )
537 myIds.Add( myListBox->text( i ).toInt() );
539 emit ListContensChanged();
541 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
543 mySubmeshChk->blockSignals( true );
544 myGroupChk->blockSignals( true );
545 mySubmeshChk->setChecked( false );
546 myGroupChk->setChecked( false );
547 mySubmeshChk->blockSignals( false );
548 myGroupChk->blockSignals( false );
553 //=======================================================================
554 // name : SMESHGUI_MultiEditDlg::isIdValid
555 // Purpose : Verify whether Id of element satisfies to filters from viewer
556 //=======================================================================
557 bool SMESHGUI_MultiEditDlg::isIdValid( const int theId ) const
559 VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle();
560 Handle(SMESHGUI_Filter) aFilter =
561 Handle(SMESHGUI_Filter)::DownCast( aStyle->GetFilter( myFilterType ) );
563 return ( !aFilter.IsNull() && aFilter->IsObjValid( theId ) );
566 //=======================================================================
567 // name : SMESHGUI_MultiEditDlg::onAddBtn
568 // Purpose : SLOT. Called when "Add" button pressed.
569 // Add selected in viewer entities in list box
570 //=======================================================================
571 void SMESHGUI_MultiEditDlg::onAddBtn()
573 int nbSelected = mySelection->IObjectCount();
574 if ( nbSelected == 0 )
577 TColStd_IndexedMapOfInteger toBeAdded;
579 if ( !mySubmeshChk->isChecked() && !myGroupChk->isChecked() )
581 if ( nbSelected == 1 )
582 SMESH::GetSelected( mySelection, toBeAdded );
584 else if ( mySubmeshChk->isChecked() )
586 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
587 for ( ; anIter.More(); anIter.Next() )
589 SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIter.Value() );
590 if ( !aSubMesh->_is_nil() )
592 if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
594 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
595 for ( int i = 0, n = anIds->length(); i < n; i++ )
597 if ( isIdValid( anIds[ i ] ) )
598 toBeAdded.Add( anIds[ i ] );
604 else if ( myGroupChk->isChecked() )
606 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
607 for ( ; anIter.More(); anIter.Next() )
609 SMESH::SMESH_GroupBase_var aGroup =
610 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Value() );
611 if ( !aGroup->_is_nil() && ( aGroup->GetType() == SMESH::FACE && entityType() == 0 || aGroup->GetType() == SMESH::VOLUME && entityType() == 1 ) )
613 if ( aGroup->GetMesh()->GetId() == myMesh->GetId() )
615 SMESH::long_array_var anIds = aGroup->GetListOfID();
616 for ( int i = 0, n = anIds->length(); i < n; i++ )
618 if ( isIdValid( anIds[ i ] ) )
619 toBeAdded.Add( anIds[ i ] );
627 bool isGroupOrSubmesh = ( mySubmeshChk->isChecked() || myGroupChk->isChecked() );
628 mySubmeshChk->setChecked( false );
629 myGroupChk->setChecked( false );
630 for( int i = 1; i <= toBeAdded.Extent(); i++ )
631 if ( myIds.Add( toBeAdded(i) ) ) {
632 QListBoxItem * item = new QListBoxText( QString( "%1" ).arg( toBeAdded(i) ));
633 myListBox->insertItem( item );
634 myListBox->setSelected( item, true );
638 emit ListContensChanged();
640 if ( isGroupOrSubmesh )
641 onListSelectionChanged();
646 //=======================================================================
647 // name : SMESHGUI_MultiEditDlg::updateButtons
648 // Purpose : Enable/disable buttons of dialog in accordance with current state
649 //=======================================================================
650 void SMESHGUI_MultiEditDlg::updateButtons()
652 bool isOk = isValid(false);
653 myOkBtn->setEnabled( isOk );
654 myApplyBtn->setEnabled( isOk );
656 bool isListBoxNonEmpty = myListBox->count() > 0;
657 bool isToAll = myToAllChk->isChecked();
658 myFilterBtn->setEnabled( !isToAll );
659 myRemoveBtn->setEnabled( isListBoxNonEmpty && !isToAll );
660 mySortBtn->setEnabled( isListBoxNonEmpty &&!isToAll );
664 mySelection->IObjectCount() != 1 ||
665 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( mySelection->firstIObject() )->_is_nil() &&
666 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( mySelection->firstIObject() )->_is_nil() &&
667 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( mySelection->firstIObject() )->_is_nil()) )
668 myAddBtn->setEnabled( false );
670 myAddBtn->setEnabled( true );
672 mySubmeshChk->setEnabled( !isToAll );
673 mySubmeshBtn->setEnabled( mySubmeshChk->isChecked() );
674 mySubmesh->setEnabled( mySubmeshChk->isChecked() );
676 myGroupChk->setEnabled( !isToAll );
677 myGroupBtn->setEnabled( myGroupChk->isChecked() );
678 myGroup->setEnabled( myGroupChk->isChecked() );
680 if ( !mySubmeshChk->isChecked() )
682 if ( !myGroupChk->isChecked() )
687 //=======================================================================
688 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
689 // Purpose : SLOT. Called when "Remove" button pressed.
690 // Remove selected in list box entities
691 //=======================================================================
692 void SMESHGUI_MultiEditDlg::onRemoveBtn()
696 for ( int i = 0, n = myListBox->count(); i < n; i++ )
698 for ( int i = myListBox->count(); i > 0; i--) {
699 if ( myListBox->isSelected( i - 1 ) )
701 int anId = myListBox->text( i - 1 ).toInt();
702 myIds.Remove( anId );
703 myIds.Remove( anId );
704 myListBox->removeItem( i-1 );
710 emit ListContensChanged();
714 //=======================================================================
715 // name : SMESHGUI_MultiEditDlg::onSortListBtn
716 // Purpose : SLOT. Called when "Sort list" button pressed.
717 // Sort entities of list box
718 //=======================================================================
719 void SMESHGUI_MultiEditDlg::onSortListBtn()
723 int i, k = myListBox->count();
726 QStringList aSelected;
727 std::vector<int> anArray( k );
728 QListBoxItem* anItem;
729 for ( anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
731 anArray[ i ] = anItem->text().toInt();
732 if ( anItem->isSelected() )
733 aSelected.append( anItem->text() );
736 std::sort( anArray.begin(), anArray.end() );
738 for ( i = 0; i < k; i++ )
739 myListBox->insertItem( QString::number( anArray[ i ] ) );
741 for ( QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it )
743 anItem = myListBox->findItem( *it, Qt::ExactMatch );
745 myListBox->setSelected( anItem, true );
751 //=======================================================================
752 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
753 // Purpose : SLOT. Called when selection in list box changed.
754 // Highlight in selected entities
755 //=======================================================================
756 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
758 if ( myActor == 0 || myBusy )
761 if ( mySubmeshChk->isChecked() || myGroupChk->isChecked() )
764 SMESH_Actor * anActor = SMESH::FindActorByObject( myMesh );
767 TVisualObjPtr anObj = anActor->GetObject();
769 TColStd_MapOfInteger anIndexes;
770 for ( QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next() )
772 if ( anItem->isSelected() )
774 int anId = anItem->text().toInt();
775 if ( anObj->GetElemVTKId( anId ) >= 0 ) // avoid exception in hilight
780 mySelection->ClearIObjects();
781 mySelection->AddOrRemoveIndex( anActor->getIO(), anIndexes, false, false );
782 mySelection->AddIObject( anActor->getIO() );
785 //=======================================================================
786 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
787 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
788 // Activate/deactivate selection of submeshes
789 //=======================================================================
790 void SMESHGUI_MultiEditDlg::onSubmeshChk()
792 bool isChecked = mySubmeshChk->isChecked();
793 mySubmeshBtn->setEnabled( isChecked );
794 mySubmesh->setEnabled( isChecked );
797 if ( isChecked && myGroupChk->isChecked() )
798 myGroupChk->setChecked( false );
803 //=======================================================================
804 // name : SMESHGUI_MultiEditDlg::onGroupChk
805 // Purpose : SLOT. Called when state of "Group" check box changed.
806 // Activate/deactivate selection of groupes
807 //=======================================================================
808 void SMESHGUI_MultiEditDlg::onGroupChk()
810 bool isChecked = myGroupChk->isChecked();
811 myGroupBtn->setEnabled( isChecked );
812 myGroup->setEnabled( isChecked );
815 if ( isChecked && mySubmeshChk->isChecked() )
816 mySubmeshChk->setChecked( false );
821 //=======================================================================
822 // name : SMESHGUI_MultiEditDlg::onToAllChk
823 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
824 // Activate/deactivate selection
825 //=======================================================================
826 void SMESHGUI_MultiEditDlg::onToAllChk()
828 bool isChecked = myToAllChk->isChecked();
835 emit ListContensChanged();
841 mySelection->AddIObject( myActor->getIO(), true );
845 //=======================================================================
846 // name : SMESHGUI_MultiEditDlg::setSelectionMode
847 // Purpose : Set selection mode
848 //=======================================================================
849 void SMESHGUI_MultiEditDlg::setSelectionMode()
851 SMESH::RemoveFilters();
853 mySelection->ClearIObjects();
854 mySelection->ClearFilters();
856 if ( mySubmeshChk->isChecked() ) {
857 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
858 mySelection->AddFilter( mySubmeshFilter );
860 else if ( myGroupChk->isChecked() ) {
861 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection, true );
862 mySelection->AddFilter( myGroupFilter );
864 if ( entityType() ) {
865 QAD_Application::getDesktop()->SetSelectionMode( VolumeSelection, true );
866 SMESH::SetFilter( new SMESHGUI_VolumesFilter() );
869 QAD_Application::getDesktop()->SetSelectionMode( FaceSelection, true );
870 if ( myFilterType == SMESHGUI_TriaFilter )
871 SMESH::SetFilter( new SMESHGUI_TriangleFilter() );
872 else if ( myFilterType == SMESHGUI_QuadFilter )
873 SMESH::SetFilter( new SMESHGUI_QuadrangleFilter() );
875 SMESH::SetFilter( new SMESHGUI_FacesFilter() );
879 //=======================================================================
880 // name : SMESHGUI_MultiEditDlg::onApply
881 // Purpose : SLOT. Called when "Apply" button clicked.
882 //=======================================================================
883 bool SMESHGUI_MultiEditDlg::onApply()
885 if ( SMESHGUI::GetSMESHGUI()->ActiveStudyLocked() )
887 if ( !isValid( true ) )
890 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
891 if ( aMeshEditor->_is_nil() )
896 SMESH::long_array_var anIds = getIds();
898 bool aResult = process( aMeshEditor, anIds.inout() );
903 mySelection->ClearIObjects();
905 mySelection->AddIObject( myActor->getIO(), false );
910 emit ListContensChanged();
919 //=======================================================================
920 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
922 //=======================================================================
923 void SMESHGUI_MultiEditDlg::on3d2dChanged(int type)
925 if ( myEntityType != type ) {
931 emit ListContensChanged();
934 myFilterType = SMESHGUI_VolumeFilter;
936 myFilterType = SMESHGUI_FaceFilter;
943 //=======================================================================
944 // name : SMESHGUI_MultiEditDlg::entityType
946 //=======================================================================
948 int SMESHGUI_MultiEditDlg::entityType()
954 Class : SMESHGUI_ChangeOrientationDlg
955 Description : Modification of orientation of faces
958 SMESHGUI_ChangeOrientationDlg::SMESHGUI_ChangeOrientationDlg( QWidget* theParent,
959 SALOME_Selection* theSelection,
960 const char* theName )
961 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_FaceFilter, true, theName )
963 setCaption( tr( "CAPTION" ) );
966 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
970 bool SMESHGUI_ChangeOrientationDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
971 const SMESH::long_array& theIds )
973 return theEditor->Reorient( theIds );
977 Class : SMESHGUI_UnionOfTrianglesDlg
978 Description : Construction of quadrangles by automatic association of triangles
981 SMESHGUI_UnionOfTrianglesDlg::SMESHGUI_UnionOfTrianglesDlg( QWidget* theParent,
982 SALOME_Selection* theSelection,
983 const char* theName )
984 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_TriaFilter, false, theName )
986 setCaption( tr( "CAPTION" ) );
989 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
993 bool SMESHGUI_UnionOfTrianglesDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
994 const SMESH::long_array& theIds )
996 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1. );
1000 Class : SMESHGUI_CuttingOfQuadsDlg
1001 Description : Construction of quadrangles by automatic association of triangles
1004 SMESHGUI_CuttingOfQuadsDlg::SMESHGUI_CuttingOfQuadsDlg( QWidget* theParent,
1005 SALOME_Selection* theSelection,
1006 const char* theName )
1007 : SMESHGUI_MultiEditDlg( theParent, theSelection, SMESHGUI_QuadFilter, false, theName )
1010 setCaption( tr( "CAPTION" ) );
1013 myUseDiagChk = new QCheckBox( tr( "USE_DIAGONAL_2_4" ), mySelGrp );
1014 myPreviewChk = new QCheckBox( tr( "PREVIEW" ), mySelGrp );
1016 connect( myPreviewChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
1017 connect( myUseDiagChk, SIGNAL( stateChanged( int ) ), this, SLOT( onPreviewChk() ) );
1018 connect( this, SIGNAL( ListContensChanged() ), this, SLOT( onPreviewChk() ) );
1021 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1025 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1028 SMESHGUI_MultiEditDlg::onClose();
1031 bool SMESHGUI_CuttingOfQuadsDlg::process( SMESH::SMESH_MeshEditor_ptr theEditor,
1032 const SMESH::long_array& theIds )
1034 return theEditor->SplitQuad( theIds, !myUseDiagChk->isChecked() );
1037 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1039 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1042 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1044 if ( myPreviewActor == 0 )
1047 if ( VTKViewer_ViewFrame* vf = SMESH::GetCurrentVtkView() )
1049 vf->RemoveActor(myPreviewActor);
1052 myPreviewActor->Delete();
1056 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1061 if ( myPreviewActor != 0 )
1064 // get Ids of elements
1065 SMESH::long_array_var anElemIds = getIds();
1066 if ( getIds()->length() == 0 )
1069 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1073 bool isDiag24 = myUseDiagChk->isChecked();
1076 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1078 vtkIdType aNbCells = anElemIds->length() * 2;
1079 vtkIdType aCellsSize = 4 * aNbCells;
1080 vtkCellArray* aConnectivity = vtkCellArray::New();
1081 aConnectivity->Allocate( aCellsSize, 0 );
1083 vtkPoints* aPoints = vtkPoints::New();
1084 aPoints->SetNumberOfPoints( anElemIds->length() * 4 );
1086 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1087 aCellTypesArray->SetNumberOfComponents( 1 );
1088 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
1090 vtkIdList *anIdList = vtkIdList::New();
1091 anIdList->SetNumberOfIds( 3 );
1093 TColStd_DataMapOfIntegerInteger anIdToVtk;
1097 for ( int i = 0, n = anElemIds->length(); i < n; i++ )
1099 const SMDS_MeshElement* anElem = aMesh->FindElement( anElemIds[ i ] );
1100 if ( anElem == 0 || anElem->NbNodes() != 4 )
1103 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1105 while( anIter->more() )
1106 if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() )
1108 if ( !anIdToVtk.IsBound( aNode->GetID() ) )
1110 aPoints->SetPoint( ++nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
1111 anIdToVtk.Bind( aNode->GetID(), nbPoints );
1114 aNodes[ k++ ] = aNode->GetID();
1122 anIdList->SetId( 0, anIdToVtk( aNodes[ 0 ] ) );
1123 anIdList->SetId( 1, anIdToVtk( aNodes[ 1 ] ) );
1124 anIdList->SetId( 2, anIdToVtk( aNodes[ 2 ] ) );
1125 aConnectivity->InsertNextCell( anIdList );
1126 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1128 anIdList->SetId( 0, anIdToVtk( aNodes[ 2 ] ) );
1129 anIdList->SetId( 1, anIdToVtk( aNodes[ 3 ] ) );
1130 anIdList->SetId( 2, anIdToVtk( aNodes[ 0 ] ) );
1131 aConnectivity->InsertNextCell( anIdList );
1132 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1136 anIdList->SetId( 0, anIdToVtk( aNodes[ 1 ] ) );
1137 anIdList->SetId( 1, anIdToVtk( aNodes[ 2 ] ) );
1138 anIdList->SetId( 2, anIdToVtk( aNodes[ 3 ] ) );
1139 aConnectivity->InsertNextCell( anIdList );
1140 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1142 anIdList->SetId( 0, anIdToVtk( aNodes[ 3 ] ) );
1143 anIdList->SetId( 1, anIdToVtk( aNodes[ 0 ] ) );
1144 anIdList->SetId( 2, anIdToVtk( aNodes[ 1 ] ) );
1145 aConnectivity->InsertNextCell( anIdList );
1146 aCellTypesArray->InsertNextValue( VTK_TRIANGLE );
1150 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1151 aCellLocationsArray->SetNumberOfComponents( 1 );
1152 aCellLocationsArray->SetNumberOfTuples( aNbCells );
1154 aConnectivity->InitTraversal();
1155 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
1156 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
1158 aGrid->SetPoints( aPoints );
1159 aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
1161 // Create and display actor
1162 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1163 aMapper->SetInput( aGrid );
1165 myPreviewActor = SALOME_Actor::New();
1166 myPreviewActor->PickableOff();
1167 myPreviewActor->SetMapper( aMapper );
1169 vtkProperty* aProp = vtkProperty::New();
1170 aProp->SetRepresentationToWireframe();
1171 aProp->SetColor( 250, 0, 250 );
1172 aProp->SetLineWidth( myActor->GetLineWidth() + 1 );
1173 myPreviewActor->SetProperty( aProp );
1175 SMESH::GetCurrentVtkView()->AddActor( myPreviewActor );
1176 SMESH::GetCurrentVtkView()->Repaint();
1180 aConnectivity->Delete();
1184 aCellTypesArray->Delete();
1185 aCellLocationsArray->Delete();