1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File : MeasureGUI_CheckSelfIntersectionsDlg.cxx
26 #include "MeasureGUI_CheckSelfIntersectionsDlg.h"
27 #include "MeasureGUI.h"
29 #include <SUIT_OverrideCursor.h>
30 #include <SUIT_Session.h>
31 #include <SUIT_ResourceMgr.h>
32 #include <LightApp_SelectionMgr.h>
33 #include <SalomeApp_Tools.h>
34 #include <SalomeApp_Application.h>
36 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TColStd_IndexedMapOfInteger.hxx>
39 #include <TColStd_MapOfInteger.hxx>
42 #include <GeometryGUI.h>
44 #include <GEOMImpl_Types.hxx>
45 #include <GEOM_GenericObjPtr.h>
47 #include <QListWidget>
49 #define TEXTEDIT_FONT_FAMILY "Courier"
50 #define TEXTEDIT_FONT_SIZE 11
52 //=================================================================================
53 // class : MeasureGUI_CheckSelfIntersectionsDlg()
54 // purpose : Constructs a MeasureGUI_CheckSelfIntersectionsDlg which is a child of 'parent', with the
55 // name 'name' and widget flags set to 'f'.
56 // The dialog will by default be modeless, unless you set 'modal' to
57 // true to construct a modal dialog.
58 //=================================================================================
59 MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent)
60 : GEOMBase_Skeleton (GUI, parent, false),
69 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
70 QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS")));
71 QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
73 setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS"));
75 /***************************************************************/
76 mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS"));
77 mainFrame()->RadioButton1->setIcon(image0);
78 mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
79 mainFrame()->RadioButton2->close();
80 mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
81 mainFrame()->RadioButton3->close();
83 QGroupBox *aGrp = new QGroupBox(tr("GEOM_CHECK_INFOS"));
84 QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT"));
85 QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"));
86 QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"));
87 QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL"));
88 QLabel *aSummaryLbl = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY"));
89 QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE);
91 aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias);
92 myTextView = new QTextBrowser;
93 myTextView->setReadOnly(true);
94 myTextView->setFont(aFont);
96 mySelButton = new QPushButton;
97 mySelButton->setIcon(image1);
98 mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
100 myEditObjName = new QLineEdit;
101 myEditObjName->setReadOnly(true);
103 myLevelBox = new QComboBox;
105 myComputeButton = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE"));
108 myInteList = new QListWidget;
109 myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection);
110 myShapeList = new QListWidget;
111 myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
113 QGridLayout *aGrpLayout = new QGridLayout(aGrp);
115 aGrpLayout->setMargin(9);
116 aGrpLayout->setSpacing(6);
117 aGrpLayout->addWidget(anObjLbl, 0, 0);
118 aGrpLayout->addWidget(anInteLbl, 5, 0);
119 aGrpLayout->addWidget(aShapeLbl, 5, 2);
120 aGrpLayout->addWidget(aLevelLbl, 1, 0);
121 aGrpLayout->addWidget(myLevelBox, 1, 1, 1, 2);
122 aGrpLayout->addWidget(myComputeButton, 2, 0, 1, 3);
123 aGrpLayout->addWidget(aSummaryLbl, 3, 0);
124 aGrpLayout->addWidget(myTextView, 4, 0, 1, 3);
125 aGrpLayout->addWidget(mySelButton, 0, 1);
126 aGrpLayout->addWidget(myEditObjName, 0, 2);
127 aGrpLayout->addWidget(myInteList, 6, 0, 1, 2);
128 aGrpLayout->addWidget(myShapeList, 6, 2);
130 QVBoxLayout* layout = new QVBoxLayout (centralWidget());
131 layout->setMargin(0); layout->setSpacing(6);
132 layout->addWidget(aGrp);
134 /***************************************************************/
136 myHelpFileName = "check_self_intersections_page.html";
142 //=================================================================================
143 // function : ~MeasureGUI_CheckSelfIntersectionsDlg()
144 // purpose : Destroys the object and frees any allocated resources
145 //=================================================================================
146 MeasureGUI_CheckSelfIntersectionsDlg::~MeasureGUI_CheckSelfIntersectionsDlg()
150 //=================================================================================
153 //=================================================================================
154 void MeasureGUI_CheckSelfIntersectionsDlg::Init()
156 // Fill in the combo box.
157 myLevelBox->insertItem(GEOM::SI_V_V, tr("GEOM_CHECK_INTE_V_V"));
158 myLevelBox->insertItem(GEOM::SI_V_E, tr("GEOM_CHECK_INTE_V_E"));
159 myLevelBox->insertItem(GEOM::SI_E_E, tr("GEOM_CHECK_INTE_E_E"));
160 myLevelBox->insertItem(GEOM::SI_V_F, tr("GEOM_CHECK_INTE_V_F"));
161 myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F"));
162 myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL"));
163 myLevelBox->setCurrentIndex(GEOM::SI_ALL);
165 connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()),
166 this, SLOT(DeactivateActiveDialog()));
167 connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),
168 this, SLOT(ClickOnCancel()));
169 connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
170 connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
171 connect(mySelButton, SIGNAL(clicked()),
172 this, SLOT(SetEditCurrentArgument()));
173 connect(myInteList, SIGNAL(itemSelectionChanged()),
174 SLOT(onInteListSelectionChanged()));
175 connect(myShapeList, SIGNAL(itemSelectionChanged()),
176 SLOT(onSubShapesListSelectionChanged()));
177 connect(myLevelBox, SIGNAL(currentIndexChanged(int)),
178 this, SLOT(clear()));
179 connect(myComputeButton, SIGNAL(clicked()), this, SLOT(onCompute()));
181 LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
183 connect(aSel, SIGNAL(currentSelectionChanged()),
184 this, SLOT(SelectionIntoArgument()));
186 initName( tr( "GEOM_SELF_INTERSECTION_NAME") );
187 buttonOk()->setEnabled(false);
188 buttonApply()->setEnabled(false);
189 myComputeButton->setEnabled(false);
191 SelectionIntoArgument();
194 //=================================================================================
197 //=================================================================================
198 void MeasureGUI_CheckSelfIntersectionsDlg::clear()
200 myTextView->setText("");
202 myInteList->blockSignals(true);
203 myShapeList->blockSignals(true);
205 myShapeList->clear();
206 myInteList->blockSignals(false);
207 myShapeList->blockSignals(false);
211 buttonOk()->setEnabled(false);
212 buttonApply()->setEnabled(false);
213 myComputeButton->setEnabled(true);
216 //=================================================================================
217 // function : onCompute
219 //=================================================================================
220 void MeasureGUI_CheckSelfIntersectionsDlg::onCompute()
222 bool hasSelfInte = false;
223 QString anErrMsg("");
225 if (!findSelfIntersections(hasSelfInte, anErrMsg)) {
226 myTextView->setText(anErrMsg);
230 // Status and apply buttons
234 aMsg += tr("GEOM_SELF_INTERSECTIONS_FOUND");
235 buttonOk()->setEnabled(true);
236 buttonApply()->setEnabled(true);
238 aMsg += tr("GEOM_NO_SELF_INTERSECTIONS");
241 if (!anErrMsg.isEmpty()) {
246 myTextView->setText(aMsg);
249 QStringList anInteList;
250 QString anInteStr ("");
251 int nbPairs = myInters->length()/2;
253 for (int i = 1; i <= nbPairs; i++) {
254 anInteStr = "Intersection # ";
255 anInteStr += QString::number(i);
256 anInteList.append(anInteStr);
259 myInteList->addItems(anInteList);
260 myComputeButton->setEnabled(false);
263 //=================================================================================
264 // function : ActivateThisDialog
266 //=================================================================================
267 void MeasureGUI_CheckSelfIntersectionsDlg::ActivateThisDialog()
269 GEOMBase_Skeleton::ActivateThisDialog();
271 LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr();
273 connect( aSel, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
276 DISPLAY_PREVIEW_MACRO
279 //=================================================================================
280 // function : DeactivateActiveDialog()
281 // purpose : public slot to deactivate if active
282 //=================================================================================
283 void MeasureGUI_CheckSelfIntersectionsDlg::DeactivateActiveDialog()
285 GEOMBase_Skeleton::DeactivateActiveDialog();
288 //=================================================================================
289 // function : activateSelection
291 //=================================================================================
292 void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection()
294 globalSelection(GEOM_ALLSHAPES);
297 //=================================================================================
298 // function : ClickOnOk()
300 //=================================================================================
301 void MeasureGUI_CheckSelfIntersectionsDlg::ClickOnOk()
303 if ( ClickOnApply() )
307 //=================================================================================
308 // function : ClickOnApply()
310 //=================================================================================
311 bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply()
320 //=================================================================================
321 // function : extractPrefix
323 //=================================================================================
324 bool MeasureGUI_CheckSelfIntersectionsDlg::extractPrefix() const
329 //=================================================================================
330 // function : createOperation
332 //=================================================================================
333 GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation()
335 return getGeomEngine()->GetIMeasureOperations( getStudyId() );
338 //=================================================================================
339 // function : isValid
341 //=================================================================================
342 bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& )
344 return !myObj->_is_nil();
347 //=================================================================================
348 // function : SetEditCurrentArgument
350 //=================================================================================
351 void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument()
353 myEditObjName->setFocus();
354 SelectionIntoArgument();
357 //=================================================================================
358 // function : SelectionIntoArgument
360 //=================================================================================
361 void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument()
365 myObj = GEOM::GEOM_Object::_nil();
367 LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
368 SALOME_ListIO aSelList;
369 aSelMgr->selectedObjects(aSelList);
371 GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil();
373 if (aSelList.Extent() > 0) {
374 aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
377 if (aSelectedObject->_is_nil()) {
378 myEditObjName->setText("");
382 myObj = aSelectedObject;
383 myEditObjName->setText(GEOMBase::GetName(myObj));
386 //=================================================================================
387 // function : enterEvent
389 //=================================================================================
390 void MeasureGUI_CheckSelfIntersectionsDlg::enterEvent(QEvent *)
392 if ( !mainFrame()->GroupConstructors->isEnabled() )
393 ActivateThisDialog();
396 //=================================================================================
397 // function : findSelfIntersections
399 //=================================================================================
400 bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
401 (bool &HasSelfInte, QString &theErrMsg)
403 if (myObj->_is_nil()) {
407 GEOM::GEOM_IMeasureOperations_var anOper =
408 GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
411 int aLevel = myLevelBox->currentIndex();
414 HasSelfInte = !anOper->CheckSelfIntersections(myObj, aLevel, myInters);
415 nbPairs = myInters->length()/2;
417 if (nbPairs*2 != myInters->length()) {
421 catch (const SALOME::SALOME_Exception& e) {
422 SalomeApp_Tools::QtCatchCorbaException(e);
426 if (!anOper->IsDone()) {
427 if (myInters->length() == 0) {
428 theErrMsg = tr(anOper->GetErrorCode());
431 // Valid case. Display all computed self-intersections
432 theErrMsg = tr("GEOM_CHECK_SELF_INTERSECTIONS_ERRORS");
435 theErrMsg = tr("GEOM_CHECK_SELF_INTERSECTIONS_FAILED");
441 //=================================================================================
442 // function : onInteListSelectionChanged
444 //=================================================================================
445 void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged()
448 myShapeList->clear();
450 TopoDS_Shape aSelShape;
451 if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
452 TopTools_IndexedMapOfShape anIndices;
453 TopExp::MapShapes(aSelShape, anIndices);
455 int nbSelected = myInteList->selectedItems().size();
457 for (int i = 0; i < myInteList->count(); i++) {
458 if ( myInteList->item(i)->isSelected() ) {
459 if ( nbSelected > 1 )
460 myShapeList->addItem(QString("--- #%1 ---").arg(i+1));
461 for (int j = 0; j < 2; j++) {
462 TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]);
463 QString aType = GEOMBase::GetShapeTypeString(aSubShape);
464 myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j]));
465 myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]);
472 //=================================================================================
473 // function : onSubShapesListSelectionChanged
475 //=================================================================================
476 void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
481 QList<QListWidgetItem*> selected = myShapeList->selectedItems();
483 foreach(QListWidgetItem* item, selected) {
484 int idx = item->data(Qt::UserRole).toInt();
485 if (idx > 0 && aIds.indexOf(idx) < 0) aIds.append(idx);
488 if (aIds.empty()) return;
490 TopoDS_Shape aSelShape;
491 TopoDS_Shape aSubShape;
492 TopTools_IndexedMapOfShape anIndices;
493 if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
494 TopExp::MapShapes(aSelShape, anIndices);
495 getDisplayer()->SetColor(Quantity_NOC_RED);
496 getDisplayer()->SetWidth(3);
497 getDisplayer()->SetToActivate(false);
498 foreach(int idx, aIds) {
499 aSubShape = anIndices.FindKey(idx);
501 SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0;
502 if (aPrs) displayPreview(aPrs, true);
504 catch (const SALOME::SALOME_Exception& e) {
505 SalomeApp_Tools::QtCatchCorbaException(e);
511 //=================================================================================
512 // function : execute
514 //=================================================================================
515 bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
520 if (!findSelfIntersections(hasSelfInte, anErrMsg)) {
524 TColStd_IndexedMapOfInteger aMapIndex;
527 int nbSelected = myInteList->selectedItems().size();
529 // Collect the map of indices
530 for (int i = 0; i < myInteList->count(); i++) {
531 if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) {
532 aMapIndex.Add(myInters[i*2]);
533 aMapIndex.Add(myInters[i*2 + 1]);
534 pairs << myInters[i*2];
535 pairs << myInters[i*2 + 1];
539 GEOM::ShapesOpPtr shapesOper = getGeomEngine()->GetIShapesOperations(getStudyId());
541 // Explode sub-shapes
542 GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
543 anArray->length(aMapIndex.Extent());
545 for (int i = 1; i <= aMapIndex.Extent(); i++)
546 anArray[i-1] = aMapIndex.FindKey(i);
548 GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray);
551 for (int i = 0; i < pairs.count()/2; i++) {
552 GEOM::ListOfGO_var aPair = new GEOM::ListOfGO();
554 aPair[0] = aList[ aMapIndex.FindIndex(pairs[i*2]) - 1 ];
555 aPair[1] = aList[ aMapIndex.FindIndex(pairs[i*2+1]) - 1 ];
556 GEOM::GEOM_Object_var aCompound = shapesOper->MakeCompound( aPair );
557 objects.push_back(aCompound._retn());
563 //================================================================
564 // Function : getFather
565 // Purpose : Get father object for object to be added in study
566 // (called with addInStudy method)
567 //================================================================
568 GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather
569 (GEOM::GEOM_Object_ptr)