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();
408 SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
409 anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
411 if (mySubmeshChk->isChecked()) {
412 SMESH::SMESH_subMesh_var aSubMesh =
413 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
414 if (!aSubMesh->_is_nil())
415 myMesh = aSubMesh->GetFather();
417 SMESH::SMESH_GroupBase_var aGroup =
418 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
419 if (!aGroup->_is_nil())
420 myMesh = aGroup->GetMesh();
422 } else if (nbSel > 1) {
423 QString aStr = mySubmeshChk->isChecked() ?
424 tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
425 aNameEdit->setText(aStr.arg(nbSel));
429 } else if (nbSel == 1) {
430 QString aListStr = "";
431 Handle(SALOME_InteractiveObject) anIO = aList.First();
432 int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
434 QStringList anElements = QStringList::split(" ", aListStr);
435 QListBoxItem* anItem = 0;
436 for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
437 anItem = myListBox->findItem(*it, Qt::ExactMatch);
438 if (anItem) myListBox->setSelected(anItem, true);
442 myMesh = SMESH::GetMeshByIO(anIO);
446 myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
448 myActor = SMESH::FindActorByObject(myMesh);
449 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
450 Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter(myFilterType);
451 if (!aFilter.IsNull())
452 aFilter->SetActor(myActor);
459 //=======================================================================
460 // name : SMESHGUI_MultiEditDlg::onDeactivate
461 // Purpose : SLOT called when dialog must be deativated
462 //=======================================================================
463 void SMESHGUI_MultiEditDlg::onDeactivate()
468 //=======================================================================
469 // name : SMESHGUI_MultiEditDlg::enterEvent
470 // Purpose : Event filter
471 //=======================================================================
472 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
475 mySMESHGUI->EmitSignalDeactivateDialog();
481 //=======================================================================
482 // name : SMESHGUI_MultiEditDlg::closeEvent
484 //=======================================================================
485 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
489 //=======================================================================
490 // name : SMESHGUI_MultiEditDlg::hideEvent
491 // Purpose : caused by ESC key
492 //=======================================================================
493 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
499 //=======================================================================
500 // name : SMESHGUI_MultiEditDlg::onFilterBtn
501 // Purpose : SLOT. Called when "Filter" button pressed.
502 // Start "Selection filters" dialog
503 //=======================================================================
504 void SMESHGUI_MultiEditDlg::onFilterBtn()
506 if (myFilterDlg == 0) {
507 myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
508 connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
510 myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
513 myFilterDlg->SetSelection();
514 myFilterDlg->SetMesh(myMesh);
515 myFilterDlg->SetSourceWg(myListBox);
520 //=======================================================================
521 // name : onFilterAccepted()
522 // Purpose : SLOT. Called when Filter dlg closed with OK button.
523 // Uncheck "Select submesh" and "Select group" checkboxes
524 //=======================================================================
525 void SMESHGUI_MultiEditDlg::onFilterAccepted()
528 for (int i = 0, n = myListBox->count(); i < n; i++)
529 myIds.Add(myListBox->text(i).toInt());
531 emit ListContensChanged();
533 if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
534 mySubmeshChk->blockSignals(true);
535 myGroupChk->blockSignals(true);
536 mySubmeshChk->setChecked(false);
537 myGroupChk->setChecked(false);
538 mySubmeshChk->blockSignals(false);
539 myGroupChk->blockSignals(false);
544 //=======================================================================
545 // name : SMESHGUI_MultiEditDlg::isIdValid
546 // Purpose : Verify whether Id of element satisfies to filters from viewer
547 //=======================================================================
548 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
550 SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
551 Handle(SMESHGUI_Filter) aFilter =
552 Handle(SMESHGUI_Filter)::DownCast(aStyle->GetFilter(myFilterType));
554 return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
557 //=======================================================================
558 // name : SMESHGUI_MultiEditDlg::onAddBtn
559 // Purpose : SLOT. Called when "Add" button pressed.
560 // Add selected in viewer entities in list box
561 //=======================================================================
562 void SMESHGUI_MultiEditDlg::onAddBtn()
564 const SALOME_ListIO& aList = mySelector->StoredIObjects();
566 int nbSelected = aList.Extent();
570 TColStd_IndexedMapOfInteger toBeAdded;
572 if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
574 mySelector->GetIndex(aList.First(),toBeAdded);
575 } else if (mySubmeshChk->isChecked()) {
576 SALOME_ListIteratorOfListIO anIter(aList);
577 for (; anIter.More(); anIter.Next()) {
578 SMESH::SMESH_subMesh_var aSubMesh =
579 SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
580 if (!aSubMesh->_is_nil()) {
581 if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
582 SMESH::long_array_var anIds = aSubMesh->GetElementsId();
583 for (int i = 0, n = anIds->length(); i < n; i++) {
584 if (isIdValid(anIds[ i ]))
585 toBeAdded.Add(anIds[ i ]);
590 } else if (myGroupChk->isChecked()) {
591 SALOME_ListIteratorOfListIO anIter(aList);
592 for (; anIter.More(); anIter.Next()) {
593 SMESH::SMESH_GroupBase_var aGroup =
594 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
595 if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
596 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
597 entityType() == 1)) {
598 if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
599 SMESH::long_array_var anIds = aGroup->GetListOfID();
600 for (int i = 0, n = anIds->length(); i < n; i++) {
601 if (isIdValid(anIds[ i ]))
602 toBeAdded.Add(anIds[ i ]);
611 bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
612 mySubmeshChk->setChecked(false);
613 myGroupChk->setChecked(false);
614 for(int i = 1; i <= toBeAdded.Extent(); i++)
615 if (myIds.Add(toBeAdded(i))) {
616 QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
617 myListBox->insertItem(item);
618 myListBox->setSelected(item, true);
622 emit ListContensChanged();
624 if (isGroupOrSubmesh)
625 onListSelectionChanged();
630 //=======================================================================
631 // name : SMESHGUI_MultiEditDlg::updateButtons
632 // Purpose : Enable/disable buttons of dialog in accordance with current state
633 //=======================================================================
634 void SMESHGUI_MultiEditDlg::updateButtons()
636 bool isOk = isValid(false);
637 myOkBtn->setEnabled(isOk);
638 myApplyBtn->setEnabled(isOk);
640 bool isListBoxNonEmpty = myListBox->count() > 0;
641 bool isToAll = myToAllChk->isChecked();
642 myFilterBtn->setEnabled(!isToAll);
643 myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
644 mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
646 const SALOME_ListIO& aList = mySelector->StoredIObjects();
650 aList.Extent() != 1 ||
651 (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
652 SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
653 SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
654 myAddBtn->setEnabled(false);
656 myAddBtn->setEnabled(true);
658 mySubmeshChk->setEnabled(!isToAll);
659 mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
660 mySubmesh->setEnabled(mySubmeshChk->isChecked());
662 myGroupChk->setEnabled(!isToAll);
663 myGroupBtn->setEnabled(myGroupChk->isChecked());
664 myGroup->setEnabled(myGroupChk->isChecked());
666 if (!mySubmeshChk->isChecked())
668 if (!myGroupChk->isChecked())
673 //=======================================================================
674 // name : SMESHGUI_MultiEditDlg::onRemoveBtn
675 // Purpose : SLOT. Called when "Remove" button pressed.
676 // Remove selected in list box entities
677 //=======================================================================
678 void SMESHGUI_MultiEditDlg::onRemoveBtn()
682 for (int i = 0, n = myListBox->count(); i < n; i++)
684 for (int i = myListBox->count(); i > 0; i--) {
685 if (myListBox->isSelected(i - 1))
687 int anId = myListBox->text(i - 1).toInt();
690 myListBox->removeItem(i-1);
696 emit ListContensChanged();
700 //=======================================================================
701 // name : SMESHGUI_MultiEditDlg::onSortListBtn
702 // Purpose : SLOT. Called when "Sort list" button pressed.
703 // Sort entities of list box
704 //=======================================================================
705 void SMESHGUI_MultiEditDlg::onSortListBtn()
709 int i, k = myListBox->count();
712 QStringList aSelected;
713 std::vector<int> anArray(k);
714 QListBoxItem* anItem;
715 for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
717 anArray[ i ] = anItem->text().toInt();
718 if (anItem->isSelected())
719 aSelected.append(anItem->text());
722 std::sort(anArray.begin(), anArray.end());
724 for (i = 0; i < k; i++)
725 myListBox->insertItem(QString::number(anArray[ i ]));
727 for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
729 anItem = myListBox->findItem(*it, Qt::ExactMatch);
731 myListBox->setSelected(anItem, true);
737 //=======================================================================
738 // name : SMESHGUI_MultiEditDlg::onListSelectionChanged
739 // Purpose : SLOT. Called when selection in list box changed.
740 // Highlight in selected entities
741 //=======================================================================
742 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
744 if (myActor == 0 || myBusy)
747 if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
750 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
753 TVisualObjPtr anObj = anActor->GetObject();
755 TColStd_MapOfInteger anIndexes;
756 for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
758 if (anItem->isSelected())
760 int anId = anItem->text().toInt();
761 if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
766 mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
767 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
768 aViewWindow->highlight(anActor->getIO(),true,true);
771 //=======================================================================
772 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
773 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
774 // Activate/deactivate selection of submeshes
775 //=======================================================================
776 void SMESHGUI_MultiEditDlg::onSubmeshChk()
778 bool isChecked = mySubmeshChk->isChecked();
779 mySubmeshBtn->setEnabled(isChecked);
780 mySubmesh->setEnabled(isChecked);
783 if (isChecked && myGroupChk->isChecked())
784 myGroupChk->setChecked(false);
789 //=======================================================================
790 // name : SMESHGUI_MultiEditDlg::onGroupChk
791 // Purpose : SLOT. Called when state of "Group" check box changed.
792 // Activate/deactivate selection of groupes
793 //=======================================================================
794 void SMESHGUI_MultiEditDlg::onGroupChk()
796 bool isChecked = myGroupChk->isChecked();
797 myGroupBtn->setEnabled(isChecked);
798 myGroup->setEnabled(isChecked);
801 if (isChecked && mySubmeshChk->isChecked())
802 mySubmeshChk->setChecked(false);
807 //=======================================================================
808 // name : SMESHGUI_MultiEditDlg::onToAllChk
809 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
810 // Activate/deactivate selection
811 //=======================================================================
812 void SMESHGUI_MultiEditDlg::onToAllChk()
814 bool isChecked = myToAllChk->isChecked();
821 emit ListContensChanged();
827 //=======================================================================
828 // name : SMESHGUI_MultiEditDlg::setSelectionMode
829 // Purpose : Set selection mode
830 //=======================================================================
831 void SMESHGUI_MultiEditDlg::setSelectionMode()
833 SMESH::RemoveFilters();
835 mySelectionMgr->clearSelected();
836 mySelectionMgr->clearFilters();
838 if (mySubmeshChk->isChecked()) {
839 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
840 aViewWindow->SetSelectionMode(ActorSelection);
841 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
843 else if (myGroupChk->isChecked()) {
844 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
845 aViewWindow->SetSelectionMode(ActorSelection);
846 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
850 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
851 aViewWindow->SetSelectionMode(VolumeSelection);
852 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
854 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
855 aViewWindow->SetSelectionMode(FaceSelection);
856 if (myFilterType == SMESHGUI_TriaFilter)
857 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
858 else if (myFilterType == SMESHGUI_QuadFilter)
859 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
861 SMESH::SetFilter(new SMESHGUI_FacesFilter());
865 //=======================================================================
866 // name : SMESHGUI_MultiEditDlg::onApply
867 // Purpose : SLOT. Called when "Apply" button clicked.
868 //=======================================================================
869 bool SMESHGUI_MultiEditDlg::onApply()
871 if (mySMESHGUI->isActiveStudyLocked())
876 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
877 if (aMeshEditor->_is_nil())
882 SMESH::long_array_var anIds = getIds();
884 bool aResult = process(aMeshEditor, anIds.inout());
887 mySelectionMgr->clearSelected();
893 emit ListContensChanged();
902 //=======================================================================
903 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
905 //=======================================================================
906 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
908 if (myEntityType != type) {
914 emit ListContensChanged();
917 myFilterType = SMESHGUI_VolumeFilter;
919 myFilterType = SMESHGUI_FaceFilter;
926 //=======================================================================
927 // name : SMESHGUI_MultiEditDlg::entityType
929 //=======================================================================
930 int SMESHGUI_MultiEditDlg::entityType()
936 * Class : SMESHGUI_ChangeOrientationDlg
937 * Description : Modification of orientation of faces
940 SMESHGUI_ChangeOrientationDlg
941 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
942 const char* theName):
943 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
945 setCaption(tr("CAPTION"));
948 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
952 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
953 const SMESH::long_array& theIds)
955 return theEditor->Reorient(theIds);
959 * Class : SMESHGUI_UnionOfTrianglesDlg
960 * Description : Construction of quadrangles by automatic association of triangles
963 SMESHGUI_UnionOfTrianglesDlg
964 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
965 const char* theName):
966 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
968 setCaption(tr("CAPTION"));
971 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
975 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
976 const SMESH::long_array& theIds)
978 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1.);
982 * Class : SMESHGUI_CuttingOfQuadsDlg
983 * Description : Construction of quadrangles by automatic association of triangles
986 SMESHGUI_CuttingOfQuadsDlg
987 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
988 const char* theName):
989 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
991 setCaption(tr("CAPTION"));
994 myUseDiagChk = new QCheckBox (tr("USE_DIAGONAL_2_4"), mySelGrp);
995 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
997 connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
998 connect(myUseDiagChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
999 connect(this, SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1002 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1006 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1009 SMESHGUI_MultiEditDlg::onClose();
1012 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1013 const SMESH::long_array& theIds)
1015 return theEditor->SplitQuad(theIds, !myUseDiagChk->isChecked());
1018 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1020 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1023 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1025 if (myPreviewActor == 0)
1028 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1029 vf->RemoveActor(myPreviewActor);
1032 myPreviewActor->Delete();
1036 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1041 if (myPreviewActor != 0)
1044 // get Ids of elements
1045 SMESH::long_array_var anElemIds = getIds();
1046 if (getIds()->length() == 0)
1049 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1053 bool isDiag24 = myUseDiagChk->isChecked();
1056 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1058 vtkIdType aNbCells = anElemIds->length() * 2;
1059 vtkIdType aCellsSize = 4 * aNbCells;
1060 vtkCellArray* aConnectivity = vtkCellArray::New();
1061 aConnectivity->Allocate(aCellsSize, 0);
1063 vtkPoints* aPoints = vtkPoints::New();
1064 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1066 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1067 aCellTypesArray->SetNumberOfComponents(1);
1068 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1070 vtkIdList *anIdList = vtkIdList::New();
1071 anIdList->SetNumberOfIds(3);
1073 TColStd_DataMapOfIntegerInteger anIdToVtk;
1077 for (int i = 0, n = anElemIds->length(); i < n; i++)
1079 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1080 if (anElem == 0 || anElem->NbNodes() != 4)
1083 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1085 while(anIter->more())
1086 if (const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next())
1088 if (!anIdToVtk.IsBound(aNode->GetID()))
1090 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1091 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1094 aNodes[ k++ ] = aNode->GetID();
1102 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1103 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1104 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1105 aConnectivity->InsertNextCell(anIdList);
1106 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1108 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1109 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1110 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1111 aConnectivity->InsertNextCell(anIdList);
1112 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1116 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1117 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1118 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1119 aConnectivity->InsertNextCell(anIdList);
1120 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1122 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1123 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1124 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1125 aConnectivity->InsertNextCell(anIdList);
1126 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1130 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1131 aCellLocationsArray->SetNumberOfComponents(1);
1132 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1134 aConnectivity->InitTraversal();
1135 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1136 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1138 aGrid->SetPoints(aPoints);
1139 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1141 // Create and display actor
1142 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1143 aMapper->SetInput(aGrid);
1145 myPreviewActor = SALOME_Actor::New();
1146 myPreviewActor->PickableOff();
1147 myPreviewActor->SetMapper(aMapper);
1149 vtkProperty* aProp = vtkProperty::New();
1150 aProp->SetRepresentationToWireframe();
1151 aProp->SetColor(250, 0, 250);
1152 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1153 myPreviewActor->SetProperty(aProp);
1155 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1156 SMESH::GetCurrentVtkView()->Repaint();
1160 aConnectivity->Delete();
1164 aCellTypesArray->Delete();
1165 aCellLocationsArray->Delete();