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"
31 #include "SMESHGUI_Filter.h"
32 #include "SMESHGUI_FilterDlg.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
36 #include "SMESHGUI_FilterUtils.h"
37 #include "SMESHGUI_SpinBox.h"
39 #include "SMESH_Actor.h"
40 #include "SMESH_TypeFilter.hxx"
41 #include "SMDS_Mesh.hxx"
42 #include "SMDS_MeshElement.hxx"
44 #include "SUIT_ResourceMgr.h"
45 #include "SUIT_Desktop.h"
47 #include "LightApp_SelectionMgr.h"
48 #include "SALOME_ListIO.hxx"
49 #include "SALOME_ListIteratorOfListIO.hxx"
51 #include "SVTK_Selector.h"
52 #include "SVTK_ViewModel.h"
53 #include "SVTK_ViewWindow.h"
56 #include <Precision.hxx>
57 #include <TColStd_IndexedMapOfInteger.hxx>
58 #include <TColStd_DataMapOfIntegerInteger.hxx>
59 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
62 #include <vtkCell3D.h>
64 #include <vtkTriangle.h>
65 #include <vtkPolygon.h>
66 #include <vtkConvexPointSet.h>
67 #include <vtkIdList.h>
68 #include <vtkIntArray.h>
69 #include <vtkCellArray.h>
70 #include <vtkUnsignedCharArray.h>
71 #include <vtkUnstructuredGrid.h>
72 #include <vtkDataSetMapper.h>
73 #include <vtkProperty.h>
80 #include <qcheckbox.h>
81 #include <qcombobox.h>
82 #include <qgroupbox.h>
83 #include <qlineedit.h>
84 #include <qpushbutton.h>
85 #include <qapplication.h>
86 #include <qradiobutton.h>
87 #include <qhbuttongroup.h>
90 #include "SALOMEconfig.h"
91 #include CORBA_SERVER_HEADER(SMESH_Group)
97 * Class : SMESHGUI_MultiEditDlg
98 * Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
99 * 2 neighboring triangles with 1 common edge
102 //=======================================================================
103 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
104 // Purpose : Constructor
105 //=======================================================================
106 SMESHGUI_MultiEditDlg
107 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
110 const char* theName):
111 QDialog(SMESH::GetDesktop(theModule),
114 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
115 mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
116 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
117 mySMESHGUI(theModule)
122 myFilterType = theMode;
123 QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
125 QFrame* aMainFrame = createMainFrame (this, the3d2d);
126 QFrame* aBtnFrame = createButtonFrame(this);
128 aDlgLay->addWidget(aMainFrame);
129 aDlgLay->addWidget(aBtnFrame);
131 aDlgLay->setStretchFactor(aMainFrame, 1);
132 aDlgLay->setStretchFactor(aBtnFrame, 0);
136 //=======================================================================
137 // name : SMESHGUI_MultiEditDlg::createMainFrame
138 // Purpose : Create frame containing dialog's input fields
139 //=======================================================================
140 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
142 QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
143 aMainGrp->setFrameStyle(QFrame::NoFrame);
144 aMainGrp->setInsideMargin(0);
146 QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
148 // "Selected cells" group
149 mySelGrp = new QGroupBox(1, Qt::Horizontal, aMainGrp);
153 myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
154 (new QRadioButton(tr("SMESH_FACE"), myEntityTypeGrp))->setChecked(true);
155 (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
156 myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
159 QFrame* aFrame = new QFrame(mySelGrp);
161 myListBox = new QListBox(aFrame);
162 myListBox->setSelectionMode(QListBox::Extended);
163 myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
164 myListBox->installEventFilter(this);
166 myFilterBtn = new QPushButton(tr("FILTER") , aFrame);
167 myAddBtn = new QPushButton(tr("ADD") , aFrame);
168 myRemoveBtn = new QPushButton(tr("REMOVE") , aFrame);
169 mySortBtn = new QPushButton(tr("SORT_LIST"), aFrame);
171 QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
172 aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
173 aLay->addWidget(myFilterBtn, 0, 1);
174 aLay->addWidget(myAddBtn, 1, 1);
175 aLay->addWidget(myRemoveBtn, 2, 1);
176 aLay->addWidget(mySortBtn, 3, 1);
178 QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
179 aLay->addItem(aSpacer, 4, 1);
181 myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
183 // Split/Join criterion group
184 myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp);
186 myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp);
187 myGroupChoice->setInsideMargin(0);
188 myGroupChoice->setFrameStyle(QFrame::NoFrame);
189 (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true);
190 (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice));
191 (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice));
193 myComboBoxFunctor = new QComboBox(myCriterionGrp);
194 myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS"));
195 myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS"));
196 myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS"));
197 myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS"));
198 //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only
199 //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only
200 myComboBoxFunctor->setCurrentItem(0);
202 myCriterionGrp->hide();
203 myGroupChoice->hide();
204 myComboBoxFunctor->setEnabled(false);
206 // "Select from" group
207 QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
209 mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
210 mySubmeshBtn = new QPushButton(aGrp);
211 mySubmesh = new QLineEdit(aGrp);
212 mySubmesh->setReadOnly(true);
213 mySubmeshBtn->setPixmap(aPix);
215 myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp);
216 myGroupBtn = new QPushButton(aGrp);
217 myGroup = new QLineEdit(aGrp);
218 myGroup->setReadOnly(true);
219 myGroupBtn->setPixmap(aPix);
224 //=======================================================================
225 // name : SMESHGUI_MultiEditDlg::createButtonFrame
226 // Purpose : Create frame containing buttons
227 //=======================================================================
228 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
230 QFrame* aFrame = new QFrame (theParent);
231 aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
233 myOkBtn = new QPushButton (tr("SMESH_BUT_OK" ), aFrame);
234 myApplyBtn = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
235 myCloseBtn = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
237 QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
239 QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
241 aLay->addWidget(myOkBtn);
242 aLay->addWidget(myApplyBtn);
243 aLay->addItem(aSpacer);
244 aLay->addWidget(myCloseBtn);
249 //=======================================================================
250 // name : SMESHGUI_MultiEditDlg::isValid
251 // Purpose : Verify validity of input data
252 //=======================================================================
253 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
255 return (!myMesh->_is_nil() &&
256 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
259 //=======================================================================
260 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
261 // Purpose : Destructor
262 //=======================================================================
263 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
265 if (myFilterDlg != 0)
267 myFilterDlg->reparent(0, QPoint());
272 //=======================================================================
273 // name : SMESHGUI_MultiEditDlg::eventFilter
274 // Purpose : event filter
275 //=======================================================================
276 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
278 if (object == myListBox && event->type() == QEvent::KeyPress) {
279 QKeyEvent* ke = (QKeyEvent*)event;
280 if (ke->key() == Key_Delete)
283 return QDialog::eventFilter(object, event);
286 //=======================================================================
287 // name : SMESHGUI_MultiEditDlg::getNumericalFunctor
289 //=======================================================================
290 SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
292 SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil();
294 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
295 if (aFilterMgr->_is_nil())
298 if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS"))
299 aNF = aFilterMgr->CreateAspectRatio();
300 else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS"))
301 aNF = aFilterMgr->CreateWarping();
302 else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS"))
303 aNF = aFilterMgr->CreateMinimumAngle();
304 else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS"))
305 aNF = aFilterMgr->CreateTaper();
306 else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS"))
307 aNF = aFilterMgr->CreateSkew();
308 else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS"))
309 aNF = aFilterMgr->CreateArea();
310 else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES"))
311 aNF = aFilterMgr->CreateLength2D();
312 else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
313 aNF = aFilterMgr->CreateMultiConnection2D();
319 //=======================================================================
320 // name : SMESHGUI_MultiEditDlg::Init
321 // Purpose : Init dialog fields, connect signals and slots, show dialog
322 //=======================================================================
323 void SMESHGUI_MultiEditDlg::Init()
325 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
330 emit ListContensChanged();
333 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
334 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
335 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
337 // selection and SMESHGUI
338 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
339 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
340 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
343 connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn() ));
344 connect(myAddBtn , SIGNAL(clicked()), SLOT(onAddBtn() ));
345 connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn() ));
346 connect(mySortBtn , SIGNAL(clicked()), SLOT(onSortListBtn()));
348 connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
349 connect(myGroupChk , SIGNAL(stateChanged(int)), SLOT(onGroupChk() ));
350 connect(myToAllChk , SIGNAL(stateChanged(int)), SLOT(onToAllChk() ));
353 connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
355 connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
359 // set selection mode
364 //=======================================================================
365 // name : SMESHGUI_MultiEditDlg::onOk
366 // Purpose : SLOT called when "Ok" button pressed.
367 // Assign filters VTK viewer and close dialog
368 //=======================================================================
369 void SMESHGUI_MultiEditDlg::onOk()
375 //=======================================================================
376 // name : SMESHGUI_MultiEditDlg::getIds
377 // Purpose : Retrive identifiers from list box
378 //=======================================================================
379 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
381 SMESH::long_array_var anIds = new SMESH::long_array;
383 if (myToAllChk->isChecked())
386 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
392 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
393 if( myFilterType == SMESHGUI_TriaFilter ||
394 myFilterType == SMESHGUI_QuadFilter ||
395 myFilterType == SMESHGUI_FaceFilter ) {
396 SMDS_FaceIteratorPtr it = aMesh->facesIterator();
398 const SMDS_MeshFace* f = it->next();
399 if(myFilterType == SMESHGUI_FaceFilter) {
400 myIds.Add(f->GetID());
402 else if( myFilterType==SMESHGUI_TriaFilter &&
403 ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
404 myIds.Add(f->GetID());
406 else if( myFilterType==SMESHGUI_QuadFilter &&
407 ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
408 myIds.Add(f->GetID());
412 else if(myFilterType == SMESHGUI_VolumeFilter) {
413 SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
415 const SMDS_MeshVolume* f = it->next();
416 myIds.Add(f->GetID());
419 /* commented by skl 07.02.2006
420 TVisualObjPtr aVisualObj = anActor->GetObject();
421 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
423 for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
424 vtkCell* aCell = aGrid->GetCell(i);
426 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
427 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
428 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
430 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
431 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
433 if (aTri && myFilterType == SMESHGUI_TriaFilter ||
434 aQua && myFilterType == SMESHGUI_QuadFilter ||
435 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
436 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
437 int anObjId = aVisualObj->GetElemObjId(i);
447 anIds->length(myIds.Extent());
448 TColStd_MapIteratorOfMapOfInteger anIter(myIds);
449 for (int i = 0; anIter.More(); anIter.Next() )
451 anIds[ i++ ] = anIter.Key();
453 return anIds._retn();
456 //=======================================================================
457 // name : SMESHGUI_MultiEditDlg::onClose
458 // Purpose : SLOT called when "Close" button pressed. Close dialog
459 //=======================================================================
460 void SMESHGUI_MultiEditDlg::onClose()
462 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
463 aViewWindow->SetSelectionMode(ActorSelection);
464 disconnect(mySelectionMgr, 0, this, 0);
465 disconnect(mySMESHGUI, 0, this, 0);
466 mySMESHGUI->ResetState();
468 SMESH::RemoveFilters();
469 SMESH::SetPickable();
471 //mySelectionMgr->clearSelected();
472 mySelectionMgr->clearFilters();
477 //=======================================================================
478 // name : SMESHGUI_MultiEditDlg::onSelectionDone
479 // Purpose : SLOT called when selection changed
480 //=======================================================================
481 void SMESHGUI_MultiEditDlg::onSelectionDone()
483 if (myBusy || !isEnabled()) return;
486 const SALOME_ListIO& aList = mySelector->StoredIObjects();
488 int nbSel = aList.Extent();
489 myListBox->clearSelection();
491 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
492 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
494 Handle(SALOME_InteractiveObject) anIO = aList.First();
496 SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
497 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
499 if (mySubmeshChk->isChecked()) {
500 SMESH::SMESH_subMesh_var aSubMesh =
501 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
502 if (!aSubMesh->_is_nil())
503 myMesh = aSubMesh->GetFather();
505 SMESH::SMESH_GroupBase_var aGroup =
506 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
507 if (!aGroup->_is_nil())
508 myMesh = aGroup->GetMesh();
510 } else if (nbSel > 1) {
511 QString aStr = mySubmeshChk->isChecked() ?
512 tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
513 aNameEdit->setText(aStr.arg(nbSel));
517 } else if (nbSel == 1) {
518 QString aListStr = "";
519 Handle(SALOME_InteractiveObject) anIO = aList.First();
520 int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
522 QStringList anElements = QStringList::split(" ", aListStr);
523 QListBoxItem* anItem = 0;
524 for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
525 anItem = myListBox->findItem(*it, Qt::ExactMatch);
526 if (anItem) myListBox->setSelected(anItem, true);
530 myMesh = SMESH::GetMeshByIO(anIO);
534 myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
536 myActor = SMESH::FindActorByObject(myMesh);
537 SVTK_Selector* aSelector = SMESH::GetSelector();
538 Handle(VTKViewer_Filter) aFilter = aSelector->GetFilter(myFilterType);
539 if (!aFilter.IsNull())
540 aFilter->SetActor(myActor);
547 //=======================================================================
548 // name : SMESHGUI_MultiEditDlg::onDeactivate
549 // Purpose : SLOT called when dialog must be deativated
550 //=======================================================================
551 void SMESHGUI_MultiEditDlg::onDeactivate()
556 //=======================================================================
557 // name : SMESHGUI_MultiEditDlg::enterEvent
558 // Purpose : Event filter
559 //=======================================================================
560 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
563 mySMESHGUI->EmitSignalDeactivateDialog();
569 //=======================================================================
570 // name : SMESHGUI_MultiEditDlg::closeEvent
572 //=======================================================================
573 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
577 //=======================================================================
578 // name : SMESHGUI_MultiEditDlg::hideEvent
579 // Purpose : caused by ESC key
580 //=======================================================================
581 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
587 //=======================================================================
588 // name : SMESHGUI_MultiEditDlg::onFilterBtn
589 // Purpose : SLOT. Called when "Filter" button pressed.
590 // Start "Selection filters" dialog
591 //=======================================================================
592 void SMESHGUI_MultiEditDlg::onFilterBtn()
594 if (myFilterDlg == 0) {
595 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
596 connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
598 myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
601 myFilterDlg->SetSelection();
602 myFilterDlg->SetMesh(myMesh);
603 myFilterDlg->SetSourceWg(myListBox);
608 //=======================================================================
609 // name : onFilterAccepted()
610 // Purpose : SLOT. Called when Filter dlg closed with OK button.
611 // Uncheck "Select submesh" and "Select group" checkboxes
612 //=======================================================================
613 void SMESHGUI_MultiEditDlg::onFilterAccepted()
616 for (int i = 0, n = myListBox->count(); i < n; i++)
617 myIds.Add(myListBox->text(i).toInt());
619 emit ListContensChanged();
621 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
622 mySubmeshChk->blockSignals(true);
623 myGroupChk->blockSignals(true);
624 mySubmeshChk->setChecked(false);
625 myGroupChk->setChecked(false);
626 mySubmeshChk->blockSignals(false);
627 myGroupChk->blockSignals(false);
632 //=======================================================================
633 // name : SMESHGUI_MultiEditDlg::isIdValid
634 // Purpose : Verify whether Id of element satisfies to filters from viewer
635 //=======================================================================
636 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
638 SVTK_Selector* aSelector = SMESH::GetSelector();
639 Handle(SMESHGUI_Filter) aFilter =
640 Handle(SMESHGUI_Filter)::DownCast(aSelector->GetFilter(myFilterType));
642 return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
645 //=======================================================================
646 // name : SMESHGUI_MultiEditDlg::onAddBtn
647 // Purpose : SLOT. Called when "Add" button pressed.
648 // Add selected in viewer entities in list box
649 //=======================================================================
650 void SMESHGUI_MultiEditDlg::onAddBtn()
652 const SALOME_ListIO& aList = mySelector->StoredIObjects();
654 int nbSelected = aList.Extent();
658 TColStd_IndexedMapOfInteger toBeAdded;
660 if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
662 mySelector->GetIndex(aList.First(),toBeAdded);
663 } else if (mySubmeshChk->isChecked()) {
664 SALOME_ListIteratorOfListIO anIter(aList);
665 for (; anIter.More(); anIter.Next()) {
666 SMESH::SMESH_subMesh_var aSubMesh =
667 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
668 if (!aSubMesh->_is_nil()) {
669 if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
670 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
671 for (int i = 0, n = anIds->length(); i < n; i++) {
672 if (isIdValid(anIds[ i ]))
673 toBeAdded.Add(anIds[ i ]);
678 } else if (myGroupChk->isChecked()) {
679 SALOME_ListIteratorOfListIO anIter(aList);
680 for (; anIter.More(); anIter.Next()) {
681 SMESH::SMESH_GroupBase_var aGroup =
682 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
683 if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
684 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
685 entityType() == 1)) {
686 if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
687 SMESH::long_array_var anIds = aGroup->GetListOfID();
688 for (int i = 0, n = anIds->length(); i < n; i++) {
689 if (isIdValid(anIds[ i ]))
690 toBeAdded.Add(anIds[ i ]);
699 bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
700 mySubmeshChk->setChecked(false);
701 myGroupChk->setChecked(false);
702 for(int i = 1; i <= toBeAdded.Extent(); i++)
703 if (myIds.Add(toBeAdded(i))) {
704 QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
705 myListBox->insertItem(item);
706 myListBox->setSelected(item, true);
710 emit ListContensChanged();
712 if (isGroupOrSubmesh)
713 onListSelectionChanged();
718 //=======================================================================
719 // name : SMESHGUI_MultiEditDlg::updateButtons
720 // Purpose : Enable/disable buttons of dialog in accordance with current state
721 //=======================================================================
722 void SMESHGUI_MultiEditDlg::updateButtons()
724 bool isOk = isValid(false);
725 myOkBtn->setEnabled(isOk);
726 myApplyBtn->setEnabled(isOk);
728 bool isListBoxNonEmpty = myListBox->count() > 0;
729 bool isToAll = myToAllChk->isChecked();
730 myFilterBtn->setEnabled(!isToAll);
731 myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
732 mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
734 const SALOME_ListIO& aList = mySelector->StoredIObjects();
738 aList.Extent() != 1 ||
739 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
740 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
741 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
742 myAddBtn->setEnabled(false);
744 myAddBtn->setEnabled(true);
746 mySubmeshChk->setEnabled(!isToAll);
747 mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
748 mySubmesh->setEnabled(mySubmeshChk->isChecked());
750 myGroupChk->setEnabled(!isToAll);
751 myGroupBtn->setEnabled(myGroupChk->isChecked());
752 myGroup->setEnabled(myGroupChk->isChecked());
754 if (!mySubmeshChk->isChecked())
756 if (!myGroupChk->isChecked())
761 //=======================================================================
762 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
763 // Purpose : SLOT. Called when "Remove" button pressed.
764 // Remove selected in list box entities
765 //=======================================================================
766 void SMESHGUI_MultiEditDlg::onRemoveBtn()
770 for (int i = 0, n = myListBox->count(); i < n; i++)
772 for (int i = myListBox->count(); i > 0; i--) {
773 if (myListBox->isSelected(i - 1))
775 int anId = myListBox->text(i - 1).toInt();
778 myListBox->removeItem(i-1);
784 emit ListContensChanged();
788 //=======================================================================
789 // name : SMESHGUI_MultiEditDlg::onSortListBtn
790 // Purpose : SLOT. Called when "Sort list" button pressed.
791 // Sort entities of list box
792 //=======================================================================
793 void SMESHGUI_MultiEditDlg::onSortListBtn()
797 int i, k = myListBox->count();
800 QStringList aSelected;
801 std::vector<int> anArray(k);
802 QListBoxItem* anItem;
803 for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
805 anArray[ i ] = anItem->text().toInt();
806 if (anItem->isSelected())
807 aSelected.append(anItem->text());
810 std::sort(anArray.begin(), anArray.end());
812 for (i = 0; i < k; i++)
813 myListBox->insertItem(QString::number(anArray[ i ]));
815 for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
817 anItem = myListBox->findItem(*it, Qt::ExactMatch);
819 myListBox->setSelected(anItem, true);
825 //=======================================================================
826 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
827 // Purpose : SLOT. Called when selection in list box changed.
828 // Highlight in selected entities
829 //=======================================================================
830 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
832 if (myActor == 0 || myBusy)
835 if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
838 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
841 TVisualObjPtr anObj = anActor->GetObject();
843 TColStd_MapOfInteger anIndexes;
844 for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
846 if (anItem->isSelected())
848 int anId = anItem->text().toInt();
849 if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
854 mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
855 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
856 aViewWindow->highlight(anActor->getIO(),true,true);
859 //=======================================================================
860 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
861 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
862 // Activate/deactivate selection of submeshes
863 //=======================================================================
864 void SMESHGUI_MultiEditDlg::onSubmeshChk()
866 bool isChecked = mySubmeshChk->isChecked();
867 mySubmeshBtn->setEnabled(isChecked);
868 mySubmesh->setEnabled(isChecked);
871 if (isChecked && myGroupChk->isChecked())
872 myGroupChk->setChecked(false);
877 //=======================================================================
878 // name : SMESHGUI_MultiEditDlg::onGroupChk
879 // Purpose : SLOT. Called when state of "Group" check box changed.
880 // Activate/deactivate selection of groupes
881 //=======================================================================
882 void SMESHGUI_MultiEditDlg::onGroupChk()
884 bool isChecked = myGroupChk->isChecked();
885 myGroupBtn->setEnabled(isChecked);
886 myGroup->setEnabled(isChecked);
889 if (isChecked && mySubmeshChk->isChecked())
890 mySubmeshChk->setChecked(false);
895 //=======================================================================
896 // name : SMESHGUI_MultiEditDlg::onToAllChk
897 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
898 // Activate/deactivate selection
899 //=======================================================================
900 void SMESHGUI_MultiEditDlg::onToAllChk()
902 bool isChecked = myToAllChk->isChecked();
909 emit ListContensChanged();
915 //=======================================================================
916 // name : SMESHGUI_MultiEditDlg::setSelectionMode
917 // Purpose : Set selection mode
918 //=======================================================================
919 void SMESHGUI_MultiEditDlg::setSelectionMode()
921 SMESH::RemoveFilters();
923 mySelectionMgr->clearSelected();
924 mySelectionMgr->clearFilters();
926 if (mySubmeshChk->isChecked()) {
927 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
928 aViewWindow->SetSelectionMode(ActorSelection);
929 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
931 else if (myGroupChk->isChecked()) {
932 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
933 aViewWindow->SetSelectionMode(ActorSelection);
934 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
938 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
939 aViewWindow->SetSelectionMode(VolumeSelection);
940 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
942 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
943 aViewWindow->SetSelectionMode(FaceSelection);
944 if (myFilterType == SMESHGUI_TriaFilter)
945 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
946 else if (myFilterType == SMESHGUI_QuadFilter)
947 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
949 SMESH::SetFilter(new SMESHGUI_FacesFilter());
953 //=======================================================================
954 // name : SMESHGUI_MultiEditDlg::onApply
955 // Purpose : SLOT. Called when "Apply" button clicked.
956 //=======================================================================
957 bool SMESHGUI_MultiEditDlg::onApply()
959 if (mySMESHGUI->isActiveStudyLocked())
964 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
965 if (aMeshEditor->_is_nil())
970 SMESH::long_array_var anIds = getIds();
972 bool aResult = process(aMeshEditor, anIds.inout());
976 mySelectionMgr->selectedObjects( sel );
977 mySelector->ClearIndex();
978 mySelectionMgr->setSelectedObjects( sel );
984 emit ListContensChanged();
993 //=======================================================================
994 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
996 //=======================================================================
997 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
999 if (myEntityType != type) {
1000 myEntityType = type;
1005 emit ListContensChanged();
1008 myFilterType = SMESHGUI_VolumeFilter;
1010 myFilterType = SMESHGUI_FaceFilter;
1017 //=======================================================================
1018 // name : SMESHGUI_MultiEditDlg::entityType
1020 //=======================================================================
1021 int SMESHGUI_MultiEditDlg::entityType()
1023 return myEntityType;
1027 * Class : SMESHGUI_ChangeOrientationDlg
1028 * Description : Modification of orientation of faces
1031 SMESHGUI_ChangeOrientationDlg
1032 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
1033 const char* theName):
1034 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
1036 setCaption(tr("CAPTION"));
1039 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
1043 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1044 const SMESH::long_array& theIds)
1046 return theEditor->Reorient(theIds);
1050 * Class : SMESHGUI_UnionOfTrianglesDlg
1051 * Description : Construction of quadrangles by automatic association of triangles
1054 SMESHGUI_UnionOfTrianglesDlg
1055 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
1056 const char* theName):
1057 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
1059 setCaption(tr("CAPTION"));
1061 myComboBoxFunctor->setEnabled(true);
1062 myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
1063 myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
1066 QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
1067 aMaxAngleGrp->setInsideMargin(0);
1068 aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
1069 new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
1070 myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
1071 myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
1072 myMaxAngleSpin->SetValue(30.0);
1074 myCriterionGrp->show();
1077 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1081 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1082 const SMESH::long_array& theIds)
1084 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1085 double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
1086 return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
1091 * Class : SMESHGUI_CuttingOfQuadsDlg
1092 * Description : Automatic splitting of quadrangles into triangles
1095 SMESHGUI_CuttingOfQuadsDlg
1096 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
1097 const char* theName):
1098 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
1100 setCaption(tr("CAPTION"));
1103 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
1105 myCriterionGrp->show();
1106 myGroupChoice->show();
1107 myComboBoxFunctor->setEnabled(false);
1109 connect(myPreviewChk , SIGNAL(stateChanged(int)) , this, SLOT(onPreviewChk()));
1110 connect(myGroupChoice , SIGNAL(clicked(int)) , this, SLOT(onCriterionRB()));
1111 connect(myComboBoxFunctor, SIGNAL(activated(int)) , this, SLOT(onPreviewChk()));
1112 connect(this , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1115 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1119 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1122 SMESHGUI_MultiEditDlg::onClose();
1125 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1126 const SMESH::long_array& theIds)
1128 switch (myGroupChoice->id(myGroupChoice->selected())) {
1129 case 0: // use diagonal 1-3
1130 return theEditor->SplitQuad(theIds, true);
1131 case 1: // use diagonal 2-4
1132 return theEditor->SplitQuad(theIds, false);
1133 default: // use numeric functor
1137 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1138 return theEditor->QuadToTri(theIds, aCriterion);
1141 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
1143 if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
1144 myComboBoxFunctor->setEnabled(true);
1146 myComboBoxFunctor->setEnabled(false);
1151 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1153 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1156 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1158 if (myPreviewActor == 0)
1161 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1162 vf->RemoveActor(myPreviewActor);
1165 myPreviewActor->Delete();
1169 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1174 if (myPreviewActor != 0)
1177 // get Ids of elements
1178 SMESH::long_array_var anElemIds = getIds();
1179 if (getIds()->length() == 0)
1182 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1186 // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
1187 int aChoice = myGroupChoice->id(myGroupChoice->selected());
1188 SMESH::NumericalFunctor_var aCriterion = SMESH::NumericalFunctor::_nil();
1189 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
1191 aCriterion = getNumericalFunctor();
1192 aMeshEditor = myMesh->GetMeshEditor();
1193 if (aMeshEditor->_is_nil())
1198 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1200 vtkIdType aNbCells = anElemIds->length() * 2;
1201 vtkIdType aCellsSize = 4 * aNbCells;
1202 vtkCellArray* aConnectivity = vtkCellArray::New();
1203 aConnectivity->Allocate(aCellsSize, 0);
1205 vtkPoints* aPoints = vtkPoints::New();
1206 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1208 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1209 aCellTypesArray->SetNumberOfComponents(1);
1210 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1212 vtkIdList *anIdList = vtkIdList::New();
1213 anIdList->SetNumberOfIds(3);
1215 TColStd_DataMapOfIntegerInteger anIdToVtk;
1219 for (int i = 0, n = anElemIds->length(); i < n; i++)
1221 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1222 if (anElem == 0 || anElem->NbNodes() != 4)
1225 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1227 while (anIter->more()) {
1228 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
1231 if (!anIdToVtk.IsBound(aNode->GetID()))
1233 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1234 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1237 aNodes[ k++ ] = aNode->GetID();
1244 bool isDiag13 = true;
1245 if (aChoice == 0) // use diagonal 1-3
1249 else if (aChoice == 1) // use diagonal 2-4
1253 else // use numerical functor
1255 // compare two sets of possible triangles
1256 int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
1257 if (diag == 1) // 1-3
1259 else if (diag == 2) // 2-4
1267 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1268 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1269 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1270 aConnectivity->InsertNextCell(anIdList);
1271 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1273 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1274 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1275 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1276 aConnectivity->InsertNextCell(anIdList);
1277 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1281 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1282 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1283 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1284 aConnectivity->InsertNextCell(anIdList);
1285 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1287 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1288 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1289 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1290 aConnectivity->InsertNextCell(anIdList);
1291 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1295 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1296 aCellLocationsArray->SetNumberOfComponents(1);
1297 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1299 aConnectivity->InitTraversal();
1300 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1301 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1303 aGrid->SetPoints(aPoints);
1304 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1306 // Create and display actor
1307 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1308 aMapper->SetInput(aGrid);
1310 myPreviewActor = SALOME_Actor::New();
1311 myPreviewActor->PickableOff();
1312 myPreviewActor->SetMapper(aMapper);
1314 vtkProperty* aProp = vtkProperty::New();
1315 aProp->SetRepresentationToWireframe();
1316 aProp->SetColor(250, 0, 250);
1317 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1318 myPreviewActor->SetProperty(aProp);
1320 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1321 SMESH::GetCurrentVtkView()->Repaint();
1325 aConnectivity->Delete();
1329 aCellTypesArray->Delete();
1330 aCellLocationsArray->Delete();