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>
79 #include <qcheckbox.h>
80 #include <qcombobox.h>
81 #include <qgroupbox.h>
82 #include <qlineedit.h>
83 #include <qpushbutton.h>
84 #include <qapplication.h>
85 #include <qradiobutton.h>
86 #include <qhbuttongroup.h>
89 #include "SALOMEconfig.h"
90 #include CORBA_SERVER_HEADER(SMESH_Group)
96 * Class : SMESHGUI_MultiEditDlg
97 * Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
98 * 2 neighboring triangles with 1 common edge
101 //=======================================================================
102 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
103 // Purpose : Constructor
104 //=======================================================================
105 SMESHGUI_MultiEditDlg
106 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
109 const char* theName):
110 QDialog(SMESH::GetDesktop(theModule),
113 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
114 mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
115 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
116 mySMESHGUI(theModule)
121 myFilterType = theMode;
122 QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
124 QFrame* aMainFrame = createMainFrame (this, the3d2d);
125 QFrame* aBtnFrame = createButtonFrame(this);
127 aDlgLay->addWidget(aMainFrame);
128 aDlgLay->addWidget(aBtnFrame);
130 aDlgLay->setStretchFactor(aMainFrame, 1);
131 aDlgLay->setStretchFactor(aBtnFrame, 0);
135 //=======================================================================
136 // name : SMESHGUI_MultiEditDlg::createMainFrame
137 // Purpose : Create frame containing dialog's input fields
138 //=======================================================================
139 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
141 QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
142 aMainGrp->setFrameStyle(QFrame::NoFrame);
143 aMainGrp->setInsideMargin(0);
145 QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
147 // "Selected cells" group
148 mySelGrp = new QGroupBox(1, Qt::Horizontal, aMainGrp);
152 myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
153 (new QRadioButton(tr("SMESH_FACE"), myEntityTypeGrp))->setChecked(true);
154 (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
155 myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
158 QFrame* aFrame = new QFrame(mySelGrp);
160 myListBox = new QListBox(aFrame);
161 myListBox->setSelectionMode(QListBox::Extended);
162 myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
163 myListBox->installEventFilter(this);
165 myFilterBtn = new QPushButton(tr("FILTER") , aFrame);
166 myAddBtn = new QPushButton(tr("ADD") , aFrame);
167 myRemoveBtn = new QPushButton(tr("REMOVE") , aFrame);
168 mySortBtn = new QPushButton(tr("SORT_LIST"), aFrame);
170 QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
171 aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
172 aLay->addWidget(myFilterBtn, 0, 1);
173 aLay->addWidget(myAddBtn, 1, 1);
174 aLay->addWidget(myRemoveBtn, 2, 1);
175 aLay->addWidget(mySortBtn, 3, 1);
177 QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
178 aLay->addItem(aSpacer, 4, 1);
180 myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
182 // Split/Join criterion group
183 myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp);
185 myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp);
186 myGroupChoice->setInsideMargin(0);
187 myGroupChoice->setFrameStyle(QFrame::NoFrame);
188 (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true);
189 (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice));
190 (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice));
192 myComboBoxFunctor = new QComboBox(myCriterionGrp);
193 myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS"));
194 myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS"));
195 myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS"));
196 myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS"));
197 //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only
198 //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only
199 myComboBoxFunctor->setCurrentItem(0);
201 myCriterionGrp->hide();
202 myGroupChoice->hide();
203 myComboBoxFunctor->setEnabled(false);
205 // "Select from" group
206 QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
208 mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
209 mySubmeshBtn = new QPushButton(aGrp);
210 mySubmesh = new QLineEdit(aGrp);
211 mySubmesh->setReadOnly(true);
212 mySubmeshBtn->setPixmap(aPix);
214 myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp);
215 myGroupBtn = new QPushButton(aGrp);
216 myGroup = new QLineEdit(aGrp);
217 myGroup->setReadOnly(true);
218 myGroupBtn->setPixmap(aPix);
223 //=======================================================================
224 // name : SMESHGUI_MultiEditDlg::createButtonFrame
225 // Purpose : Create frame containing buttons
226 //=======================================================================
227 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
229 QFrame* aFrame = new QFrame (theParent);
230 aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
232 myOkBtn = new QPushButton (tr("SMESH_BUT_OK" ), aFrame);
233 myApplyBtn = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
234 myCloseBtn = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
236 QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
238 QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
240 aLay->addWidget(myOkBtn);
241 aLay->addWidget(myApplyBtn);
242 aLay->addItem(aSpacer);
243 aLay->addWidget(myCloseBtn);
248 //=======================================================================
249 // name : SMESHGUI_MultiEditDlg::isValid
250 // Purpose : Verify validity of input data
251 //=======================================================================
252 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
254 return (!myMesh->_is_nil() &&
255 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
258 //=======================================================================
259 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
260 // Purpose : Destructor
261 //=======================================================================
262 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
264 if (myFilterDlg != 0)
266 myFilterDlg->reparent(0, QPoint());
271 //=======================================================================
272 // name : SMESHGUI_MultiEditDlg::eventFilter
273 // Purpose : event filter
274 //=======================================================================
275 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
277 if (object == myListBox && event->type() == QEvent::KeyPress) {
278 QKeyEvent* ke = (QKeyEvent*)event;
279 if (ke->key() == Key_Delete)
282 return QDialog::eventFilter(object, event);
285 //=======================================================================
286 // name : SMESHGUI_MultiEditDlg::getNumericalFunctor
288 //=======================================================================
289 SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
291 SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil();
293 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
294 if (aFilterMgr->_is_nil())
297 if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS"))
298 aNF = aFilterMgr->CreateAspectRatio();
299 else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS"))
300 aNF = aFilterMgr->CreateWarping();
301 else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS"))
302 aNF = aFilterMgr->CreateMinimumAngle();
303 else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS"))
304 aNF = aFilterMgr->CreateTaper();
305 else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS"))
306 aNF = aFilterMgr->CreateSkew();
307 else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS"))
308 aNF = aFilterMgr->CreateArea();
309 else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES"))
310 aNF = aFilterMgr->CreateLength2D();
311 else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
312 aNF = aFilterMgr->CreateMultiConnection2D();
318 //=======================================================================
319 // name : SMESHGUI_MultiEditDlg::Init
320 // Purpose : Init dialog fields, connect signals and slots, show dialog
321 //=======================================================================
322 void SMESHGUI_MultiEditDlg::Init()
324 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
329 emit ListContensChanged();
332 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
333 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
334 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
336 // selection and SMESHGUI
337 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
338 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
339 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
342 connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn() ));
343 connect(myAddBtn , SIGNAL(clicked()), SLOT(onAddBtn() ));
344 connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn() ));
345 connect(mySortBtn , SIGNAL(clicked()), SLOT(onSortListBtn()));
347 connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
348 connect(myGroupChk , SIGNAL(stateChanged(int)), SLOT(onGroupChk() ));
349 connect(myToAllChk , SIGNAL(stateChanged(int)), SLOT(onToAllChk() ));
352 connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
354 connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
358 // set selection mode
363 //=======================================================================
364 // name : SMESHGUI_MultiEditDlg::onOk
365 // Purpose : SLOT called when "Ok" button pressed.
366 // Assign filters VTK viewer and close dialog
367 //=======================================================================
368 void SMESHGUI_MultiEditDlg::onOk()
374 //=======================================================================
375 // name : SMESHGUI_MultiEditDlg::getIds
376 // Purpose : Retrive identifiers from list box
377 //=======================================================================
378 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
380 SMESH::long_array_var anIds = new SMESH::long_array;
382 if (myToAllChk->isChecked())
385 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
390 TVisualObjPtr aVisualObj = anActor->GetObject();
391 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
393 for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
394 vtkCell* aCell = aGrid->GetCell(i);
396 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
397 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
398 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
400 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
401 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
403 if (aTri && myFilterType == SMESHGUI_TriaFilter ||
404 aQua && myFilterType == SMESHGUI_QuadFilter ||
405 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
406 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
407 int anObjId = aVisualObj->GetElemObjId(i);
416 anIds->length(myIds.Extent());
417 TColStd_MapIteratorOfMapOfInteger anIter(myIds);
418 for (int i = 0; anIter.More(); anIter.Next() )
420 anIds[ i++ ] = anIter.Key();
422 return anIds._retn();
425 //=======================================================================
426 // name : SMESHGUI_MultiEditDlg::onClose
427 // Purpose : SLOT called when "Close" button pressed. Close dialog
428 //=======================================================================
429 void SMESHGUI_MultiEditDlg::onClose()
431 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
432 aViewWindow->SetSelectionMode(ActorSelection);
433 disconnect(mySelectionMgr, 0, this, 0);
434 disconnect(mySMESHGUI, 0, this, 0);
435 mySMESHGUI->ResetState();
437 SMESH::RemoveFilters();
438 SMESH::SetPickable();
440 //mySelectionMgr->clearSelected();
441 mySelectionMgr->clearFilters();
446 //=======================================================================
447 // name : SMESHGUI_MultiEditDlg::onSelectionDone
448 // Purpose : SLOT called when selection changed
449 //=======================================================================
450 void SMESHGUI_MultiEditDlg::onSelectionDone()
452 if (myBusy || !isEnabled()) return;
455 const SALOME_ListIO& aList = mySelector->StoredIObjects();
457 int nbSel = aList.Extent();
458 myListBox->clearSelection();
460 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
461 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
463 Handle(SALOME_InteractiveObject) anIO = aList.First();
465 SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
466 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
468 if (mySubmeshChk->isChecked()) {
469 SMESH::SMESH_subMesh_var aSubMesh =
470 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
471 if (!aSubMesh->_is_nil())
472 myMesh = aSubMesh->GetFather();
474 SMESH::SMESH_GroupBase_var aGroup =
475 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
476 if (!aGroup->_is_nil())
477 myMesh = aGroup->GetMesh();
479 } else if (nbSel > 1) {
480 QString aStr = mySubmeshChk->isChecked() ?
481 tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
482 aNameEdit->setText(aStr.arg(nbSel));
486 } else if (nbSel == 1) {
487 QString aListStr = "";
488 Handle(SALOME_InteractiveObject) anIO = aList.First();
489 int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
491 QStringList anElements = QStringList::split(" ", aListStr);
492 QListBoxItem* anItem = 0;
493 for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
494 anItem = myListBox->findItem(*it, Qt::ExactMatch);
495 if (anItem) myListBox->setSelected(anItem, true);
499 myMesh = SMESH::GetMeshByIO(anIO);
503 myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
505 myActor = SMESH::FindActorByObject(myMesh);
506 SVTK_Selector* aSelector = SMESH::GetSelector();
507 Handle(VTKViewer_Filter) aFilter = aSelector->GetFilter(myFilterType);
508 if (!aFilter.IsNull())
509 aFilter->SetActor(myActor);
516 //=======================================================================
517 // name : SMESHGUI_MultiEditDlg::onDeactivate
518 // Purpose : SLOT called when dialog must be deativated
519 //=======================================================================
520 void SMESHGUI_MultiEditDlg::onDeactivate()
525 //=======================================================================
526 // name : SMESHGUI_MultiEditDlg::enterEvent
527 // Purpose : Event filter
528 //=======================================================================
529 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
532 mySMESHGUI->EmitSignalDeactivateDialog();
538 //=======================================================================
539 // name : SMESHGUI_MultiEditDlg::closeEvent
541 //=======================================================================
542 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
546 //=======================================================================
547 // name : SMESHGUI_MultiEditDlg::hideEvent
548 // Purpose : caused by ESC key
549 //=======================================================================
550 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
556 //=======================================================================
557 // name : SMESHGUI_MultiEditDlg::onFilterBtn
558 // Purpose : SLOT. Called when "Filter" button pressed.
559 // Start "Selection filters" dialog
560 //=======================================================================
561 void SMESHGUI_MultiEditDlg::onFilterBtn()
563 if (myFilterDlg == 0) {
564 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
565 connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
567 myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
570 myFilterDlg->SetSelection();
571 myFilterDlg->SetMesh(myMesh);
572 myFilterDlg->SetSourceWg(myListBox);
577 //=======================================================================
578 // name : onFilterAccepted()
579 // Purpose : SLOT. Called when Filter dlg closed with OK button.
580 // Uncheck "Select submesh" and "Select group" checkboxes
581 //=======================================================================
582 void SMESHGUI_MultiEditDlg::onFilterAccepted()
585 for (int i = 0, n = myListBox->count(); i < n; i++)
586 myIds.Add(myListBox->text(i).toInt());
588 emit ListContensChanged();
590 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
591 mySubmeshChk->blockSignals(true);
592 myGroupChk->blockSignals(true);
593 mySubmeshChk->setChecked(false);
594 myGroupChk->setChecked(false);
595 mySubmeshChk->blockSignals(false);
596 myGroupChk->blockSignals(false);
601 //=======================================================================
602 // name : SMESHGUI_MultiEditDlg::isIdValid
603 // Purpose : Verify whether Id of element satisfies to filters from viewer
604 //=======================================================================
605 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
607 SVTK_Selector* aSelector = SMESH::GetSelector();
608 Handle(SMESHGUI_Filter) aFilter =
609 Handle(SMESHGUI_Filter)::DownCast(aSelector->GetFilter(myFilterType));
611 return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
614 //=======================================================================
615 // name : SMESHGUI_MultiEditDlg::onAddBtn
616 // Purpose : SLOT. Called when "Add" button pressed.
617 // Add selected in viewer entities in list box
618 //=======================================================================
619 void SMESHGUI_MultiEditDlg::onAddBtn()
621 const SALOME_ListIO& aList = mySelector->StoredIObjects();
623 int nbSelected = aList.Extent();
627 TColStd_IndexedMapOfInteger toBeAdded;
629 if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
631 mySelector->GetIndex(aList.First(),toBeAdded);
632 } else if (mySubmeshChk->isChecked()) {
633 SALOME_ListIteratorOfListIO anIter(aList);
634 for (; anIter.More(); anIter.Next()) {
635 SMESH::SMESH_subMesh_var aSubMesh =
636 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
637 if (!aSubMesh->_is_nil()) {
638 if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
639 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
640 for (int i = 0, n = anIds->length(); i < n; i++) {
641 if (isIdValid(anIds[ i ]))
642 toBeAdded.Add(anIds[ i ]);
647 } else if (myGroupChk->isChecked()) {
648 SALOME_ListIteratorOfListIO anIter(aList);
649 for (; anIter.More(); anIter.Next()) {
650 SMESH::SMESH_GroupBase_var aGroup =
651 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
652 if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
653 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
654 entityType() == 1)) {
655 if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
656 SMESH::long_array_var anIds = aGroup->GetListOfID();
657 for (int i = 0, n = anIds->length(); i < n; i++) {
658 if (isIdValid(anIds[ i ]))
659 toBeAdded.Add(anIds[ i ]);
668 bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
669 mySubmeshChk->setChecked(false);
670 myGroupChk->setChecked(false);
671 for(int i = 1; i <= toBeAdded.Extent(); i++)
672 if (myIds.Add(toBeAdded(i))) {
673 QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
674 myListBox->insertItem(item);
675 myListBox->setSelected(item, true);
679 emit ListContensChanged();
681 if (isGroupOrSubmesh)
682 onListSelectionChanged();
687 //=======================================================================
688 // name : SMESHGUI_MultiEditDlg::updateButtons
689 // Purpose : Enable/disable buttons of dialog in accordance with current state
690 //=======================================================================
691 void SMESHGUI_MultiEditDlg::updateButtons()
693 bool isOk = isValid(false);
694 myOkBtn->setEnabled(isOk);
695 myApplyBtn->setEnabled(isOk);
697 bool isListBoxNonEmpty = myListBox->count() > 0;
698 bool isToAll = myToAllChk->isChecked();
699 myFilterBtn->setEnabled(!isToAll);
700 myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
701 mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
703 const SALOME_ListIO& aList = mySelector->StoredIObjects();
707 aList.Extent() != 1 ||
708 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
709 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
710 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
711 myAddBtn->setEnabled(false);
713 myAddBtn->setEnabled(true);
715 mySubmeshChk->setEnabled(!isToAll);
716 mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
717 mySubmesh->setEnabled(mySubmeshChk->isChecked());
719 myGroupChk->setEnabled(!isToAll);
720 myGroupBtn->setEnabled(myGroupChk->isChecked());
721 myGroup->setEnabled(myGroupChk->isChecked());
723 if (!mySubmeshChk->isChecked())
725 if (!myGroupChk->isChecked())
730 //=======================================================================
731 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
732 // Purpose : SLOT. Called when "Remove" button pressed.
733 // Remove selected in list box entities
734 //=======================================================================
735 void SMESHGUI_MultiEditDlg::onRemoveBtn()
739 for (int i = 0, n = myListBox->count(); i < n; i++)
741 for (int i = myListBox->count(); i > 0; i--) {
742 if (myListBox->isSelected(i - 1))
744 int anId = myListBox->text(i - 1).toInt();
747 myListBox->removeItem(i-1);
753 emit ListContensChanged();
757 //=======================================================================
758 // name : SMESHGUI_MultiEditDlg::onSortListBtn
759 // Purpose : SLOT. Called when "Sort list" button pressed.
760 // Sort entities of list box
761 //=======================================================================
762 void SMESHGUI_MultiEditDlg::onSortListBtn()
766 int i, k = myListBox->count();
769 QStringList aSelected;
770 std::vector<int> anArray(k);
771 QListBoxItem* anItem;
772 for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
774 anArray[ i ] = anItem->text().toInt();
775 if (anItem->isSelected())
776 aSelected.append(anItem->text());
779 std::sort(anArray.begin(), anArray.end());
781 for (i = 0; i < k; i++)
782 myListBox->insertItem(QString::number(anArray[ i ]));
784 for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
786 anItem = myListBox->findItem(*it, Qt::ExactMatch);
788 myListBox->setSelected(anItem, true);
794 //=======================================================================
795 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
796 // Purpose : SLOT. Called when selection in list box changed.
797 // Highlight in selected entities
798 //=======================================================================
799 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
801 if (myActor == 0 || myBusy)
804 if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
807 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
810 TVisualObjPtr anObj = anActor->GetObject();
812 TColStd_MapOfInteger anIndexes;
813 for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
815 if (anItem->isSelected())
817 int anId = anItem->text().toInt();
818 if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
823 mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
824 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
825 aViewWindow->highlight(anActor->getIO(),true,true);
828 //=======================================================================
829 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
830 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
831 // Activate/deactivate selection of submeshes
832 //=======================================================================
833 void SMESHGUI_MultiEditDlg::onSubmeshChk()
835 bool isChecked = mySubmeshChk->isChecked();
836 mySubmeshBtn->setEnabled(isChecked);
837 mySubmesh->setEnabled(isChecked);
840 if (isChecked && myGroupChk->isChecked())
841 myGroupChk->setChecked(false);
846 //=======================================================================
847 // name : SMESHGUI_MultiEditDlg::onGroupChk
848 // Purpose : SLOT. Called when state of "Group" check box changed.
849 // Activate/deactivate selection of groupes
850 //=======================================================================
851 void SMESHGUI_MultiEditDlg::onGroupChk()
853 bool isChecked = myGroupChk->isChecked();
854 myGroupBtn->setEnabled(isChecked);
855 myGroup->setEnabled(isChecked);
858 if (isChecked && mySubmeshChk->isChecked())
859 mySubmeshChk->setChecked(false);
864 //=======================================================================
865 // name : SMESHGUI_MultiEditDlg::onToAllChk
866 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
867 // Activate/deactivate selection
868 //=======================================================================
869 void SMESHGUI_MultiEditDlg::onToAllChk()
871 bool isChecked = myToAllChk->isChecked();
878 emit ListContensChanged();
884 //=======================================================================
885 // name : SMESHGUI_MultiEditDlg::setSelectionMode
886 // Purpose : Set selection mode
887 //=======================================================================
888 void SMESHGUI_MultiEditDlg::setSelectionMode()
890 SMESH::RemoveFilters();
892 mySelectionMgr->clearSelected();
893 mySelectionMgr->clearFilters();
895 if (mySubmeshChk->isChecked()) {
896 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
897 aViewWindow->SetSelectionMode(ActorSelection);
898 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
900 else if (myGroupChk->isChecked()) {
901 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
902 aViewWindow->SetSelectionMode(ActorSelection);
903 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
907 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
908 aViewWindow->SetSelectionMode(VolumeSelection);
909 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
911 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
912 aViewWindow->SetSelectionMode(FaceSelection);
913 if (myFilterType == SMESHGUI_TriaFilter)
914 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
915 else if (myFilterType == SMESHGUI_QuadFilter)
916 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
918 SMESH::SetFilter(new SMESHGUI_FacesFilter());
922 //=======================================================================
923 // name : SMESHGUI_MultiEditDlg::onApply
924 // Purpose : SLOT. Called when "Apply" button clicked.
925 //=======================================================================
926 bool SMESHGUI_MultiEditDlg::onApply()
928 if (mySMESHGUI->isActiveStudyLocked())
933 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
934 if (aMeshEditor->_is_nil())
939 SMESH::long_array_var anIds = getIds();
941 bool aResult = process(aMeshEditor, anIds.inout());
945 mySelectionMgr->selectedObjects( sel );
946 mySelector->ClearIndex();
947 mySelectionMgr->setSelectedObjects( sel );
953 emit ListContensChanged();
962 //=======================================================================
963 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
965 //=======================================================================
966 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
968 if (myEntityType != type) {
974 emit ListContensChanged();
977 myFilterType = SMESHGUI_VolumeFilter;
979 myFilterType = SMESHGUI_FaceFilter;
986 //=======================================================================
987 // name : SMESHGUI_MultiEditDlg::entityType
989 //=======================================================================
990 int SMESHGUI_MultiEditDlg::entityType()
996 * Class : SMESHGUI_ChangeOrientationDlg
997 * Description : Modification of orientation of faces
1000 SMESHGUI_ChangeOrientationDlg
1001 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
1002 const char* theName):
1003 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
1005 setCaption(tr("CAPTION"));
1008 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
1012 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1013 const SMESH::long_array& theIds)
1015 return theEditor->Reorient(theIds);
1019 * Class : SMESHGUI_UnionOfTrianglesDlg
1020 * Description : Construction of quadrangles by automatic association of triangles
1023 SMESHGUI_UnionOfTrianglesDlg
1024 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
1025 const char* theName):
1026 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
1028 setCaption(tr("CAPTION"));
1030 myComboBoxFunctor->setEnabled(true);
1031 myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
1032 myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
1035 QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
1036 aMaxAngleGrp->setInsideMargin(0);
1037 aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
1038 new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
1039 myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
1040 myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
1041 myMaxAngleSpin->SetValue(30.0);
1043 myCriterionGrp->show();
1046 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1050 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1051 const SMESH::long_array& theIds)
1053 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1054 double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
1055 return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
1060 * Class : SMESHGUI_CuttingOfQuadsDlg
1061 * Description : Automatic splitting of quadrangles into triangles
1064 SMESHGUI_CuttingOfQuadsDlg
1065 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
1066 const char* theName):
1067 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
1069 setCaption(tr("CAPTION"));
1072 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
1074 myCriterionGrp->show();
1075 myGroupChoice->show();
1076 myComboBoxFunctor->setEnabled(false);
1078 connect(myPreviewChk , SIGNAL(stateChanged(int)) , this, SLOT(onPreviewChk()));
1079 connect(myGroupChoice , SIGNAL(clicked(int)) , this, SLOT(onCriterionRB()));
1080 connect(myComboBoxFunctor, SIGNAL(activated(int)) , this, SLOT(onPreviewChk()));
1081 connect(this , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1084 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1088 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1091 SMESHGUI_MultiEditDlg::onClose();
1094 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1095 const SMESH::long_array& theIds)
1097 switch (myGroupChoice->id(myGroupChoice->selected())) {
1098 case 0: // use diagonal 1-3
1099 return theEditor->SplitQuad(theIds, true);
1100 case 1: // use diagonal 2-4
1101 return theEditor->SplitQuad(theIds, false);
1102 default: // use numeric functor
1106 SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1107 return theEditor->QuadToTri(theIds, aCriterion);
1110 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
1112 if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
1113 myComboBoxFunctor->setEnabled(true);
1115 myComboBoxFunctor->setEnabled(false);
1120 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1122 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1125 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1127 if (myPreviewActor == 0)
1130 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1131 vf->RemoveActor(myPreviewActor);
1134 myPreviewActor->Delete();
1138 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1143 if (myPreviewActor != 0)
1146 // get Ids of elements
1147 SMESH::long_array_var anElemIds = getIds();
1148 if (getIds()->length() == 0)
1151 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1155 // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
1156 int aChoice = myGroupChoice->id(myGroupChoice->selected());
1157 SMESH::NumericalFunctor_var aCriterion = SMESH::NumericalFunctor::_nil();
1158 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
1160 aCriterion = getNumericalFunctor();
1161 aMeshEditor = myMesh->GetMeshEditor();
1162 if (aMeshEditor->_is_nil())
1167 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1169 vtkIdType aNbCells = anElemIds->length() * 2;
1170 vtkIdType aCellsSize = 4 * aNbCells;
1171 vtkCellArray* aConnectivity = vtkCellArray::New();
1172 aConnectivity->Allocate(aCellsSize, 0);
1174 vtkPoints* aPoints = vtkPoints::New();
1175 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1177 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1178 aCellTypesArray->SetNumberOfComponents(1);
1179 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1181 vtkIdList *anIdList = vtkIdList::New();
1182 anIdList->SetNumberOfIds(3);
1184 TColStd_DataMapOfIntegerInteger anIdToVtk;
1188 for (int i = 0, n = anElemIds->length(); i < n; i++)
1190 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1191 if (anElem == 0 || anElem->NbNodes() != 4)
1194 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1196 while (anIter->more()) {
1197 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
1200 if (!anIdToVtk.IsBound(aNode->GetID()))
1202 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1203 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1206 aNodes[ k++ ] = aNode->GetID();
1213 bool isDiag13 = true;
1214 if (aChoice == 0) // use diagonal 1-3
1218 else if (aChoice == 1) // use diagonal 2-4
1222 else // use numerical functor
1224 // compare two sets of possible triangles
1225 int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
1226 if (diag == 1) // 1-3
1228 else if (diag == 2) // 2-4
1236 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1237 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1238 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1239 aConnectivity->InsertNextCell(anIdList);
1240 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1242 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1243 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1244 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1245 aConnectivity->InsertNextCell(anIdList);
1246 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1250 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1251 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1252 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1253 aConnectivity->InsertNextCell(anIdList);
1254 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1256 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1257 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1258 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1259 aConnectivity->InsertNextCell(anIdList);
1260 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1264 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1265 aCellLocationsArray->SetNumberOfComponents(1);
1266 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1268 aConnectivity->InitTraversal();
1269 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1270 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1272 aGrid->SetPoints(aPoints);
1273 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1275 // Create and display actor
1276 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1277 aMapper->SetInput(aGrid);
1279 myPreviewActor = SALOME_Actor::New();
1280 myPreviewActor->PickableOff();
1281 myPreviewActor->SetMapper(aMapper);
1283 vtkProperty* aProp = vtkProperty::New();
1284 aProp->SetRepresentationToWireframe();
1285 aProp->SetColor(250, 0, 250);
1286 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1287 myPreviewActor->SetProperty(aProp);
1289 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1290 SMESH::GetCurrentVtkView()->Repaint();
1294 aConnectivity->Delete();
1298 aCellTypesArray->Delete();
1299 aCellLocationsArray->Delete();