0022750: [EDF] Improve ergonomics of the "Detect Self-intersections" dialog box

Additional improvements:
- Allow multiple selection of interferences
- Publish each interference as a Compound containing two sub-shapes
This commit is contained in:
vsr 2014-12-23 16:19:54 +03:00
parent be8d935c3b
commit 045908212e
3 changed files with 64 additions and 86 deletions

View File

@ -14,10 +14,10 @@ In this dialog:
- <b>Compute self-intersections</b> button computes self-interferences. - <b>Compute self-intersections</b> button computes self-interferences.
- \b Summary section contains the general report if the object has self-intersections and/or if errors are occured during computation. - \b Summary section contains the general report if the object has self-intersections and/or if errors are occured during computation.
- \b Self-intersections list contains the list of self-intersections detected. - \b Self-intersections list contains the list of self-intersections detected.
Select the intersection to show <b>Sub-shapes</b> in the field to the right. Select the intersection(s) to show <b>Sub-shapes</b> in the field to the right.
- \b Apply and <b>Apply and Close</b> buttons are used to store selected self-intersected shapes in the study for further analysis. - \b Apply and <b>Apply and Close</b> buttons are used to store interferences selected in the "Self-intersections" list box in the study for further analysis.
If no shapes are selected, but an intersection is selected the both of intersected shapes are stored. If no intersections selected If no any interference is selected, all interferences are published in the study. Each interference is published as a child
all shapes of all intersections are stored in the study. compound of the source shape and contains a couple of intersecting sub-shapes.
\note This tool is useful for detection of shapes, not suitable for \note This tool is useful for detection of shapes, not suitable for
arguments of Boolean operations and Partition algorithm. arguments of Boolean operations and Partition algorithm.

View File

