1 // SMESH SMESHGUI : GUI for SMESH component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESHGUI_MultiEditDlg.cxx
25 // Author : Sergey LITONIN
28 #include "SMESHGUI_MultiEditDlg.h"
29 #include "SMESHGUI_FilterDlg.h"
30 #include "SMESHGUI_Filter.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
37 #include "SMESH_Actor.h"
38 #include "SMESH_TypeFilter.hxx"
39 #include "SMDS_Mesh.hxx"
40 #include "SMDS_MeshElement.hxx"
42 #include "SUIT_ResourceMgr.h"
43 #include "SUIT_Desktop.h"
45 #include "SalomeApp_SelectionMgr.h"
46 #include "SALOME_ListIO.hxx"
47 #include "SALOME_ListIteratorOfListIO.hxx"
49 #include "SVTK_Selector.h"
50 #include "SVTK_ViewModel.h"
51 #include "SVTK_ViewWindow.h"
52 #include "SVTK_InteractorStyle.h"
55 #include <Precision.hxx>
56 #include <TColStd_IndexedMapOfInteger.hxx>
57 #include <TColStd_DataMapOfIntegerInteger.hxx>
58 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
61 #include <vtkCell3D.h>
63 #include <vtkTriangle.h>
64 #include <vtkPolygon.h>
65 #include <vtkConvexPointSet.h>
66 #include <vtkIdList.h>
67 #include <vtkIntArray.h>
68 #include <vtkCellArray.h>
69 #include <vtkUnsignedCharArray.h>
70 #include <vtkUnstructuredGrid.h>
71 #include <vtkDataSetMapper.h>
74 #include <qcheckbox.h>
76 #include <qgroupbox.h>
79 #include <qlineedit.h>
81 #include <qpushbutton.h>
82 #include <qapplication.h>
83 #include <qhbuttongroup.h>
84 #include <qradiobutton.h>
87 #include "SALOMEconfig.h"
88 #include CORBA_SERVER_HEADER(SMESH_Group)
94 * Class : SMESHGUI_MultiEditDlg
95 * Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
96 * 2 neighboring triangles with 1 common edge
99 //=======================================================================
100 // name : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
101 // Purpose : Constructor
102 //=======================================================================
103 SMESHGUI_MultiEditDlg
104 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
107 const char* theName):
108 QDialog(SMESH::GetDesktop(theModule),
111 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
112 mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
113 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
114 mySMESHGUI(theModule)
119 myFilterType = theMode;
120 QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
122 QFrame* aMainFrame = createMainFrame (this, the3d2d);
123 QFrame* aBtnFrame = createButtonFrame(this);
125 aDlgLay->addWidget(aMainFrame);
126 aDlgLay->addWidget(aBtnFrame);
128 aDlgLay->setStretchFactor(aMainFrame, 1);
129 aDlgLay->setStretchFactor(aBtnFrame, 0);
133 //=======================================================================
134 // name : SMESHGUI_MultiEditDlg::createMainFrame
135 // Purpose : Create frame containing dialog's input fields
136 //=======================================================================
137 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
139 QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
140 aMainGrp->setFrameStyle(QFrame::NoFrame);
141 aMainGrp->setInsideMargin(0);
143 QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
145 // "Selected cells" group
146 mySelGrp = new QGroupBox(1, Qt::Horizontal, aMainGrp);
150 myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
151 (new QRadioButton(tr("SMESH_FACE"), myEntityTypeGrp))->setChecked(true);
152 (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
153 myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
156 QFrame* aFrame = new QFrame(mySelGrp);
158 myListBox = new QListBox(aFrame);
159 myListBox->setSelectionMode(QListBox::Extended);
160 myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
161 // myListBox->setColumnMode(QListBox::FitToHeight);
162 myListBox->installEventFilter(this);
164 myFilterBtn = new QPushButton(tr("FILTER") , aFrame);
165 myAddBtn = new QPushButton(tr("ADD") , aFrame);
166 myRemoveBtn = new QPushButton(tr("REMOVE") , aFrame);
167 mySortBtn = new QPushButton(tr("SORT_LIST"), aFrame);
169 QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
170 aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
171 aLay->addWidget(myFilterBtn, 0, 1);
172 aLay->addWidget(myAddBtn, 1, 1);
173 aLay->addWidget(myRemoveBtn, 2, 1);
174 aLay->addWidget(mySortBtn, 3, 1);
176 QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
177 aLay->addItem(aSpacer, 4, 1);
179 myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
181 // "Select from" group
182 QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
184 mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
185 mySubmeshBtn = new QPushButton(aGrp);
186 mySubmesh = new QLineEdit(aGrp);
187 mySubmesh->setReadOnly(true);
188 mySubmeshBtn->setPixmap(aPix);
190 myGroupChk = new QCheckBox(tr("GROUP"), aGrp);
191 myGroupBtn = new QPushButton(aGrp);
192 myGroup = new QLineEdit(aGrp);
193 myGroup->setReadOnly(true);
194 myGroupBtn->setPixmap(aPix);
199 //=======================================================================
200 // name : SMESHGUI_MultiEditDlg::createButtonFrame
201 // Purpose : Create frame containing buttons
202 //=======================================================================
203 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
205 QFrame* aFrame = new QFrame (theParent);
206 aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
208 myOkBtn = new QPushButton (tr("SMESH_BUT_OK" ), aFrame);
209 myApplyBtn = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
210 myCloseBtn = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
212 QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
214 QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
216 aLay->addWidget(myOkBtn);
217 aLay->addWidget(myApplyBtn);
218 aLay->addItem(aSpacer);
219 aLay->addWidget(myCloseBtn);
224 //=======================================================================
225 // name : SMESHGUI_MultiEditDlg::isValid
226 // Purpose : Verify validity of input data
227 //=======================================================================
228 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
230 return (!myMesh->_is_nil() &&
231 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
234 //=======================================================================
235 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
236 // Purpose : Destructor
237 //=======================================================================
238 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
240 if (myFilterDlg != 0)
242 myFilterDlg->reparent(0, QPoint());
247 //=======================================================================
248 // name : SMESHGUI_MultiEditDlg::eventFilter
249 // Purpose : event filter
250 //=======================================================================
251 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
253 if (object == myListBox && event->type() == QEvent::KeyPress) {
254 QKeyEvent* ke = (QKeyEvent*)event;
255 if (ke->key() == Key_Delete)
258 return QDialog::eventFilter(object, event);
261 //=======================================================================
262 // name : SMESHGUI_MultiEditDlg::Init
263 // Purpose : Init dialog fields, connect signals and slots, show dialog
264 //=======================================================================
265 void SMESHGUI_MultiEditDlg::Init()
267 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
272 emit ListContensChanged();
275 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
276 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
277 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
279 // selection and SMESHGUI
280 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
281 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
282 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
285 connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn() ));
286 connect(myAddBtn , SIGNAL(clicked()), SLOT(onAddBtn() ));
287 connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn() ));
288 connect(mySortBtn , SIGNAL(clicked()), SLOT(onSortListBtn()));
290 connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
291 connect(myGroupChk , SIGNAL(stateChanged(int)), SLOT(onGroupChk() ));
292 connect(myToAllChk , SIGNAL(stateChanged(int)), SLOT(onToAllChk() ));
295 connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
297 connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
301 // set selection mode
306 //=======================================================================
307 // name : SMESHGUI_MultiEditDlg::onOk
308 // Purpose : SLOT called when "Ok" button pressed.
309 // Assign filters VTK viewer and close dialog
310 //=======================================================================
311 void SMESHGUI_MultiEditDlg::onOk()
317 //=======================================================================
318 // name : SMESHGUI_MultiEditDlg::getIds
319 // Purpose : Retrive identifiers from list box
320 //=======================================================================
321 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
323 SMESH::long_array_var anIds = new SMESH::long_array;
325 if (myToAllChk->isChecked())
328 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
333 TVisualObjPtr aVisualObj = anActor->GetObject();
334 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
336 for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
337 vtkCell* aCell = aGrid->GetCell(i);
339 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
340 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
341 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
343 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
344 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
346 if (aTri && myFilterType == SMESHGUI_TriaFilter ||
347 aQua && myFilterType == SMESHGUI_QuadFilter ||
348 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
349 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
350 int anObjId = aVisualObj->GetElemObjId(i);
359 anIds->length(myIds.Extent());
360 TColStd_MapIteratorOfMapOfInteger anIter(myIds);
361 for (int i = 0; anIter.More(); anIter.Next() )
363 anIds[ i++ ] = anIter.Key();
365 return anIds._retn();
368 //=======================================================================
369 // name : SMESHGUI_MultiEditDlg::onClose
370 // Purpose : SLOT called when "Close" button pressed. Close dialog
371 //=======================================================================
372 void SMESHGUI_MultiEditDlg::onClose()
374 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
375 aViewWindow->SetSelectionMode(ActorSelection);
376 disconnect(mySelectionMgr, 0, this, 0);
377 disconnect(mySMESHGUI, 0, this, 0);
378 mySMESHGUI->ResetState();
380 SMESH::RemoveFilters();
381 SMESH::SetPickable();
383 mySelectionMgr->clearSelected();
384 mySelectionMgr->clearFilters();
389 //=======================================================================
390 // name : SMESHGUI_MultiEditDlg::onSelectionDone
391 // Purpose : SLOT called when selection changed
392 //=======================================================================
393 void SMESHGUI_MultiEditDlg::onSelectionDone()
395 if (myBusy || !isEnabled()) return;
398 const SALOME_ListIO& aList = mySelector->StoredIObjects();
400 int nbSel = aList.Extent();
401 myListBox->clearSelection();
403 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
404 QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
406 Handle(SALOME_InteractiveObject) anIO = aList.First();
407 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(anIO->getName());
409 if (mySubmeshChk->isChecked()) {
410 SMESH::SMESH_subMesh_var aSubMesh =
411 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
412 if (!aSubMesh->_is_nil())
413 myMesh = aSubMesh->GetFather();
415 SMESH::SMESH_GroupBase_var aGroup =
416 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
417 if (!aGroup->_is_nil())
418 myMesh = aGroup->GetMesh();
420 } else if (nbSel > 1) {
421 QString aStr = mySubmeshChk->isChecked() ?
422 tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
423 aNameEdit->setText(aStr.arg(nbSel));
427 } else if (nbSel == 1) {
428 QString aListStr = "";
429 Handle(SALOME_InteractiveObject) anIO = aList.First();
430 int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
432 QStringList anElements = QStringList::split(" ", aListStr);
433 QListBoxItem* anItem = 0;
434 for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
435 anItem = myListBox->findItem(*it, Qt::ExactMatch);
436 if (anItem) myListBox->setSelected(anItem, true);
440 myMesh = SMESH::GetMeshByIO(anIO);
444 myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
446 myActor = SMESH::FindActorByObject(myMesh);
447 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
448 Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter(myFilterType);
449 if (!aFilter.IsNull())
450 aFilter->SetActor(myActor);
457 //=======================================================================
458 // name : SMESHGUI_MultiEditDlg::onDeactivate
459 // Purpose : SLOT called when dialog must be deativated
460 //=======================================================================
461 void SMESHGUI_MultiEditDlg::onDeactivate()
466 //=======================================================================
467 // name : SMESHGUI_MultiEditDlg::enterEvent
468 // Purpose : Event filter
469 //=======================================================================
470 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
473 mySMESHGUI->EmitSignalDeactivateDialog();
479 //=======================================================================
480 // name : SMESHGUI_MultiEditDlg::closeEvent
482 //=======================================================================
483 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
487 //=======================================================================
488 // name : SMESHGUI_MultiEditDlg::hideEvent
489 // Purpose : caused by ESC key
490 //=======================================================================
491 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
497 //=======================================================================
498 // name : SMESHGUI_MultiEditDlg::onFilterBtn
499 // Purpose : SLOT. Called when "Filter" button pressed.
500 // Start "Selection filters" dialog
501 //=======================================================================
502 void SMESHGUI_MultiEditDlg::onFilterBtn()
504 if (myFilterDlg == 0) {
505 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
506 connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
508 myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
511 myFilterDlg->SetSelection();
512 myFilterDlg->SetMesh(myMesh);
513 myFilterDlg->SetSourceWg(myListBox);
518 //=======================================================================
519 // name : onFilterAccepted()
520 // Purpose : SLOT. Called when Filter dlg closed with OK button.
521 // Uncheck "Select submesh" and "Select group" checkboxes
522 //=======================================================================
523 void SMESHGUI_MultiEditDlg::onFilterAccepted()
526 for (int i = 0, n = myListBox->count(); i < n; i++)
527 myIds.Add(myListBox->text(i).toInt());
529 emit ListContensChanged();
531 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
532 mySubmeshChk->blockSignals(true);
533 myGroupChk->blockSignals(true);
534 mySubmeshChk->setChecked(false);
535 myGroupChk->setChecked(false);
536 mySubmeshChk->blockSignals(false);
537 myGroupChk->blockSignals(false);
542 //=======================================================================
543 // name : SMESHGUI_MultiEditDlg::isIdValid
544 // Purpose : Verify whether Id of element satisfies to filters from viewer
545 //=======================================================================
546 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
548 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
549 Handle(SMESHGUI_Filter) aFilter =
550 Handle(SMESHGUI_Filter)::DownCast(aStyle->GetFilter(myFilterType));
552 return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
555 //=======================================================================
556 // name : SMESHGUI_MultiEditDlg::onAddBtn
557 // Purpose : SLOT. Called when "Add" button pressed.
558 // Add selected in viewer entities in list box
559 //=======================================================================
560 void SMESHGUI_MultiEditDlg::onAddBtn()
562 const SALOME_ListIO& aList = mySelector->StoredIObjects();
564 int nbSelected = aList.Extent();
568 TColStd_IndexedMapOfInteger toBeAdded;
570 if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
572 mySelector->GetIndex(aList.First(),toBeAdded);
573 } else if (mySubmeshChk->isChecked()) {
574 SALOME_ListIteratorOfListIO anIter(aList);
575 for (; anIter.More(); anIter.Next()) {
576 SMESH::SMESH_subMesh_var aSubMesh =
577 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
578 if (!aSubMesh->_is_nil()) {
579 if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
580 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
581 for (int i = 0, n = anIds->length(); i < n; i++) {
582 if (isIdValid(anIds[ i ]))
583 toBeAdded.Add(anIds[ i ]);
588 } else if (myGroupChk->isChecked()) {
589 SALOME_ListIteratorOfListIO anIter(aList);
590 for (; anIter.More(); anIter.Next()) {
591 SMESH::SMESH_GroupBase_var aGroup =
592 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
593 if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
594 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
595 entityType() == 1)) {
596 if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
597 SMESH::long_array_var anIds = aGroup->GetListOfID();
598 for (int i = 0, n = anIds->length(); i < n; i++) {
599 if (isIdValid(anIds[ i ]))
600 toBeAdded.Add(anIds[ i ]);
609 bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
610 mySubmeshChk->setChecked(false);
611 myGroupChk->setChecked(false);
612 for(int i = 1; i <= toBeAdded.Extent(); i++)
613 if (myIds.Add(toBeAdded(i))) {
614 QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
615 myListBox->insertItem(item);
616 myListBox->setSelected(item, true);
620 emit ListContensChanged();
622 if (isGroupOrSubmesh)
623 onListSelectionChanged();
628 //=======================================================================
629 // name : SMESHGUI_MultiEditDlg::updateButtons
630 // Purpose : Enable/disable buttons of dialog in accordance with current state
631 //=======================================================================
632 void SMESHGUI_MultiEditDlg::updateButtons()
634 bool isOk = isValid(false);
635 myOkBtn->setEnabled(isOk);
636 myApplyBtn->setEnabled(isOk);
638 bool isListBoxNonEmpty = myListBox->count() > 0;
639 bool isToAll = myToAllChk->isChecked();
640 myFilterBtn->setEnabled(!isToAll);
641 myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
642 mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
644 const SALOME_ListIO& aList = mySelector->StoredIObjects();
648 aList.Extent() != 1 ||
649 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
650 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
651 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
652 myAddBtn->setEnabled(false);
654 myAddBtn->setEnabled(true);
656 mySubmeshChk->setEnabled(!isToAll);
657 mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
658 mySubmesh->setEnabled(mySubmeshChk->isChecked());
660 myGroupChk->setEnabled(!isToAll);
661 myGroupBtn->setEnabled(myGroupChk->isChecked());
662 myGroup->setEnabled(myGroupChk->isChecked());
664 if (!mySubmeshChk->isChecked())
666 if (!myGroupChk->isChecked())
671 //=======================================================================
672 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
673 // Purpose : SLOT. Called when "Remove" button pressed.
674 // Remove selected in list box entities
675 //=======================================================================
676 void SMESHGUI_MultiEditDlg::onRemoveBtn()
680 for (int i = 0, n = myListBox->count(); i < n; i++)
682 for (int i = myListBox->count(); i > 0; i--) {
683 if (myListBox->isSelected(i - 1))
685 int anId = myListBox->text(i - 1).toInt();
688 myListBox->removeItem(i-1);
694 emit ListContensChanged();
698 //=======================================================================
699 // name : SMESHGUI_MultiEditDlg::onSortListBtn
700 // Purpose : SLOT. Called when "Sort list" button pressed.
701 // Sort entities of list box
702 //=======================================================================
703 void SMESHGUI_MultiEditDlg::onSortListBtn()
707 int i, k = myListBox->count();
710 QStringList aSelected;
711 std::vector<int> anArray(k);
712 QListBoxItem* anItem;
713 for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
715 anArray[ i ] = anItem->text().toInt();
716 if (anItem->isSelected())
717 aSelected.append(anItem->text());
720 std::sort(anArray.begin(), anArray.end());
722 for (i = 0; i < k; i++)
723 myListBox->insertItem(QString::number(anArray[ i ]));
725 for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
727 anItem = myListBox->findItem(*it, Qt::ExactMatch);
729 myListBox->setSelected(anItem, true);
735 //=======================================================================
736 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
737 // Purpose : SLOT. Called when selection in list box changed.
738 // Highlight in selected entities
739 //=======================================================================
740 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
742 if (myActor == 0 || myBusy)
745 if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
748 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
751 TVisualObjPtr anObj = anActor->GetObject();
753 TColStd_MapOfInteger anIndexes;
754 for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
756 if (anItem->isSelected())
758 int anId = anItem->text().toInt();
759 if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
764 mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
765 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
766 aViewWindow->highlight(anActor->getIO(),true,true);
769 //=======================================================================
770 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
771 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
772 // Activate/deactivate selection of submeshes
773 //=======================================================================
774 void SMESHGUI_MultiEditDlg::onSubmeshChk()
776 bool isChecked = mySubmeshChk->isChecked();
777 mySubmeshBtn->setEnabled(isChecked);
778 mySubmesh->setEnabled(isChecked);
781 if (isChecked && myGroupChk->isChecked())
782 myGroupChk->setChecked(false);
787 //=======================================================================
788 // name : SMESHGUI_MultiEditDlg::onGroupChk
789 // Purpose : SLOT. Called when state of "Group" check box changed.
790 // Activate/deactivate selection of groupes
791 //=======================================================================
792 void SMESHGUI_MultiEditDlg::onGroupChk()
794 bool isChecked = myGroupChk->isChecked();
795 myGroupBtn->setEnabled(isChecked);
796 myGroup->setEnabled(isChecked);
799 if (isChecked && mySubmeshChk->isChecked())
800 mySubmeshChk->setChecked(false);
805 //=======================================================================
806 // name : SMESHGUI_MultiEditDlg::onToAllChk
807 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
808 // Activate/deactivate selection
809 //=======================================================================
810 void SMESHGUI_MultiEditDlg::onToAllChk()
812 bool isChecked = myToAllChk->isChecked();
819 emit ListContensChanged();
825 //=======================================================================
826 // name : SMESHGUI_MultiEditDlg::setSelectionMode
827 // Purpose : Set selection mode
828 //=======================================================================
829 void SMESHGUI_MultiEditDlg::setSelectionMode()
831 SMESH::RemoveFilters();
833 mySelectionMgr->clearSelected();
834 mySelectionMgr->clearFilters();
836 if (mySubmeshChk->isChecked()) {
837 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
838 aViewWindow->SetSelectionMode(ActorSelection);
839 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
841 else if (myGroupChk->isChecked()) {
842 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
843 aViewWindow->SetSelectionMode(ActorSelection);
844 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
848 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
849 aViewWindow->SetSelectionMode(VolumeSelection);
850 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
852 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
853 aViewWindow->SetSelectionMode(FaceSelection);
854 if (myFilterType == SMESHGUI_TriaFilter)
855 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
856 else if (myFilterType == SMESHGUI_QuadFilter)
857 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
859 SMESH::SetFilter(new SMESHGUI_FacesFilter());
863 //=======================================================================
864 // name : SMESHGUI_MultiEditDlg::onApply
865 // Purpose : SLOT. Called when "Apply" button clicked.
866 //=======================================================================
867 bool SMESHGUI_MultiEditDlg::onApply()
869 if (mySMESHGUI->isActiveStudyLocked())
874 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
875 if (aMeshEditor->_is_nil())
880 SMESH::long_array_var anIds = getIds();
882 bool aResult = process(aMeshEditor, anIds.inout());
890 emit ListContensChanged();
899 //=======================================================================
900 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
902 //=======================================================================
903 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
905 if (myEntityType != type) {
911 emit ListContensChanged();
914 myFilterType = SMESHGUI_VolumeFilter;
916 myFilterType = SMESHGUI_FaceFilter;
923 //=======================================================================
924 // name : SMESHGUI_MultiEditDlg::entityType
926 //=======================================================================
927 int SMESHGUI_MultiEditDlg::entityType()
933 * Class : SMESHGUI_ChangeOrientationDlg
934 * Description : Modification of orientation of faces
937 SMESHGUI_ChangeOrientationDlg
938 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
939 const char* theName):
940 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
942 setCaption(tr("CAPTION"));
945 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
949 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
950 const SMESH::long_array& theIds)
952 return theEditor->Reorient(theIds);
956 * Class : SMESHGUI_UnionOfTrianglesDlg
957 * Description : Construction of quadrangles by automatic association of triangles
960 SMESHGUI_UnionOfTrianglesDlg
961 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
962 const char* theName):
963 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
965 setCaption(tr("CAPTION"));
968 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
972 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
973 const SMESH::long_array& theIds)
975 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1.);
979 * Class : SMESHGUI_CuttingOfQuadsDlg
980 * Description : Construction of quadrangles by automatic association of triangles
983 SMESHGUI_CuttingOfQuadsDlg
984 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
985 const char* theName):
986 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
988 setCaption(tr("CAPTION"));
991 myUseDiagChk = new QCheckBox (tr("USE_DIAGONAL_2_4"), mySelGrp);
992 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
994 connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
995 connect(myUseDiagChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
996 connect(this, SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
999 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1003 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1006 SMESHGUI_MultiEditDlg::onClose();
1009 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1010 const SMESH::long_array& theIds)
1012 return theEditor->SplitQuad(theIds, !myUseDiagChk->isChecked());
1015 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1017 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1020 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1022 if (myPreviewActor == 0)
1025 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1026 vf->RemoveActor(myPreviewActor);
1029 myPreviewActor->Delete();
1033 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1038 if (myPreviewActor != 0)
1041 // get Ids of elements
1042 SMESH::long_array_var anElemIds = getIds();
1043 if (getIds()->length() == 0)
1046 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1050 bool isDiag24 = myUseDiagChk->isChecked();
1053 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1055 vtkIdType aNbCells = anElemIds->length() * 2;
1056 vtkIdType aCellsSize = 4 * aNbCells;
1057 vtkCellArray* aConnectivity = vtkCellArray::New();
1058 aConnectivity->Allocate(aCellsSize, 0);
1060 vtkPoints* aPoints = vtkPoints::New();
1061 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1063 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1064 aCellTypesArray->SetNumberOfComponents(1);
1065 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1067 vtkIdList *anIdList = vtkIdList::New();
1068 anIdList->SetNumberOfIds(3);
1070 TColStd_DataMapOfIntegerInteger anIdToVtk;
1074 for (int i = 0, n = anElemIds->length(); i < n; i++)
1076 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1077 if (anElem == 0 || anElem->NbNodes() != 4)
1080 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1082 while(anIter->more())
1083 if (const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next())
1085 if (!anIdToVtk.IsBound(aNode->GetID()))
1087 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1088 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1091 aNodes[ k++ ] = aNode->GetID();
1099 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1100 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1101 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1102 aConnectivity->InsertNextCell(anIdList);
1103 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1105 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1106 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1107 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1108 aConnectivity->InsertNextCell(anIdList);
1109 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1113 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1114 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1115 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1116 aConnectivity->InsertNextCell(anIdList);
1117 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1119 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1120 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1121 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1122 aConnectivity->InsertNextCell(anIdList);
1123 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1127 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1128 aCellLocationsArray->SetNumberOfComponents(1);
1129 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1131 aConnectivity->InitTraversal();
1132 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1133 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1135 aGrid->SetPoints(aPoints);
1136 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1138 // Create and display actor
1139 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1140 aMapper->SetInput(aGrid);
1142 myPreviewActor = SALOME_Actor::New();
1143 myPreviewActor->PickableOff();
1144 myPreviewActor->SetMapper(aMapper);
1146 vtkProperty* aProp = vtkProperty::New();
1147 aProp->SetRepresentationToWireframe();
1148 aProp->SetColor(250, 0, 250);
1149 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1150 myPreviewActor->SetProperty(aProp);
1152 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1153 SMESH::GetCurrentVtkView()->Repaint();
1157 aConnectivity->Delete();
1161 aCellTypesArray->Delete();
1162 aCellLocationsArray->Delete();