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 myViewWindow(SMESH::GetViewWindow(theModule)),
115 mySMESHGUI(theModule)
120 myFilterType = theMode;
121 QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
123 QFrame* aMainFrame = createMainFrame (this, the3d2d);
124 QFrame* aBtnFrame = createButtonFrame(this);
126 aDlgLay->addWidget(aMainFrame);
127 aDlgLay->addWidget(aBtnFrame);
129 aDlgLay->setStretchFactor(aMainFrame, 1);
130 aDlgLay->setStretchFactor(aBtnFrame, 0);
134 //=======================================================================
135 // name : SMESHGUI_MultiEditDlg::createMainFrame
136 // Purpose : Create frame containing dialog's input fields
137 //=======================================================================
138 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
140 QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
141 aMainGrp->setFrameStyle(QFrame::NoFrame);
142 aMainGrp->setInsideMargin(0);
144 QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
146 // "Selected cells" group
147 mySelGrp = new QGroupBox(1, Qt::Horizontal, aMainGrp);
151 myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
152 (new QRadioButton(tr("SMESH_FACE"), myEntityTypeGrp))->setChecked(true);
153 (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
154 myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
157 QFrame* aFrame = new QFrame(mySelGrp);
159 myListBox = new QListBox(aFrame);
160 myListBox->setSelectionMode(QListBox::Extended);
161 myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
162 // myListBox->setColumnMode(QListBox::FitToHeight);
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 // "Select from" group
183 QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
185 mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
186 mySubmeshBtn = new QPushButton(aGrp);
187 mySubmesh = new QLineEdit(aGrp);
188 mySubmesh->setReadOnly(true);
189 mySubmeshBtn->setPixmap(aPix);
191 myGroupChk = new QCheckBox(tr("GROUP"), aGrp);
192 myGroupBtn = new QPushButton(aGrp);
193 myGroup = new QLineEdit(aGrp);
194 myGroup->setReadOnly(true);
195 myGroupBtn->setPixmap(aPix);
200 //=======================================================================
201 // name : SMESHGUI_MultiEditDlg::createButtonFrame
202 // Purpose : Create frame containing buttons
203 //=======================================================================
204 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
206 QFrame* aFrame = new QFrame (theParent);
207 aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
209 myOkBtn = new QPushButton (tr("SMESH_BUT_OK" ), aFrame);
210 myApplyBtn = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
211 myCloseBtn = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
213 QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
215 QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
217 aLay->addWidget(myOkBtn);
218 aLay->addWidget(myApplyBtn);
219 aLay->addItem(aSpacer);
220 aLay->addWidget(myCloseBtn);
225 //=======================================================================
226 // name : SMESHGUI_MultiEditDlg::isValid
227 // Purpose : Verify validity of input data
228 //=======================================================================
229 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
231 return (!myMesh->_is_nil() &&
232 (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
235 //=======================================================================
236 // name : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
237 // Purpose : Destructor
238 //=======================================================================
239 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
241 if (myFilterDlg != 0)
243 myFilterDlg->reparent(0, QPoint());
248 //=======================================================================
249 // name : SMESHGUI_MultiEditDlg::eventFilter
250 // Purpose : event filter
251 //=======================================================================
252 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
254 if (object == myListBox && event->type() == QEvent::KeyPress) {
255 QKeyEvent* ke = (QKeyEvent*)event;
256 if (ke->key() == Key_Delete)
259 return QDialog::eventFilter(object, event);
262 //=======================================================================
263 // name : SMESHGUI_MultiEditDlg::Init
264 // Purpose : Init dialog fields, connect signals and slots, show dialog
265 //=======================================================================
266 void SMESHGUI_MultiEditDlg::Init()
268 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
273 emit ListContensChanged();
276 connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk()));
277 connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
278 connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
280 // selection and SMESHGUI
281 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
282 connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
283 connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
286 connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn() ));
287 connect(myAddBtn , SIGNAL(clicked()), SLOT(onAddBtn() ));
288 connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn() ));
289 connect(mySortBtn , SIGNAL(clicked()), SLOT(onSortListBtn()));
291 connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
292 connect(myGroupChk , SIGNAL(stateChanged(int)), SLOT(onGroupChk() ));
293 connect(myToAllChk , SIGNAL(stateChanged(int)), SLOT(onToAllChk() ));
296 connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
298 connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
302 // set selection mode
307 //=======================================================================
308 // name : SMESHGUI_MultiEditDlg::onOk
309 // Purpose : SLOT called when "Ok" button pressed.
310 // Assign filters VTK viewer and close dialog
311 //=======================================================================
312 void SMESHGUI_MultiEditDlg::onOk()
318 //=======================================================================
319 // name : SMESHGUI_MultiEditDlg::getIds
320 // Purpose : Retrive identifiers from list box
321 //=======================================================================
322 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
324 SMESH::long_array_var anIds = new SMESH::long_array;
326 if (myToAllChk->isChecked())
329 SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
334 TVisualObjPtr aVisualObj = anActor->GetObject();
335 vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
337 for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
338 vtkCell* aCell = aGrid->GetCell(i);
340 vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
341 vtkQuad* aQua = vtkQuad::SafeDownCast(aCell);
342 vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell);
344 vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell);
345 vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
347 if (aTri && myFilterType == SMESHGUI_TriaFilter ||
348 aQua && myFilterType == SMESHGUI_QuadFilter ||
349 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
350 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
351 int anObjId = aVisualObj->GetElemObjId(i);
360 anIds->length(myIds.Extent());
361 TColStd_MapIteratorOfMapOfInteger anIter(myIds);
362 for (int i = 0; anIter.More(); anIter.Next() )
364 anIds[ i++ ] = anIter.Key();
366 return anIds._retn();
369 //=======================================================================
370 // name : SMESHGUI_MultiEditDlg::onClose
371 // Purpose : SLOT called when "Close" button pressed. Close dialog
372 //=======================================================================
373 void SMESHGUI_MultiEditDlg::onClose()
375 myViewWindow->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 myViewWindow->highlight(anActor->getIO(),true,true);
768 //=======================================================================
769 // name : SMESHGUI_MultiEditDlg::onSubmeshChk
770 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
771 // Activate/deactivate selection of submeshes
772 //=======================================================================
773 void SMESHGUI_MultiEditDlg::onSubmeshChk()
775 bool isChecked = mySubmeshChk->isChecked();
776 mySubmeshBtn->setEnabled(isChecked);
777 mySubmesh->setEnabled(isChecked);
780 if (isChecked && myGroupChk->isChecked())
781 myGroupChk->setChecked(false);
786 //=======================================================================
787 // name : SMESHGUI_MultiEditDlg::onGroupChk
788 // Purpose : SLOT. Called when state of "Group" check box changed.
789 // Activate/deactivate selection of groupes
790 //=======================================================================
791 void SMESHGUI_MultiEditDlg::onGroupChk()
793 bool isChecked = myGroupChk->isChecked();
794 myGroupBtn->setEnabled(isChecked);
795 myGroup->setEnabled(isChecked);
798 if (isChecked && mySubmeshChk->isChecked())
799 mySubmeshChk->setChecked(false);
804 //=======================================================================
805 // name : SMESHGUI_MultiEditDlg::onToAllChk
806 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
807 // Activate/deactivate selection
808 //=======================================================================
809 void SMESHGUI_MultiEditDlg::onToAllChk()
811 bool isChecked = myToAllChk->isChecked();
818 emit ListContensChanged();
824 //=======================================================================
825 // name : SMESHGUI_MultiEditDlg::setSelectionMode
826 // Purpose : Set selection mode
827 //=======================================================================
828 void SMESHGUI_MultiEditDlg::setSelectionMode()
830 SMESH::RemoveFilters();
832 mySelectionMgr->clearSelected();
833 mySelectionMgr->clearFilters();
835 if (mySubmeshChk->isChecked()) {
836 myViewWindow->SetSelectionMode(ActorSelection);
837 mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
839 else if (myGroupChk->isChecked()) {
840 myViewWindow->SetSelectionMode(ActorSelection);
841 mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
845 myViewWindow->SetSelectionMode(VolumeSelection);
846 SMESH::SetFilter(new SMESHGUI_VolumesFilter());
848 myViewWindow->SetSelectionMode(FaceSelection);
849 if (myFilterType == SMESHGUI_TriaFilter)
850 SMESH::SetFilter(new SMESHGUI_TriangleFilter());
851 else if (myFilterType == SMESHGUI_QuadFilter)
852 SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
854 SMESH::SetFilter(new SMESHGUI_FacesFilter());
858 //=======================================================================
859 // name : SMESHGUI_MultiEditDlg::onApply
860 // Purpose : SLOT. Called when "Apply" button clicked.
861 //=======================================================================
862 bool SMESHGUI_MultiEditDlg::onApply()
864 if (mySMESHGUI->isActiveStudyLocked())
869 SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
870 if (aMeshEditor->_is_nil())
875 SMESH::long_array_var anIds = getIds();
877 bool aResult = process(aMeshEditor, anIds.inout());
885 emit ListContensChanged();
894 //=======================================================================
895 // name : SMESHGUI_MultiEditDlg::on3d2dChanged
897 //=======================================================================
898 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
900 if (myEntityType != type) {
906 emit ListContensChanged();
909 myFilterType = SMESHGUI_VolumeFilter;
911 myFilterType = SMESHGUI_FaceFilter;
918 //=======================================================================
919 // name : SMESHGUI_MultiEditDlg::entityType
921 //=======================================================================
922 int SMESHGUI_MultiEditDlg::entityType()
928 * Class : SMESHGUI_ChangeOrientationDlg
929 * Description : Modification of orientation of faces
932 SMESHGUI_ChangeOrientationDlg
933 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
934 const char* theName):
935 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
937 setCaption(tr("CAPTION"));
940 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
944 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
945 const SMESH::long_array& theIds)
947 return theEditor->Reorient(theIds);
951 * Class : SMESHGUI_UnionOfTrianglesDlg
952 * Description : Construction of quadrangles by automatic association of triangles
955 SMESHGUI_UnionOfTrianglesDlg
956 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
957 const char* theName):
958 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
960 setCaption(tr("CAPTION"));
963 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
967 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
968 const SMESH::long_array& theIds)
970 return theEditor->TriToQuad(theIds, SMESH::NumericalFunctor::_nil(), 1.);
974 * Class : SMESHGUI_CuttingOfQuadsDlg
975 * Description : Construction of quadrangles by automatic association of triangles
978 SMESHGUI_CuttingOfQuadsDlg
979 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
980 const char* theName):
981 SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
983 setCaption(tr("CAPTION"));
986 myUseDiagChk = new QCheckBox (tr("USE_DIAGONAL_2_4"), mySelGrp);
987 myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
989 connect(myPreviewChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
990 connect(myUseDiagChk, SIGNAL(stateChanged(int)), this, SLOT(onPreviewChk()));
991 connect(this, SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
994 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
998 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1001 SMESHGUI_MultiEditDlg::onClose();
1004 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1005 const SMESH::long_array& theIds)
1007 return theEditor->SplitQuad(theIds, !myUseDiagChk->isChecked());
1010 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1012 myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1015 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1017 if (myPreviewActor == 0)
1020 if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1021 vf->RemoveActor(myPreviewActor);
1024 myPreviewActor->Delete();
1028 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1033 if (myPreviewActor != 0)
1036 // get Ids of elements
1037 SMESH::long_array_var anElemIds = getIds();
1038 if (getIds()->length() == 0)
1041 SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1045 bool isDiag24 = myUseDiagChk->isChecked();
1048 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1050 vtkIdType aNbCells = anElemIds->length() * 2;
1051 vtkIdType aCellsSize = 4 * aNbCells;
1052 vtkCellArray* aConnectivity = vtkCellArray::New();
1053 aConnectivity->Allocate(aCellsSize, 0);
1055 vtkPoints* aPoints = vtkPoints::New();
1056 aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1058 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1059 aCellTypesArray->SetNumberOfComponents(1);
1060 aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1062 vtkIdList *anIdList = vtkIdList::New();
1063 anIdList->SetNumberOfIds(3);
1065 TColStd_DataMapOfIntegerInteger anIdToVtk;
1069 for (int i = 0, n = anElemIds->length(); i < n; i++)
1071 const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1072 if (anElem == 0 || anElem->NbNodes() != 4)
1075 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1077 while(anIter->more())
1078 if (const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next())
1080 if (!anIdToVtk.IsBound(aNode->GetID()))
1082 aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1083 anIdToVtk.Bind(aNode->GetID(), nbPoints);
1086 aNodes[ k++ ] = aNode->GetID();
1094 anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1095 anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1096 anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1097 aConnectivity->InsertNextCell(anIdList);
1098 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1100 anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1101 anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1102 anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1103 aConnectivity->InsertNextCell(anIdList);
1104 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1108 anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1109 anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1110 anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1111 aConnectivity->InsertNextCell(anIdList);
1112 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1114 anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1115 anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1116 anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1117 aConnectivity->InsertNextCell(anIdList);
1118 aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1122 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
1123 aCellLocationsArray->SetNumberOfComponents(1);
1124 aCellLocationsArray->SetNumberOfTuples(aNbCells);
1126 aConnectivity->InitTraversal();
1127 for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1128 aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1130 aGrid->SetPoints(aPoints);
1131 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1133 // Create and display actor
1134 vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1135 aMapper->SetInput(aGrid);
1137 myPreviewActor = SALOME_Actor::New();
1138 myPreviewActor->PickableOff();
1139 myPreviewActor->SetMapper(aMapper);
1141 vtkProperty* aProp = vtkProperty::New();
1142 aProp->SetRepresentationToWireframe();
1143 aProp->SetColor(250, 0, 250);
1144 aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1145 myPreviewActor->SetProperty(aProp);
1147 SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1148 SMESH::GetCurrentVtkView()->Repaint();
1152 aConnectivity->Delete();
1156 aCellTypesArray->Delete();
1157 aCellLocationsArray->Delete();