@ -42,6 +42,7 @@
#include <GeometryGUI.h> #include <GeometryGUI.h>
#include <GEOMBase.h> #include <GEOMBase.h>
#include <GEOMImpl_Types.hxx> #include <GEOMImpl_Types.hxx>
#include <GEOM_GenericObjPtr.h>
#include <QListWidget> #include <QListWidget>
@ -105,6 +106,7 @@ MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (Geom
myInteList = new QListWidget; myInteList = new QListWidget;
myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection);
myShapeList = new QListWidget; myShapeList = new QListWidget;
myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection); myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection);
@ -196,15 +198,16 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init()
void MeasureGUI_CheckSelfIntersectionsDlg::clear() void MeasureGUI_CheckSelfIntersectionsDlg::clear()
{ {
myTextView->setText(""); myTextView->setText("");
disconnect(myInteList, SIGNAL(itemSelectionChanged()), this, 0);
disconnect(myShapeList, SIGNAL(itemSelectionChanged()), this, 0); myInteList->blockSignals(true);
myShapeList->blockSignals(true);
myInteList->clear(); myInteList->clear();
myShapeList->clear(); myShapeList->clear();
connect(myInteList, SIGNAL(itemSelectionChanged()), myInteList->blockSignals(false);
SLOT(onInteListSelectionChanged())); myShapeList->blockSignals(false);
connect(myShapeList, SIGNAL(itemSelectionChanged()),
SLOT(onSubShapesListSelectionChanged()));
erasePreview(); erasePreview();
buttonOk()->setEnabled(false); buttonOk()->setEnabled(false);
buttonApply()->setEnabled(false); buttonApply()->setEnabled(false);
myComputeButton->setEnabled(true); myComputeButton->setEnabled(true);
@ -442,28 +445,28 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections
void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged() void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged()
{ {
erasePreview(); erasePreview();
int aCurItem = myInteList->currentRow(); myShapeList->clear();
if (aCurItem < 0)
return;
QStringList aSubShapeList;
TopoDS_Shape aSelShape; TopoDS_Shape aSelShape;
if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
TopTools_IndexedMapOfShape anIndices; TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(aSelShape, anIndices); TopExp::MapShapes(aSelShape, anIndices);
TopoDS_Shape aSubShape = anIndices.FindKey(myInters[aCurItem*2]); int nbSelected = myInteList->selectedItems().size();
for (int i = 0; i < myInteList->count(); i++) {
if ( myInteList->item(i)->isSelected() ) {
if ( nbSelected > 1 )
myShapeList->addItem(QString("--- #%1 ---").arg(i+1));
for (int j = 0; j < 2; j++) {
TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]);
QString aType = GEOMBase::GetShapeTypeString(aSubShape); QString aType = GEOMBase::GetShapeTypeString(aSubShape);
if (!aType.isEmpty()) myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j]));
aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2])); myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]);
aSubShape = anIndices.FindKey(myInters[aCurItem*2 + 1]); }
aType = GEOMBase::GetShapeTypeString(aSubShape); }
if (!aType.isEmpty()) }
aSubShapeList.append(QString("%1_%2").arg(aType).arg(myInters[aCurItem*2 + 1]));
} }
myShapeList->clear();
myShapeList->addItems(aSubShapeList);
} }
//================================================================================= //=================================================================================
@ -474,36 +477,29 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged()
{ {
erasePreview(); erasePreview();
// Current pair
int aErrCurItem = myInteList->currentRow();
if (aErrCurItem < 0)
return;
// Selected IDs // Selected IDs
QList<QListWidgetItem*> selected = myShapeList->selectedItems();
QList<int> aIds; QList<int> aIds;
for (int i = 0, n = myShapeList->count(); i < n; i++) { foreach(QListWidgetItem* item, selected) {
if (myShapeList->item(i)->isSelected()) int idx = item->data(Qt::UserRole).toInt();
aIds.append(i); if (idx > 0 && aIds.indexOf(idx) < 0) aIds.append(idx);
} }
if (aIds.count() < 1)
return; if (aIds.empty()) return;
TopoDS_Shape aSelShape; TopoDS_Shape aSelShape;
TopoDS_Shape aSubShape; TopoDS_Shape aSubShape;
TopTools_IndexedMapOfShape anIndices; TopTools_IndexedMapOfShape anIndices;
if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) {
SALOME_Prs* aPrs = 0;
TopExp::MapShapes(aSelShape, anIndices); TopExp::MapShapes(aSelShape, anIndices);
QList<int>::iterator it;
for (it = aIds.begin(); it != aIds.end(); ++it) {
aSubShape = anIndices.FindKey(myInters[aErrCurItem*2 + (*it)]);
try {
getDisplayer()->SetColor(Quantity_NOC_RED); getDisplayer()->SetColor(Quantity_NOC_RED);
getDisplayer()->SetWidth(3); getDisplayer()->SetWidth(3);
getDisplayer()->SetToActivate(false); getDisplayer()->SetToActivate(false);
aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; foreach(int idx, aIds) {
if (aPrs) aSubShape = anIndices.FindKey(idx);
displayPreview(aPrs, true); try {
SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0;
if (aPrs) displayPreview(aPrs, true);
} }
catch (const SALOME::SALOME_Exception& e) { catch (const SALOME::SALOME_Exception& e) {
SalomeApp_Tools::QtCatchCorbaException(e); SalomeApp_Tools::QtCatchCorbaException(e);
@ -525,56 +521,40 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects)
return false; return false;
} }
const int aNbInteSelected = myInteList->selectedItems().size();
const bool isPublishAllInte = (aNbInteSelected < 1);
const bool isPublishAllShapes =
(aNbInteSelected != 1 || myShapeList->selectedItems().empty());
int i;
const int n = myInteList->count();
TColStd_IndexedMapOfInteger aMapIndex; TColStd_IndexedMapOfInteger aMapIndex;
QList<int> pairs;
// Collect the map of indices. int nbSelected = myInteList->selectedItems().size();
for (i = 0; i < n; i++) {
if (isPublishAllInte) { // Collect the map of indices
// Collect the both of two indices. for (int i = 0; i < myInteList->count(); i++) {
if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) {
aMapIndex.Add(myInters[i*2]); aMapIndex.Add(myInters[i*2]);
aMapIndex.Add(myInters[i*2 + 1]); aMapIndex.Add(myInters[i*2 + 1]);
} else if (myInteList->item(i)->isSelected()) { pairs << myInters[i*2];
if (isPublishAllShapes) { pairs << myInters[i*2 + 1];
// Collect the both of two indices.
aMapIndex.Add(myInters[i*2]);
aMapIndex.Add(myInters[i*2 + 1]);
} else if (myShapeList->count() == 2) {
// Collect only selected items.
if (myShapeList->item(0)->isSelected()) {
aMapIndex.Add(myInters[i*2]);
}
if (myShapeList->item(1)->isSelected()) {
aMapIndex.Add(myInters[i*2 + 1]);
}
}
} }
} }
// Create objects. GEOM::ShapesOpPtr shapesOper = getGeomEngine()->GetIShapesOperations(getStudyId());
// Explode sub-shapes
GEOM::ListOfLong_var anArray = new GEOM::ListOfLong; GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
const int aNbShapes = aMapIndex.Extent(); anArray->length(aMapIndex.Extent());
anArray->length(aNbShapes); for (int i = 1; i <= aMapIndex.Extent(); i++)
for (i = 1; i <= aNbShapes; i++) {
anArray[i-1] = aMapIndex.FindKey(i); anArray[i-1] = aMapIndex.FindKey(i);
}
if (myShapesOper->_is_nil()) { GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray);
myShapesOper = getGeomEngine()->GetIShapesOperations(getStudyId());
}
GEOM::ListOfGO_var aList = myShapesOper->MakeSubShapes(myObj, anArray); // Make compounds
const int aNbObj = aList->length(); for (int i = 0; i < pairs.count()/2; i++) {
GEOM::ListOfGO_var aPair = new GEOM::ListOfGO();
for (i = 0; i < aNbObj; i++) { aPair->length(2);
objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i])); aPair[0] = aList[ aMapIndex.FindIndex(pairs[i*2]) - 1 ];
aPair[1] = aList[ aMapIndex.FindIndex(pairs[i*2+1]) - 1 ];
GEOM::GEOM_Object_var aCompound = shapesOper->MakeCompound( aPair );
objects.push_back(aCompound._retn());
} }
return true; return true;

View File

@ -88,8 +88,6 @@ private:
QListWidget *myShapeList; QListWidget *myShapeList;
GEOM::GEOM_Object_var myObj; GEOM::GEOM_Object_var myObj;
GEOM::ListOfLong_var myInters; GEOM::ListOfLong_var myInters;
GEOM::GEOM_IShapesOperations_var myShapesOper;
}; };
#endif // MEASUREGUI_CHECKSELFINTERDLG_H #endif // MEASUREGUI_CHECKSELFINTERDLG_H