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"
54 #include "SVTK_InteractorStyle.h"
57 #include <Precision.hxx>
58 #include <TColStd_IndexedMapOfInteger.hxx>
59 #include <TColStd_DataMapOfIntegerInteger.hxx>
60 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
63 #include <vtkCell3D.h>
65 #include <vtkTriangle.h>
66 #include <vtkPolygon.h>
67 #include <vtkConvexPointSet.h>
68 #include <vtkIdList.h>
69 #include <vtkIntArray.h>
70 #include <vtkCellArray.h>
71 #include <vtkUnsignedCharArray.h>
72 #include <vtkUnstructuredGrid.h>
73 #include <vtkDataSetMapper.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);
391 TVisualObjPtr aVisualObj = anActor->GetObject();
392 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
394 for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
395 vtkCell* aCell = aGrid->GetCell(i);
397 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
398 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
399 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
401 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
402 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
404 if (aTri && myFilterType == SMESHGUI_TriaFilter ||
405 aQua && myFilterType == SMESHGUI_QuadFilter ||
406 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
407 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
408 int anObjId = aVisualObj->GetElemObjId(i);
417 anIds->length(myIds.Extent());
418 TColStd_MapIteratorOfMapOfInteger anIter(myIds);
419 for (int i = 0; anIter.More(); anIter.Next() )
421 anIds[ i++ ] = anIter.Key();
423 return anIds._retn();
426 //=======================================================================
427 // name : SMESHGUI_MultiEditDlg::onClose
428 // Purpose : SLOT called when "Close" button pressed. Close dialog
429 //=======================================================================
430 void SMESHGUI_MultiEditDlg::onClose()
432 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
433 aViewWindow->SetSelectionMode(ActorSelection);
434 disconnect(mySelectionMgr, 0, this, 0);
435 disconnect(mySMESHGUI, 0, this, 0);
436 mySMESHGUI->ResetState();
438 SMESH::RemoveFilters();
439 SMESH::SetPickable();
441 //mySelectionMgr->clearSelected();
442 mySelectionMgr->clearFilters();
447 //=======================================================================
448 // name : SMESHGUI_MultiEditDlg::onSelectionDone
449 // Purpose : SLOT called when selection changed
450 //=======================================================================
451 void SMESHGUI_MultiEditDlg::onSelectionDone()
453 if (myBusy || !isEnabled()) return;
456 const SALOME_ListIO& aList = mySelector->StoredIObjects();
458 int nbSel = aList.Extent();
459 myListBox->clearSelection();
461 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
462 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
464 Handle(SALOME_InteractiveObject) anIO = aList.First();
466 SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
467 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
469 if (mySubmeshChk->isChecked()) {
470 SMESH::SMESH_subMesh_var aSubMesh =
471 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
472 if (!aSubMesh->_is_nil())
473 myMesh = aSubMesh->GetFather();
475 SMESH::SMESH_GroupBase_var aGroup =
476 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
477 if (!aGroup->_is_nil())
478 myMesh = aGroup->GetMesh();
480 } else if (nbSel > 1) {
481 QString aStr = mySubmeshChk->isChecked() ?
482 tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
483 aNameEdit->setText(aStr.arg(nbSel));
487 } else if (nbSel == 1) {
488 QString aListStr = "";
489 Handle(SALOME_InteractiveObject) anIO = aList.First();
490 int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
492 QStringList anElements = QStringList::split(" ", aListStr);
493 QListBoxItem* anItem = 0;
494 for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
495 anItem = myListBox->findItem(*it, Qt::ExactMatch);
496 if (anItem) myListBox->setSelected(anItem, true);
500 myMesh = SMESH::GetMeshByIO(anIO);
504 myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
506 myActor = SMESH::FindActorByObject(myMesh);
507 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
508 Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter(myFilterType);
509 if (!aFilter.IsNull())
510 aFilter->SetActor(myActor);
517 //=======================================================================
518 // name : SMESHGUI_MultiEditDlg::onDeactivate
519 // Purpose : SLOT called when dialog must be deativated
520 //=======================================================================
521 void SMESHGUI_MultiEditDlg::onDeactivate()
526 //=======================================================================
527 // name : SMESHGUI_MultiEditDlg::enterEvent
528 // Purpose : Event filter
529 //=======================================================================
530 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
533 mySMESHGUI->EmitSignalDeactivateDialog();
539 //=======================================================================
540 // name : SMESHGUI_MultiEditDlg::closeEvent
542 //=======================================================================
543 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
547 //=======================================================================
548 // name : SMESHGUI_MultiEditDlg::hideEvent
549 // Purpose : caused by ESC key
550 //=======================================================================
551 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
557 //=======================================================================
558 // name : SMESHGUI_MultiEditDlg::onFilterBtn
559 // Purpose : SLOT. Called when "Filter" button pressed.
560 // Start "Selection filters" dialog
561 //=======================================================================
562 void SMESHGUI_MultiEditDlg::onFilterBtn()
564 if (myFilterDlg == 0) {
565 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
566 connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
568 myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
571 myFilterDlg->SetSelection();
572 myFilterDlg->SetMesh(myMesh);
573 myFilterDlg->SetSourceWg(myListBox);
578 //=======================================================================
579 // name : onFilterAccepted()
580 // Purpose : SLOT. Called when Filter dlg closed with OK button.
581 // Uncheck "Select submesh" and "Select group" checkboxes
582 //=======================================================================
583 void SMESHGUI_MultiEditDlg::onFilterAccepted()
586 for (int i = 0, n = myListBox->count(); i < n; i++)
587 myIds.Add(myListBox->text(i).toInt());
589 emit ListContensChanged();
591 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
592 mySubmeshChk->blockSignals(true);
593 myGroupChk->blockSignals(true);
594 mySubmeshChk->setChecked(false);
595 myGroupChk->setChecked(false);
596 mySubmeshChk->blockSignals(false);
597 myGroupChk->blockSignals(false);
602 //=======================================================================
603 // name : SMESHGUI_MultiEditDlg::isIdValid
604 // Purpose : Verify whether Id of element satisfies to filters from viewer
605 //=======================================================================
606 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
608 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
609 Handle(SMESHGUI_Filter) aFilter =
610 Handle(SMESHGUI_Filter)::DownCast(aStyle->GetFilter(myFilterType));
612 return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
615 //=======================================================================
616 // name : SMESHGUI_MultiEditDlg::onAddBtn
617 // Purpose : SLOT. Called when "Add" button pressed.
618 // Add selected in viewer entities in list box
619 //=======================================================================
620 void SMESHGUI_MultiEditDlg::onAddBtn()
622 const SALOME_ListIO& aList = mySelector->StoredIObjects();
624 int nbSelected = aList.Extent();
628 TColStd_IndexedMapOfInteger toBeAdded;
630 if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
632 mySelector->GetIndex(aList.First(),toBeAdded);
633 } else if (mySubmeshChk->isChecked()) {
634 SALOME_ListIteratorOfListIO anIter(aList);
635 for (; anIter.More(); anIter.Next()) {
636 SMESH::SMESH_subMesh_var aSubMesh =
637 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
638 if (!aSubMesh->_is_nil()) {
639 if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
640 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
641 for (int i = 0, n = anIds->length(); i < n; i++) {
642 if (isIdValid(anIds[ i ]))
643 toBeAdded.Add(anIds[ i ]);
648 } else if (myGroupChk->isChecked()) {
649 SALOME_ListIteratorOfListIO anIter(aList);
650 for (; anIter.More(); anIter.Next()) {
651 SMESH::SMESH_GroupBase_var aGroup =
652 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
653 if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
654 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
655 entityType() == 1)) {
656 if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
657 SMESH::long_array_var anIds = aGroup->GetListOfID();
658 for (int i = 0, n = anIds->length(); i < n; i++) {
659 if (isIdValid(anIds[ i ]))
660 toBeAdded.Add(anIds[ i ]);
669 bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
670 mySubmeshChk->setChecked(false);
671 myGroupChk->setChecked(false);
672 for(int i = 1; i <= toBeAdded.Extent(); i++)
673 if (myIds.Add(toBeAdded(i))) {
674 QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
675 myListBox->insertItem(item);
676 myListBox->setSelected(item, true);
680 emit ListContensChanged();
682 if (isGroupOrSubmesh)
683 onListSelectionChanged();
688 //=======================================================================
689 // name : SMESHGUI_MultiEditDlg::updateButtons
690 // Purpose : Enable/disable buttons of dialog in accordance with current state
691 //=======================================================================
692 void SMESHGUI_MultiEditDlg::updateButtons()
694 bool isOk = isValid(false);
695 myOkBtn->setEnabled(isOk);
696 myApplyBtn->setEnabled(isOk);
698 bool isListBoxNonEmpty = myListBox->count() > 0;
699 bool isToAll = myToAllChk->isChecked();
700 myFilterBtn->setEnabled(!isToAll);
701 myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
702 mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
704 const SALOME_ListIO& aList = mySelector->StoredIObjects();
708 aList.Extent() != 1 ||
709 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
710 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
711 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
712 myAddBtn->setEnabled(false);
714 myAddBtn->setEnabled(true);
716 mySubmeshChk->setEnabled(!isToAll);
717 mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
718 mySubmesh->setEnabled(mySubmeshChk->isChecked());
720 myGroupChk->setEnabled(!isToAll);
721 myGroupBtn->setEnabled(myGroupChk->isChecked());
722 myGroup->setEnabled(myGroupChk->isChecked());
724 if (!mySubmeshChk->isChecked())
726 if (!myGroupChk->isChecked())
731 //=======================================================================
732 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
733 // Purpose : SLOT. Called when "Remove" button pressed.
734 // Remove selected in list box entities
735 //=======================================================================
736 void SMESHGUI_MultiEditDlg::onRemoveBtn()
740 for (int i = 0, n = myListBox->count(); i < n; i++)
742 for (int i = myListBox->count(); i > 0; i--) {
743 if (myListBox->isSelected(i - 1))
745 int anId = myListBox->text(i - 1).toInt();
748 myListBox->removeItem(i-1);
754 emit ListContensChanged();
758 //=======================================================================
759 // name : SMESHGUI_MultiEditDlg::onSortListBtn
760 // Purpose : SLOT. Called when "Sort list" button pressed.
761 // Sort entities of list box
762 //=======================================================================
763 void SMESHGUI_MultiEditDlg::onSortListBtn()
767 int i, k = myListBox->count();
770 QStringList aSelected;
771 std::vector<int> anArray(k);
772 QListBoxItem* anItem;
773 for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
775 anArray[ i ] = anItem->text().toInt();
776 if (anItem->isSelected())
777 aSelected.append(anItem->text());
780 std::sort(anArray.begin(), anArray.end());
782 for (i = 0; i < k; i++)
783 myListBox->insertItem(QString::number(anArray[ i ]));
785 for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
787 anItem = myListBox->findItem(*it, Qt::ExactMatch);
789 myListBox->setSelected(anItem, true);
795 //=======================================================================
796 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
797 // Purpose : SLOT. Called when selection in list box changed.
798 // Highlight in selected entities
799 //=======================================================================
800 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
802 if (myActor == 0 || myBusy)
805 if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
808 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
811 TVisualObjPtr anObj = anActor->GetObject();
813 TColStd_MapOfInteger anIndexes;
814 for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
816 if (anItem->isSelected())
818 int anId = anItem->text().toInt();
819 if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
824 mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
825 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
826 aViewWindow->highlight(anActor->getIO(),true,true);
829 //=======================================================================
830 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
831 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
832 // Activate/deactivate selection of submeshes
833 //=======================================================================
834 void SMESHGUI_MultiEditDlg::onSubmeshChk()
836 bool isChecked = mySubmeshChk->isChecked();
837 mySubmeshBtn->setEnabled(isChecked);
838 mySubmesh->setEnabled(isChecked);
841 if (isChecked && myGroupChk->isChecked())
842 myGroupChk->setChecked(false);
847 //=======================================================================
848 // name : SMESHGUI_MultiEditDlg::onGroupChk
849 // Purpose : SLOT. Called when state of "Group" check box changed.
850 // Activate/deactivate selection of groupes
851 //=======================================================================
852 void SMESHGUI_MultiEditDlg::onGroupChk()
854 bool isChecked = myGroupChk->isChecked();
855 myGroupBtn->setEnabled(isChecked);
856 myGroup->setEnabled(isChecked);
859 if (isChecked && mySubmeshChk->isChecked())
860 mySubmeshChk->setChecked(false);
865 //=======================================================================
866 // name : SMESHGUI_MultiEditDlg::onToAllChk
867 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
868 // Activate/deactivate selection
869 //=======================================================================
870 void SMESHGUI_MultiEditDlg::onToAllChk()
872 bool isChecked = myToAllChk->isChecked();
879 emit ListContensChanged();
885 //=======================================================================
886 // name : SMESHGUI_MultiEditDlg::setSelectionMode
887 // Purpose : Set selection mode
888 //=======================================================================
889 void SMESHGUI_MultiEditDlg::setSelectionMode()
891 SMESH::RemoveFilters();
893 mySelectionMgr->clearSelected();
894 mySelectionMgr->clearFilters();
896 if (mySubmeshChk->isChecked()) {
897 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
898 aViewWindow->SetSelectionMode(ActorSelection);
899 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
901 else if (myGroupChk->isChecked()) {
902 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
903 aViewWindow->SetSelectionMode(ActorSelection);
904 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
908 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
909 aViewWindow->SetSelectionMode(VolumeSelection);
910 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
912 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
913 aViewWindow->SetSelectionMode(FaceSelection);
914 if (myFilterType == SMESHGUI_TriaFilter)
915 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
916 else if (myFilterType == SMESHGUI_QuadFilter)
917 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
919 SMESH::SetFilter(new SMESHGUI_FacesFilter());
923 //=======================================================================
924 // name : SMESHGUI_MultiEditDlg::onApply
925 // Purpose : SLOT. Called when "Apply" button clicked.
926 //=======================================================================
927 bool SMESHGUI_MultiEditDlg::onApply()
929 if (mySMESHGUI->isActiveStudyLocked())
934 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
935 if (aMeshEditor->_is_nil())
940 SMESH::long_array_var anIds = getIds();
942 bool aResult = process(aMeshEditor, anIds.inout());
946 mySelectionMgr->selectedObjects( sel );
947 mySelector->ClearIndex();
948 mySelectionMgr->setSelectedObjects( sel );
954 emit ListContensChanged();
963 //=======================================================================
964 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
966 //=======================================================================
967 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
969 if (myEntityType != type) {
975 emit ListContensChanged();
978 myFilterType = SMESHGUI_VolumeFilter;
980 myFilterType = SMESHGUI_FaceFilter;
987 //=======================================================================
988 // name : SMESHGUI_MultiEditDlg::entityType
990 //=======================================================================
991 int SMESHGUI_MultiEditDlg::entityType()
997 * Class : SMESHGUI_ChangeOrientationDlg
998 * Description : Modification of orientation of faces
1001 SMESHGUI_ChangeOrientationDlg
1002 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
1003 const char* theName):
1004 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
1006 setCaption(tr("CAPTION"));
1009 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
1013 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1014 const SMESH::long_array& theIds)
1016 return theEditor->Reorient(theIds);
1020 * Class : SMESHGUI_UnionOfTrianglesDlg
1021 * Description : Construction of quadrangles by automatic association of triangles
1024 SMESHGUI_UnionOfTrianglesDlg
1025 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
1026 const char* theName):
1027 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
1029 setCaption(tr("CAPTION"));
1031 myComboBoxFunctor->setEnabled(true);
1032 myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
1033 myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
1036 QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
1037 aMaxAngleGrp->setInsideMargin(0);
1038 aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
1039 new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
1040 myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
1041 myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
1042 myMaxAngleSpin->SetValue(30.0);
1044 myCriterionGrp->show();
1047 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1051 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1052 const SMESH::long_array& theIds)
1054 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1055 double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
1056 return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
1061 * Class : SMESHGUI_CuttingOfQuadsDlg
1062 * Description : Automatic splitting of quadrangles into triangles
1065 SMESHGUI_CuttingOfQuadsDlg
1066 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
1067 const char* theName):
1068 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
1070 setCaption(tr("CAPTION"));
1073 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
1075 myCriterionGrp->show();
1076 myGroupChoice->show();
1077 myComboBoxFunctor->setEnabled(false);
1079 connect(myPreviewChk , SIGNAL(stateChanged(int)) , this, SLOT(onPreviewChk()));
1080 connect(myGroupChoice , SIGNAL(clicked(int)) , this, SLOT(onCriterionRB()));
1081 connect(myComboBoxFunctor, SIGNAL(activated(int)) , this, SLOT(onPreviewChk()));
1082 connect(this , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1085 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1089 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1092 SMESHGUI_MultiEditDlg::onClose();
1095 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1096 const SMESH::long_array& theIds)
1098 switch (myGroupChoice->id(myGroupChoice->selected())) {
1099 case 0: // use diagonal 1-3
1100 return theEditor->SplitQuad(theIds, true);
1101 case 1: // use diagonal 2-4
1102 return theEditor->SplitQuad(theIds, false);
1103 default: // use numeric functor
1107 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1108 return theEditor->QuadToTri(theIds, aCriterion);
1111 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
1113 if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
1114 myComboBoxFunctor->setEnabled(true);
1116 myComboBoxFunctor->setEnabled(false);
1121 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1123 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1126 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1128 if (myPreviewActor == 0)
1131 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1132 vf->RemoveActor(myPreviewActor);
1135 myPreviewActor->Delete();
1139 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1144 if (myPreviewActor != 0)
1147 // get Ids of elements
1148 SMESH::long_array_var anElemIds = getIds();
1149 if (getIds()->length() == 0)
1152 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1156 // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
1157 int aChoice = myGroupChoice->id(myGroupChoice->selected());
1158 SMESH::NumericalFunctor_var aCriterion = SMESH::NumericalFunctor::_nil();
1159 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
1161 aCriterion = getNumericalFunctor();
1162 aMeshEditor = myMesh->GetMeshEditor();
1163 if (aMeshEditor->_is_nil())
1168 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1170 vtkIdType aNbCells = anElemIds->length() * 2;
1171 vtkIdType aCellsSize = 4 * aNbCells;
1172 vtkCellArray* aConnectivity = vtkCellArray::New();
1173 aConnectivity->Allocate(aCellsSize, 0);
1175 vtkPoints* aPoints = vtkPoints::New();
1176 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1178 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1179 aCellTypesArray->SetNumberOfComponents(1);
1180 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1182 vtkIdList *anIdList = vtkIdList::New();
1183 anIdList->SetNumberOfIds(3);
1185 TColStd_DataMapOfIntegerInteger anIdToVtk;
1189 for (int i = 0, n = anElemIds->length(); i < n; i++)
1191 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1192 if (anElem == 0 || anElem->NbNodes() != 4)
1195 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1197 while (anIter->more()) {
1198 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
1201 if (!anIdToVtk.IsBound(aNode->GetID()))
1203 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1204 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1207 aNodes[ k++ ] = aNode->GetID();
1214 bool isDiag13 = true;
1215 if (aChoice == 0) // use diagonal 1-3
1219 else if (aChoice == 1) // use diagonal 2-4
1223 else // use numerical functor
1225 // compare two sets of possible triangles
1226 int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
1227 if (diag == 1) // 1-3
1229 else if (diag == 2) // 2-4
1237 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1238 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1239 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1240 aConnectivity->InsertNextCell(anIdList);
1241 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1243 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1244 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1245 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1246 aConnectivity->InsertNextCell(anIdList);
1247 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1251 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1252 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1253 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1254 aConnectivity->InsertNextCell(anIdList);
1255 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1257 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1258 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1259 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1260 aConnectivity->InsertNextCell(anIdList);
1261 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1265 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1266 aCellLocationsArray->SetNumberOfComponents(1);
1267 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1269 aConnectivity->InitTraversal();
1270 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1271 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1273 aGrid->SetPoints(aPoints);
1274 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1276 // Create and display actor
1277 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1278 aMapper->SetInput(aGrid);
1280 myPreviewActor = SALOME_Actor::New();
1281 myPreviewActor->PickableOff();
1282 myPreviewActor->SetMapper(aMapper);
1284 vtkProperty* aProp = vtkProperty::New();
1285 aProp->SetRepresentationToWireframe();
1286 aProp->SetColor(250, 0, 250);
1287 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1288 myPreviewActor->SetProperty(aProp);
1290 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1291 SMESH::GetCurrentVtkView()->Repaint();
1295 aConnectivity->Delete();
1299 aCellTypesArray->Delete();
1300 aCellLocationsArray->Delete();