From 0a40f988ad3ec08e2d5975ff12ec01ee9bd40aba Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 13 Nov 2015 09:21:54 +0300 Subject: [PATCH] 0023197: [CEA] Extract and rebuild: GUI --- idl/GEOM_Gen.idl | 37 + resources/CMakeLists.txt | 1 + resources/extract.png | Bin 0 -> 1084 bytes src/GEOMGUI/GEOM_images.ts | 8 + src/GEOMGUI/GEOM_msg_en.ts | 75 + src/GEOMGUI/GeometryGUI.cxx | 4 + src/GEOMGUI/GeometryGUI_Operations.h | 1 + src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 17 + src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 34 + src/GEOM_I/GEOM_IShapesOperations_i.cc | 94 ++ src/GEOM_I/GEOM_IShapesOperations_i.hh | 5 + src/OperationGUI/CMakeLists.txt | 3 + src/OperationGUI/OperationGUI.cxx | 2 + .../OperationGUI_ExtractionDlg.cxx | 1322 +++++++++++++++++ src/OperationGUI/OperationGUI_ExtractionDlg.h | 115 ++ 15 files changed, 1718 insertions(+) create mode 100644 resources/extract.png create mode 100644 src/OperationGUI/OperationGUI_ExtractionDlg.cxx create mode 100644 src/OperationGUI/OperationGUI_ExtractionDlg.h diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 830fcc398..0c5a3a0b9 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2778,6 +2778,43 @@ module GEOM in comparison_condition theCondition, in double theTolerance); + /** + * This enumeration represents an extraction statistics type. It is used in + * the interface GEOM_IShapesOperations::MakeExtraction. + */ + enum ExtractionStatType + { + EST_Removed, ///< Removed sub-shapes + EST_Modified, ///< Modified sub-shapes + EST_Added ///< Newly created sub-shapes + }; + + /*! + * This structure defines a format of extraction statistics. It is used in + * the interface GEOM_IShapesOperations::MakeExtraction. + */ + struct ExtractionStat + { + ExtractionStatType type; ///< Type of extraction statistics. + ListOfLong indices; ///< Shape indices touched by this type of modification. + }; + + typedef sequence ExtractionStats; + + /*! + * \brief Return the shape that is constructed from theShape without + * extracted sub-shapes from the input list. + * + * \param theShape the original shape. + * \param theSubShapeIDs the list of sub-shape IDs to be extracted from + * the original shape. + * \param theStats the operation statistics. Output parameter. + * \return the shape without extracted sub-shapes. + */ + GEOM_Object MakeExtraction(in GEOM_Object theShape, + in ListOfLong theSubShapeIDs, + out ExtractionStats theStats); + }; // # GEOM_IBlocksOperations: diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 3d47d93ed..0aa42ed0b 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -94,6 +94,7 @@ SET( _res_files edgeextension.png erase.png eraseall.png + extract.png extruded_boss.png extruded_cut.png facetosurface.png diff --git a/resources/extract.png b/resources/extract.png new file mode 100644 index 0000000000000000000000000000000000000000..528fe308a45b25256eb4a6d9035120708837d3d7 GIT binary patch literal 1084 zcmV-C1jGA@P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZmH`cu1hGLF zAb>Cotgo;C5Aq7gYo9)SV)*>|GsCxU-@x7mc^?G!?Ag-{(tJ)&uhr<%B|{K9I5_zF z+O=y10Rjk{3ps#T0f<2g6`_1|@Z+qOR;%%~Yhc4-Vq&g?EZ?+glO#X@!Nc%QM#g`j zsSN-B{$=HKmfrF z1S$S0>(1~G7^c7e`~$}DUxu%sm<6)G|AHhPw#zfY;Rgy95CB>7=^IeZ*AEPgKu3T8 zKmfrF1ljTfXxrbv|KJ9G0~+%4_djs*`3}VYfoecO^7qRZu)&~+`1S20!|!h&7#N@i z0t67;Ku}Wo1vK#Y-~V9x8_X;qUJsK-WXO`Wc!YLB9I=k}=U0ZmKn%)i|Neqp`4i+Mu-Z3J13{^Q`Qa{@ zVIbQ+00a=+Ku`dG{qmXN_xDdg1A+7pkb&QT$p{!3|Na6K{2zG0e}H-qlx!|vz6{FK zpuBt^h_3?#5ZpjW0Kb98+DD*wzkICO_TRANSFER_DATA transfer_data.png + + ICO_EXTRACTION + extract.png + ICO_IMPORT_SHAPE import.png @@ -1407,6 +1411,10 @@ ICON_DLG_TRANSFER_DATA transfer_data.png + + ICON_DLG_EXTRACTION + extract.png + ICON_DLG_SCALE_ALONG_AXES scale_along_axes.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 2f225edbd..f24a3c424 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -471,6 +471,10 @@ Please, select face, shell or solid and try again GEOM_COMPOUNDSOLID CompSolid + + GEOM_COMPSOLIDS + CompSolids + GEOM_COMPOUND_TITLE Create A Compound @@ -607,6 +611,10 @@ Please, select face, shell or solid and try again GEOM_EDGE Edge + + GEOM_EDGES + Edges + GEOM_EDGE_TITLE Create An Edge @@ -2024,6 +2032,10 @@ Please, select face, shell or solid and try again GEOM_SOLID Solid + + GEOM_SOLIDS + Solids + GEOM_SOLID_TITLE Solid Construction @@ -5228,6 +5240,18 @@ Please, select face, shell or solid and try again STB_TRANSFER_DATA Transfer Data + + TOP_EXTRACTION + Extract and Rebuild + + + MEN_EXTRACTION + Extract and Rebuild + + + STB_EXTRACTION + Extract and Rebuild + TOP_EXTENSION Extend Edge or Face @@ -7621,4 +7645,55 @@ Do you want to create new material? Rotation angle + + OperationGUI_ExtractionDlg + + GEOM_EXTRACT_TITLE + Extract and Rebuild + + + GEOM_EXTRACT_TYPE + Extraction type + + + GEOM_EXTRACT_INPUT_PARAMS + Input parameters + + + GEOM_EXTRACT_STATISTICS + Statistics + + + GEOM_EXTRACT_SUB_SHAPE_TYPE + Sub-shape type + + + GEOM_EXTRACT_FILTERED_SHAPES + Filtered shapes + + + GEOM_EXTRACT_SHAPES_TO_EXTRACT + Shapes to extract + + + GEOM_EXTRACT_REBUILD + Rebuild + + + GEOM_EXTRACT_REMOVED + Removed + + + GEOM_EXTRACT_MODIFIED + Modified + + + GEOM_EXTRACT_ADDED + Added + + + GEOM_EXTRACT_NAME + Extraction + + diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 0d3f733a6..47aeffbf8 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -623,6 +623,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpExtrudedBoss: // MENU OPERATION - EXTRUDED BOSS case GEOMOp::OpExtrudedCut: // MENU OPERATION - EXTRUDED CUT case GEOMOp::OpTransferData: // MENU OPERATION - TRANSFER DATA + case GEOMOp::OpExtraction: // MENU OPERATION - EXTRACT AND REBUILD libName = "OperationGUI"; break; case GEOMOp::OpSewing: // MENU REPAIR - SEWING @@ -1005,6 +1006,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpShapesOnShape, "GET_SHAPES_ON_SHAPE" ); createGeomAction( GEOMOp::OpSharedShapes, "GET_SHARED_SHAPES" ); createGeomAction( GEOMOp::OpTransferData, "TRANSFER_DATA" ); + createGeomAction( GEOMOp::OpExtraction, "EXTRACTION" ); createGeomAction( GEOMOp::OpExtrudedCut, "EXTRUDED_CUT" ); createGeomAction( GEOMOp::OpExtrudedBoss, "EXTRUDED_BOSS" ); createGeomAction( GEOMOp::OpFillet1d, "FILLET_1D" ); @@ -1262,6 +1264,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpShapesOnShape, operId, -1 ); createMenu( GEOMOp::OpSharedShapes, operId, -1 ); createMenu( GEOMOp::OpTransferData, operId, -1 ); + createMenu( GEOMOp::OpExtraction, operId, -1 ); createMenu( separator(), operId, -1 ); @@ -1438,6 +1441,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpShapesOnShape, operTbId ); createTool( GEOMOp::OpSharedShapes, operTbId ); createTool( GEOMOp::OpTransferData, operTbId ); + createTool( GEOMOp::OpExtraction, operTbId ); int featTbId = createTool( tr( "TOOL_FEATURES" ), QString( "GEOMModification" ) ); createTool( GEOMOp::OpFillet1d, featTbId ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 480b7d2fd..a80c3d093 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -166,6 +166,7 @@ namespace GEOMOp { OpExtrudedBoss = 3709, // MENU OPERATION - ETRUDED BOSS OpExtrudedCut = 3710, // MENU OPERATION - ETRUDED CUT OpTransferData = 3711, // MENU OPERATION - TRANSFER DATA + OpExtraction = 3712, // MENU OPERATION - EXTRACT AND REBUILD // RepairGUI -------------------//-------------------------------- OpSewing = 4000, // MENU REPAIR - SEWING OpSuppressFaces = 4001, // MENU REPAIR - SUPPRESS FACES diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 3ed4513ec..11bd57a44 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -3162,6 +3162,23 @@ Handle(TColStd_HSequenceOfTransient) return aSeq; } +//============================================================================= +/*! + * MakeExtraction + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeExtraction + (const Handle(GEOM_Object) &theShape, + const Handle(TColStd_HArray1OfInteger) &theSubShapeIDs, + std::list &theStats) +{ + theStats.clear(); + + SetErrorCode(OK); + + return theShape; +} + //======================================================================= //function : getShapesOnSurfaceIDs /*! diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index d8e4f9fb2..38b375059 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -59,6 +59,25 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations All = Groups | Fields | SubShapes, }; + /** + * This enumeration represents an extraction statistics type. + */ + enum ExtractionStatType + { + EST_Removed, ///< Removed sub-shapes + EST_Modified, ///< Modified sub-shapes + EST_Added ///< Newly created sub-shapes + }; + + /*! + * This structure defines a format of extraction statistics. + */ + struct ExtractionStat + { + ExtractionStatType type; ///< Type of extraction statistics. + std::list indices; ///< Shape indices touched by this type of modification. + }; + Standard_EXPORT GEOMImpl_IShapesOperations(GEOM_Engine* theEngine, int theDocID); Standard_EXPORT ~GEOMImpl_IShapesOperations(); @@ -470,6 +489,21 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations const GEOMUtils::ComparisonCondition theCondition, const Standard_Real theTolerance); + /*! + * \brief Return the shape that is constructed from theShape without + * extracted sub-shapes from the input list. + * + * \param theShape the original shape. + * \param theSubShapeIDs the list of sub-shape IDs to be extracted from + * the original shape. + * \param theStats the operation statistics. Output parameter. + * \return the shape without extracted sub-shapes. + */ + Handle(GEOM_Object) MakeExtraction + (const Handle(GEOM_Object) &theShape, + const Handle(TColStd_HArray1OfInteger) &theSubShapeIDs, + std::list &theStats); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 7561d9a16..324401311 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -2230,3 +2230,97 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapesWithTolerance return aSeq._retn(); } + +//============================================================================= +/*! + * MakeExtraction + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeExtraction + (GEOM::GEOM_Object_ptr theShape, + const GEOM::ListOfLong &theSubShapeIDs, + GEOM::GEOM_IShapesOperations::ExtractionStats_out theStats) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference object + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (aShape.IsNull()) { + return aGEOMObject._retn(); + } + + const int aNbIDs = theSubShapeIDs.length(); + int i; + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, aNbIDs); + + for (i = 0; i < aNbIDs; i++) { + anArray->SetValue(i + 1, theSubShapeIDs[i]); + } + + //Get Shapes in place of aShapeWhat + std::list aStats; + Handle(GEOM_Object) aResult = + GetOperations()->MakeExtraction(aShape, anArray, aStats); + + if (!GetOperations()->IsDone() || aResult.IsNull()) { + return aGEOMObject._retn(); + } + + // Convert statistics. + GEOM::GEOM_IShapesOperations::ExtractionStats_var aResStats = + new GEOM::GEOM_IShapesOperations::ExtractionStats; + const int aNbStats = aStats.size(); + + aResStats->length(aNbStats); + + // fill the local CORBA array with values from lists + std::list::const_iterator + anIt = aStats.begin(); + + for (i = 0; anIt != aStats.end(); i++, anIt++) { + GEOM::GEOM_IShapesOperations::ExtractionStat_var aResStat = + new GEOM::GEOM_IShapesOperations::ExtractionStat; + + // Copy type + switch (anIt->type) { + case GEOMImpl_IShapesOperations::EST_Removed: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Removed; + break; + case GEOMImpl_IShapesOperations::EST_Modified: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Modified; + break; + case GEOMImpl_IShapesOperations::EST_Added: + aResStat->type = GEOM::GEOM_IShapesOperations::EST_Added; + break; + default: + break; + } + + // Copy the list of IDs + std::list aIDList = anIt->indices; + GEOM::ListOfLong_var aResIDList = new GEOM::ListOfLong; + + aResIDList->length(aIDList.size()); + + std::list::iterator anIDIt = aIDList.begin(); + int j = 0; + + for (; anIDIt != aIDList.end(); j++, anIDIt++) { + aResIDList[j] = *anIDIt; + } + + aResStat->indices = aResIDList; + + aResStats[i] = aResStat; + } + + // initialize out-parameter with local array + theStats = aResStats._retn(); + + return GetObject(aResult); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index 0f36a38c3..ff9e417f0 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -306,6 +306,11 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::comparison_condition theCondition, CORBA::Double theTolerance); + GEOM::GEOM_Object_ptr MakeExtraction + (GEOM::GEOM_Object_ptr theShape, + const GEOM::ListOfLong &theSubShapeIDs, + GEOM::GEOM_IShapesOperations::ExtractionStats_out theStats); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/OperationGUI/CMakeLists.txt b/src/OperationGUI/CMakeLists.txt index 4fa28ace0..b32dd2d0e 100755 --- a/src/OperationGUI/CMakeLists.txt +++ b/src/OperationGUI/CMakeLists.txt @@ -74,6 +74,7 @@ SET(OperationGUI_HEADERS OperationGUI_ChamferDlg.h OperationGUI_GetShapesOnShapeDlg.h OperationGUI_GetSharedShapesDlg.h + OperationGUI_ExtractionDlg.h OperationGUI_ExtrudedFeatureDlg.h OperationGUI_ClippingDlg.h OperationGUI_TransferDataDlg.h @@ -88,6 +89,7 @@ SET(_moc_HEADERS OperationGUI_ChamferDlg.h OperationGUI_GetShapesOnShapeDlg.h OperationGUI_GetSharedShapesDlg.h + OperationGUI_ExtractionDlg.h OperationGUI_ExtrudedFeatureDlg.h OperationGUI_ClippingDlg.h OperationGUI_TransferDataDlg.h @@ -110,6 +112,7 @@ SET(OperationGUI_SOURCES OperationGUI_FilletDlg.cxx OperationGUI_Fillet1d2dDlg.cxx OperationGUI_ChamferDlg.cxx + OperationGUI_ExtractionDlg.cxx OperationGUI_ExtrudedFeatureDlg.cxx OperationGUI_ClippingDlg.cxx OperationGUI_TransferDataDlg.cxx diff --git a/src/OperationGUI/OperationGUI.cxx b/src/OperationGUI/OperationGUI.cxx index 3288921ab..96e5fc57a 100644 --- a/src/OperationGUI/OperationGUI.cxx +++ b/src/OperationGUI/OperationGUI.cxx @@ -40,6 +40,7 @@ #include "OperationGUI_GetSharedShapesDlg.h" #include "OperationGUI_ExtrudedFeatureDlg.h" // Methods EXTRUDED BOSS / CUT #include "OperationGUI_TransferDataDlg.h" +#include "OperationGUI_ExtractionDlg.h" //======================================================================= // function : OperationGUI() @@ -83,6 +84,7 @@ bool OperationGUI::OnGUIEvent (int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpFillet1d: (new OperationGUI_Fillet1d2dDlg (getGeometryGUI(), parent, true))->show(); break; case GEOMOp::OpFillet2d: (new OperationGUI_Fillet1d2dDlg (getGeometryGUI(), parent, false))->show(); break; case GEOMOp::OpTransferData: (new OperationGUI_TransferDataDlg (getGeometryGUI(), parent))->show(); break; + case GEOMOp::OpExtraction: (new OperationGUI_ExtractionDlg (getGeometryGUI(), parent))->show(); break; default: app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); } diff --git a/src/OperationGUI/OperationGUI_ExtractionDlg.cxx b/src/OperationGUI/OperationGUI_ExtractionDlg.cxx new file mode 100644 index 000000000..6885ff728 --- /dev/null +++ b/src/OperationGUI/OperationGUI_ExtractionDlg.cxx @@ -0,0 +1,1322 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "OperationGUI_ExtractionDlg.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x050300 + #include +#else + /** + * This class is named as QT class as it is introduced since Qt 5.3. + * It should not be compiled when Salome is ported on Qt 5.3. + */ + class QSignalBlocker + { + public: + QSignalBlocker(QObject *object) + : myObject (object), + myIsBlocked (object && object->signalsBlocked()) { + if (myObject) { + myObject->blockSignals(true); + } + } + + ~QSignalBlocker() { + if (myObject) { + myObject->blockSignals(myIsBlocked); + } + } + + private: + QObject *myObject; ///< Blocked object. + bool myIsBlocked; ///< Initial blocked state. + }; +#endif + + +#define ID_ROLE Qt::DisplayRole +#define TYPE_ROLE Qt::UserRole + +static const char* const TMP_STR = "TEMP"; + +static const char* const SINGLE_SHAPE_TYPE_TR_CODES [] = { + "GEOM_COMPOUND", + "GEOM_COMPOUNDSOLID", + "GEOM_SOLID", + "GEOM_SHELL", + "GEOM_FACE", + "GEOM_WIRE", + "GEOM_EDGE", + "GEOM_VERTEX" +}; + +static const char* const PLURAL_SHAPE_TYPE_TR_CODES [] = { + "GEOM_COMPOUND", // Not used + "GEOM_COMPSOLIDS", + "GEOM_SOLIDS", + "GEOM_SHELLS", + "GEOM_FACES", + "GEOM_WIREZ", + "GEOM_EDGES", + "GEOM_VERTEXES" +}; + + +/** + * This static function creates a new list widget item with given ID and + * returns it. + * + * \param theID the item ID. + * \param theListWidget the list widget. + * \return the created list widget item. + */ +static QListWidgetItem *addNewItem(const int theID, + QListWidget *theListWidget) +{ + QListWidgetItem *aResult = new QListWidgetItem; + + aResult->setData(ID_ROLE, theID); + theListWidget->addItem(aResult); + + return aResult; +} + +/** + * This static function creates a new tree widget item as a child of the input + * one with given ID and returns it. + * + * \param theID the item ID. + * \param theParentItem the parent item. + * \return the created tree widget item. + */ +static QTreeWidgetItem *addChildItem(const int theID, + QTreeWidgetItem *theParentItem) +{ + QTreeWidgetItem *aResult = new QTreeWidgetItem; + + aResult->setData(0, ID_ROLE, theID); + theParentItem->addChild(aResult); + + return aResult; +} + +/** + * This static function returns the maximal shape type of sub-shapes stored in + * the input compound. If it is not a compound, it returns TopAbs_SHAPE. + * + * \param theCompound the compound. + * \return the maximal shape type of sub-shapes stored in the input compound. + */ +static TopAbs_ShapeEnum GetMaxShapeTypeInComp(const TopoDS_Shape &theCompound) +{ + TopAbs_ShapeEnum aResult = TopAbs_SHAPE; + + if (theCompound.IsNull() || theCompound.ShapeType() != TopAbs_COMPOUND) { + return aResult; + } + + TopoDS_Iterator anIt(theCompound, Standard_False, Standard_False); + + for (; anIt.More(); anIt.Next()) { + const TopoDS_Shape &aSubShape = anIt.Value(); + + if (aSubShape.IsNull()) { + continue; + } + + // Get the sub-shape type. + TopAbs_ShapeEnum aSubType = aSubShape.ShapeType(); + + if (aSubType == TopAbs_COMPOUND) { + aSubType = GetMaxShapeTypeInComp(aSubShape); + } + + if (aSubType == TopAbs_SHAPE) { + continue; + } + + if (aResult == TopAbs_SHAPE) { + // This is an initialization. + aResult = aSubType; + } else if (aResult > aSubType) { + aResult = aSubType; + } + } + + return aResult; +} + +//================================================================================= +// class : OperationGUI_ExtractionDlg() +// purpose : +//================================================================================= +OperationGUI_ExtractionDlg::OperationGUI_ExtractionDlg + (GeometryGUI* GUI, QWidget* parent) + : GEOMBase_Skeleton (GUI, parent, false), + mySelBtn (0), + myMainShapeEdit (0), + mySubShTypeCompo (0), + myFilteredList (0), + myExtractedTree (0), + myRemovedList (0), + myModifiedList (0), + myAddedList (0), + myRebuildBtn (0), + myIsHiddenMain (false) +{ + QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap( + "GEOM", tr("ICON_DLG_EXTRACTION"))); + QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap( + "GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_EXTRACT_TITLE")); + + /***************************************************************/ + + mainFrame()->GroupConstructors->setTitle(tr("GEOM_EXTRACT_TYPE")); + mainFrame()->RadioButton1->setIcon( image0 ); + mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); + + // Create an input group. + QGroupBox *anInputGrp = new QGroupBox(tr("GEOM_EXTRACT_INPUT_PARAMS"), centralWidget()); + QGridLayout *anInputLayout = new QGridLayout(anInputGrp); + QHBoxLayout *aShapeLayout = new QHBoxLayout(anInputGrp); + QVBoxLayout *aViewBtnsLayout = new QVBoxLayout(anInputGrp); + QVBoxLayout *aMoveBtnsLayout = new QVBoxLayout(anInputGrp); + QLabel *aMainObjLbl = new QLabel(tr("GEOM_MAIN_OBJECT"), anInputGrp); + QLabel *aSubShTypeLbl = new QLabel(tr("GEOM_EXTRACT_SUB_SHAPE_TYPE"), anInputGrp); + QLabel *aFilteredLbl = new QLabel(tr("GEOM_EXTRACT_FILTERED_SHAPES"), anInputGrp); + QLabel *anExtractedLbl = new QLabel(tr("GEOM_EXTRACT_SHAPES_TO_EXTRACT"), anInputGrp); + QPushButton *aShowOnlySelBtn = new QPushButton(tr("SHOW_ONLY_SELECTED"), anInputGrp); + QPushButton *aHideSelBtn = new QPushButton(tr("HIDE_SELECTED"), anInputGrp); + QPushButton *aShowAllBtn = new QPushButton(tr("SHOW_ALL_SUB_SHAPES"), anInputGrp); + QPushButton *anAddBtn = new QPushButton(">>", anInputGrp); + QPushButton *aRemoveBtn = new QPushButton("<<", anInputGrp); + + myRebuildBtn = new QPushButton(tr("GEOM_EXTRACT_REBUILD"), anInputGrp); + mySelBtn = new QPushButton(anInputGrp); + myMainShapeEdit = new QLineEdit(anInputGrp); + mySubShTypeCompo = new QComboBox(anInputGrp); + myFilteredList = new QListWidget(anInputGrp); + myExtractedTree = new QTreeWidget(anInputGrp); + mySelBtn->setIcon(image1); + myMainShapeEdit->setReadOnly(true); + + aShapeLayout->addWidget(mySelBtn); + aShapeLayout->addWidget(myMainShapeEdit); + + aViewBtnsLayout->addStretch(); + aViewBtnsLayout->addWidget(aShowOnlySelBtn); + aViewBtnsLayout->addWidget(aHideSelBtn); + aViewBtnsLayout->addWidget(aShowAllBtn); + aViewBtnsLayout->addStretch(); + + aMoveBtnsLayout->addStretch(); + aMoveBtnsLayout->addWidget(anAddBtn); + aMoveBtnsLayout->addWidget(aRemoveBtn); + aMoveBtnsLayout->addStretch(); + + anInputLayout->setSpacing(6); + anInputLayout->setContentsMargins(9, 9, 9, 9); + anInputLayout->addWidget(aMainObjLbl, 0, 0); + anInputLayout->addLayout(aShapeLayout, 0, 1, 1, 3); + anInputLayout->addWidget(aSubShTypeLbl, 1, 0); + anInputLayout->addWidget(mySubShTypeCompo, 1, 1, 1, 3); + anInputLayout->addWidget(aFilteredLbl, 2, 1); + anInputLayout->addWidget(anExtractedLbl, 2, 3); + anInputLayout->addLayout(aViewBtnsLayout, 3, 0); + anInputLayout->addWidget(myFilteredList, 3, 1); + anInputLayout->addLayout(aMoveBtnsLayout, 3, 2); + anInputLayout->addWidget(myExtractedTree, 3, 3); + anInputLayout->addWidget(myRebuildBtn, 4, 0, 1, 4); + + // Create a statistics group. + QGroupBox *aStatGrp = new QGroupBox(tr("GEOM_EXTRACT_STATISTICS"), centralWidget()); + QGridLayout *aStatLayout = new QGridLayout(aStatGrp); + QLabel *aRemovedLbl = new QLabel(tr("GEOM_EXTRACT_REMOVED"), aStatGrp); + QLabel *aModifiedLbl = new QLabel(tr("GEOM_EXTRACT_MODIFIED"), aStatGrp); + QLabel *anAddedLbl = new QLabel(tr("GEOM_EXTRACT_ADDED"), aStatGrp); + + myRemovedList = new QListWidget(aStatGrp); + myModifiedList = new QListWidget(aStatGrp); + myAddedList = new QListWidget(aStatGrp); + + aStatLayout->setSpacing(6); + aStatLayout->setContentsMargins(9, 9, 9, 9); + aStatLayout->addWidget(aRemovedLbl, 0, 0); + aStatLayout->addWidget(aModifiedLbl, 0, 1); + aStatLayout->addWidget(anAddedLbl, 0, 2); + aStatLayout->addWidget(myRemovedList, 1, 0); + aStatLayout->addWidget(myModifiedList, 1, 1); + aStatLayout->addWidget(myAddedList, 1, 2); + + // Create a main layout. + QVBoxLayout* aLayout = new QVBoxLayout(centralWidget()); + + aLayout->setMargin(0); + aLayout->setSpacing(6); + aLayout->addWidget(anInputGrp); + aLayout->addWidget(aStatGrp); + + // signals and slots connections + connect(anAddBtn, SIGNAL(clicked()), this, SLOT(onAddExtracted())); + connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveExtracted())); + connect(aShowOnlySelBtn, SIGNAL(clicked()), this, SLOT(showOnlySelected())); + connect(aHideSelBtn, SIGNAL(clicked()), this, SLOT(hideSelected())); + connect(aShowAllBtn, SIGNAL(clicked()), this, SLOT(showAllSelected())); + + /***************************************************************/ + myHelpFileName = "extract_and_rebuild_page.html"; + + /* Initialisation */ + Init(); +} + +//================================================================================= +// function : ~OperationGUI_ExtractionDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +OperationGUI_ExtractionDlg::~OperationGUI_ExtractionDlg() +{ + restoreViewer(); +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::Init() +{ + mySelBtn->setCheckable(true); + mySelBtn->setChecked(true); + myFilteredList->setSelectionMode(QAbstractItemView::ExtendedSelection); + myFilteredList->setSortingEnabled(true); + myExtractedTree->setHeaderHidden(true); + myExtractedTree->setSelectionMode(QAbstractItemView::ExtendedSelection); + myExtractedTree->setColumnCount(1); + myRebuildBtn->setEnabled(false); + myRemovedList->setSelectionMode(QAbstractItemView::NoSelection); + myModifiedList->setSelectionMode(QAbstractItemView::NoSelection); + myAddedList->setSelectionMode(QAbstractItemView::NoSelection); + + // Fill in the extracted tree with initial elements. + myTopItems[0] = 0; // No need to create a item for compound. + + int i; + + for (i = 1; i < 8; i++) { + myTopItems[i] = new QTreeWidgetItem; + myTopItems[i]->setText(0, tr(PLURAL_SHAPE_TYPE_TR_CODES[i])); + myTopItems[i]->setData(0, TYPE_ROLE, i); + + myExtractedTree->addTopLevelItem(myTopItems[i]); + myTopItems[i]->setHidden(true); + } + + // signals and slots connections + connect(mySelBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(mySubShTypeCompo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onShapeTypeChanged())); + connect(myRebuildBtn, SIGNAL(clicked()), this, SLOT(onRebuild())); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + connect(myFilteredList, SIGNAL(itemSelectionChanged()), + this, SLOT(onListSelectionChanged())); + connect(myExtractedTree, SIGNAL(itemSelectionChanged()), + this, SLOT(onListSelectionChanged())); + + initName(tr("GEOM_EXTRACT_NAME")); + + activateSelection(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : updateSubShTypeCompo() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::updateSubShTypeCompo() +{ + bool isValid = true; + int anIStart = TopAbs_COMPOUND; + const int anIEnd = TopAbs_VERTEX; + TopoDS_Shape aShape; + + if (GEOMBase::GetShape(myObj, aShape)) { + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + + if (aType == TopAbs_COMPOUND) { + anIStart = GetMaxShapeTypeInComp(aShape); + isValid = anIStart != TopAbs_SHAPE; + } else { + anIStart = aType + 1; + } + } + + QSignalBlocker aBlocker(mySubShTypeCompo); + mySubShTypeCompo->clear(); + + if (isValid) { + int i; + + for (i = anIStart; i <= anIEnd; i++) { + mySubShTypeCompo->addItem(tr(SINGLE_SHAPE_TYPE_TR_CODES[i]), i); + } + + updateFilteredList(); + } + + return isValid; +} + +//================================================================================= +// function : updateFilteredList() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::updateFilteredList() +{ + TopoDS_Shape aShape; + QSignalBlocker aBlocker(myFilteredList); + + myFilteredList->clear(); + + if (GEOMBase::GetShape(myObj, aShape)) { + const TopAbs_ShapeEnum aType = (TopAbs_ShapeEnum) + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + TopExp_Explorer anExp(aShape, aType); + + if (anExp.More()) { + TopTools_MapOfShape aMapFence; + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (!aSubShape.IsNull() && aMapFence.Add(aSubShape)) { + int anIndex = myIndices.FindIndex(aSubShape); + + if (!myMapExtractedIDs.Contains(anIndex)) { + addNewItem(anIndex, myFilteredList); + } + } + } + } + } +} + +//================================================================================= +// function : resetBuildData() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::resetBuildData(const bool isEnableBuild) +{ + // Clear result data. + myRemovedList->clear(); + myModifiedList->clear(); + myAddedList->clear(); + myRebuildBtn->setEnabled(isEnableBuild); +} + +//================================================================================= +// function : isEmptyExtracted() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::isEmptyExtracted() +{ + bool isEmpty = true; + int i; + + // Check if there are sub-shapes to be extracted. + for (i = 1; i < 8; i++) { + if (!myTopItems[i]->isHidden()) { + isEmpty = false; + + break; + } + } + + return isEmpty; +} + +//================================================================================= +// function : selectMainShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::selectMainShape() +{ + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + + aSelMgr->selectedObjects(aSelList); + + if (aSelList.Extent() == 1) { + GEOM::GEOM_Object_var aSelObject = + GEOMBase::ConvertIOinGEOMObject(aSelList.First()); + TopoDS_Shape aSelShape; + + if (GEOMBase::GetShape(aSelObject, aSelShape)) { + const TopAbs_ShapeEnum aType = aSelShape.ShapeType(); + + // Skip verices. + if (aType != TopAbs_VERTEX) { + myObj = aSelObject; + + // Initialize map of indices. Note that myIndices should be empty. + TopExp::MapShapes(aSelShape, myIndices); + } + } + } + + if (!updateSubShTypeCompo()) { + // Invalid selected object. + myObj = GEOM::GEOM_Object::_nil(); + } + + if (!CORBA::is_nil(myObj)) { + mySelBtn->setChecked(false); + myMainShapeEdit->setEnabled(false); + myMainShapeEdit->setText(GEOMBase::GetName(myObj)); + + // Hide the main object from the viewer. + SALOME_View* aView = GEOM_Displayer::GetActiveView(); + + if (aView) { + CORBA::String_var aMainEntry = myObj->GetStudyEntry(); + Handle(SALOME_InteractiveObject) anIO = createIO(aMainEntry.in()); + + if (aView->isVisible(anIO)) { + GEOM_Displayer *aDisplayer = getDisplayer(); + + aDisplayer->Erase(myObj, false, true); + myIsHiddenMain = true; + } + } + } +} + +//================================================================================= +// function : selectSubShapes +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::selectSubShapes() +{ + QSignalBlocker aBlocker(myFilteredList); + + // Clear current selection. + myFilteredList->clearSelection(); + + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + const int aCurType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + + aSelMgr->selectedObjects(aSelList); + + // try to find out and process the global selection + // (of not published objects and of published sub-shapes) + SALOME_ListIteratorOfListIO anIter(aSelList); + + for (; anIter.More(); anIter.Next()) { + Handle(SALOME_InteractiveObject) anIObj = anIter.Value(); + QString anEntry = anIObj->getEntry(); + QStringList aParts = anEntry.split("_"); + int aSubShapeId = -1; + + if (!aParts.isEmpty()) { + if (aParts.first() == TMP_STR) { + bool isOk = false; + const int anIndex = aParts.last().toInt(&isOk); + + if (isOk && anIndex > 0) { + // This is a sub-shape. + aSubShapeId = anIndex; + } + } + } + + if (aSubShapeId < 0) { + // This is a published shape. + GEOM::GEOM_Object_var aSelObject = + GEOMBase::ConvertIOinGEOMObject(anIObj); + TopoDS_Shape aSelShape; + + if (GEOMBase::GetShape(aSelObject, aSelShape)) { + + if (aSelShape.ShapeType() == aCurType) { + const int anIndex = myIndices.FindIndex(aSelShape); + + if (anIndex > 0) { + // This is a sub-shape. Select it in the filtered list. + aSubShapeId = anIndex; + } + } + } + } + + // Select a list widget item by Id. + if (aSubShapeId > 0) { + QString anIdText = QString("%1").arg(aSubShapeId); + QList aFound = + myFilteredList->findItems(anIdText, Qt::MatchExactly); + + foreach (QListWidgetItem *anItem, aFound) { + anItem->setSelected(true); + } + } + } +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::ClickOnOk() +{ + if (ClickOnApply()) { + ClickOnCancel(); + } +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::ClickOnApply() +{ + if (!onAccept()) { + return false; + } + + initName(); + + return true; +} + +//================================================================================= +// function : onShapeTypeChanged +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onShapeTypeChanged() +{ + updateFilteredList(); + eraseAll(); +} + +//================================================================================= +// function : onAddExtracted +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onAddExtracted() +{ + QList aListSelected = myFilteredList->selectedItems(); + + if (aListSelected.empty()) { + return; + } + + const int aShapeType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + bool isTreeUpdated = false; + + foreach (QListWidgetItem *anItem, aListSelected) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (myMapExtractedIDs.Add(anIndex)) { + addChildItem(anIndex, myTopItems[aShapeType]); + isTreeUpdated = true; + } + + // Remove anItem from the list. + myFilteredList->removeItemWidget(anItem); + delete anItem; + } + + if (isTreeUpdated) { + myTopItems[aShapeType]->sortChildren(0, Qt::AscendingOrder); + + // Reset build data + resetBuildData(true); + } + + myFilteredList->clearSelection(); + myTopItems[aShapeType]->setHidden(false); +} + +//================================================================================= +// function : onRemoveExtracted +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onRemoveExtracted() +{ + QList aListSelected = myExtractedTree->selectedItems(); + + if (aListSelected.empty()) { + return; + } + + const int aShapeType = + mySubShTypeCompo->itemData(mySubShTypeCompo->currentIndex()).toInt(); + QSet aSetFence; + bool isTreeUpdated = false; + + foreach (QTreeWidgetItem *anItem, aListSelected) { + if (!aSetFence.contains(anItem)) { + aSetFence.insert(anItem); + + QTreeWidgetItem *aParent = anItem->parent(); + + if (aParent) { + const int anIndex = anItem->data(0, ID_ROLE).toInt(); + // This is a ID item. Remove the ID from myMapExtractedIDs. + if (myMapExtractedIDs.Remove(anIndex)) { + // The item is not removed yet. Get parent index. + const int aParentIndex = aParent->data(0, TYPE_ROLE).toInt(); + + if (aShapeType == aParentIndex) { + // Create an item in the filtered list. + addNewItem(anIndex, myFilteredList); + } + + aParent->removeChild(anItem); + delete anItem; + isTreeUpdated = true; + + // Hilde an empty parent item. + if (aParent->childCount() == 0) { + aParent->setHidden(true); + } + } + } else { + // This is a top level item. Remove all its children. + QList aChildItems = anItem->takeChildren(); + const int anIndex = anItem->data(0, TYPE_ROLE).toInt(); + + // Remove IDs from myMapExtractedIDs. + foreach (QTreeWidgetItem *aChild, aChildItems) { + if (!aSetFence.contains(aChild)) { + aSetFence.insert(aChild); + + const int aChildIndex = aChild->data(0, ID_ROLE).toInt(); + + if (myMapExtractedIDs.Remove(aChildIndex)) { + if (aShapeType == anIndex) { + // Create items in the filtered list. + addNewItem(aChildIndex, myFilteredList); + } + + delete aChild; + isTreeUpdated = true; + } + } + } + + // Hilde an empty item. + anItem->setHidden(true); + } + } + } + + myExtractedTree->clearSelection(); + + if (isTreeUpdated) { + // Reset build data + const bool isEnableRebuild = !isEmptyExtracted(); + + resetBuildData(isEnableRebuild); + } +} + +//================================================================================= +// function : onListSelectionChanged +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onListSelectionChanged() +{ + SALOME_ListIO anIOList; + QList aListSel = myFilteredList->selectedItems(); + QList aTreeSel = myExtractedTree->selectedItems(); + + // Collect selected items from myFilteredList + foreach (QListWidgetItem *anItem, aListSel) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (myMapDisplayedIDs.Contains(anIndex)) { + // Collect only displayed sub-shapes for selection in the viewer. + QString anEntry = getSubShapeEntry(anIndex); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + anIOList.Append(anIO); + } + } + + // Collect selected items from myExtractedTree + foreach (QTreeWidgetItem *anItem, aTreeSel) { + if (anItem->parent()) { + // This is a ID item. + const int anIndex = anItem->data(0, ID_ROLE).toInt(); + + if (myMapDisplayedIDs.Contains(anIndex)) { + // Collect only displayed sub-shapes for selection in the viewer. + QString anEntry = getSubShapeEntry(anIndex); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + anIOList.Append(anIO); + } + } + } + + // Select object in viewer. + LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr(); + + aSelMgr->setSelectedObjects(anIOList); +} + +//================================================================================= +// function : showOnlySelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::showOnlySelected() +{ + TColStd_MapOfInteger aMapIDsSelected; + TColStd_MapOfInteger aMapIDsToDisplay; + const int aNbItems = myFilteredList->count(); + int i; + QSet aSelEntry; + + // Get sub-shape IDs to be displayed. + for (i = 0; i < aNbItems; ++i) { + QListWidgetItem *anItem = myFilteredList->item(i); + const int anIndex = anItem->data(ID_ROLE).toInt(); + + if (anItem->isSelected()) { + aMapIDsSelected.Add(anIndex); + aSelEntry.insert(getSubShapeEntry(anIndex)); + + if (!myMapDisplayedIDs.Contains(anIndex)) { + aMapIDsToDisplay.Add(anIndex); + } + } + } + + // Get sub-shape IDs to be erased. + TColStd_MapOfInteger aMapIDsToHide; + TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs); + + for (; anIter.More(); anIter.Next()) { + const int anIndex = anIter.Key(); + + if (!aMapIDsSelected.Contains(anIndex)) { + aMapIDsToHide.Add(anIndex); + } + } + + // Display sub-shapes. + for (anIter.Initialize(aMapIDsToDisplay); anIter.More(); anIter.Next()) { + displaySubShape(anIter.Key()); + } + + // Hide sub-shapes. + for (anIter.Initialize(aMapIDsToHide); anIter.More(); anIter.Next()) { + eraseSubShape(anIter.Key()); + } + + // Hide all objects except already displayed sub-shapes. + SALOME_ListIO aDisplayed; + SALOME_View *aView = GEOM_Displayer::GetActiveView(); + + if (aView) { + aView->GetVisible(aDisplayed); + } + + SALOME_ListIteratorOfListIO aDispIt(aDisplayed); + GEOM_Displayer *aDisplayer = getDisplayer(); + + for (; aDispIt.More(); aDispIt.Next()) { + Handle(SALOME_InteractiveObject) anIO = aDispIt.Value(); + + if (!aSelEntry.contains(anIO->getEntry())) { + aDisplayer->Erase(anIO, false, false); + } + } + + onListSelectionChanged(); + aDisplayer->UpdateViewer(); +} + +//================================================================================= +// function : hideSelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::hideSelected() +{ + QList aListSelected = myFilteredList->selectedItems(); + + foreach (QListWidgetItem *anItem, aListSelected) { + const int anIndex = anItem->data(ID_ROLE).toInt(); + + eraseSubShape(anIndex); + } + + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : showAllSelected +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::showAllSelected() +{ + const int aNbItems = myFilteredList->count(); + int i; + + for (i = 0; i < aNbItems; ++i) { + QListWidgetItem *anItem = myFilteredList->item(i); + const int anIndex = anItem->data(ID_ROLE).toInt(); + + displaySubShape(anIndex); + } + + onListSelectionChanged(); + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : onRebuild +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::onRebuild() +{ + GEOM::GEOM_Object_var aResShape; + GEOM::GEOM_IShapesOperations::ExtractionStats aStats; + + if (!getResult(aResShape.out(), aStats)) { + resetBuildData(false); + return; + } + + TopoDS_Shape anOldShape; + TopoDS_Shape aNewShape; + TopTools_IndexedMapOfShape aNewIndices; + + if (!GEOMBase::GetShape(aResShape, aNewShape)) { + resetBuildData(false); + return; + } + + TopExp::MapShapes(aNewShape, aNewIndices); + + const int aNbStat = aStats.length(); + int i; + + for (i = 0; i < aNbStat; ++i) { + // Compute number of sub-shapes of each type. + const int aNbSubShapes = aStats[i].indices.length(); + int aNbShapes [] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int j; + + TopTools_IndexedMapOfShape *aMapShapes = + (aStats[i].type == GEOM::GEOM_IShapesOperations::EST_Added) ? + &aNewIndices : &myIndices; + + for (j = 0; j < aNbSubShapes; ++j) { + const int anIndex = aStats[i].indices[j]; + + if (anIndex < 1 || anIndex > aMapShapes->Extent()) { + resetBuildData(false); + return; + } + + const TopoDS_Shape &aSubShape = aMapShapes->FindKey(anIndex); + + aNbShapes[aSubShape.ShapeType()]++; + } + + // Fill the statistics. + QListWidget *aListWidget = 0; + + switch (aStats[i].type) { + case GEOM::GEOM_IShapesOperations::EST_Removed: + aListWidget = myRemovedList; + break; + case GEOM::GEOM_IShapesOperations::EST_Modified: + aListWidget = myModifiedList; + break; + case GEOM::GEOM_IShapesOperations::EST_Added: + aListWidget = myAddedList; + break; + default: + resetBuildData(false); + return; + } + + QStringList aStrList; + + for (j = 1; j < 8; ++j) { + if (aNbShapes[j] >= 1) { + const char *aShapeType = aNbShapes[j] == 1 ? + SINGLE_SHAPE_TYPE_TR_CODES[j] : PLURAL_SHAPE_TYPE_TR_CODES[j]; + + aStrList.append(QString("%1 %2").arg(aNbShapes[j]).arg(tr(aShapeType))); + } + } + + aListWidget->addItems(aStrList); + } + + myRebuildBtn->setEnabled(false); +} + +//================================================================================= +// function : SelectionIntoArgument +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::SelectionIntoArgument() +{ + if (myMainShapeEdit->isEnabled()) { + // Selection of main object + selectMainShape(); + } else { + // Selection of filtered shapes + selectSubShapes(); + } +} + +//================================================================================= +// function : SetEditCurrentArgument +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::SetEditCurrentArgument() +{ + QSignalBlocker aBlockerList(myFilteredList); + QSignalBlocker aBlockerTree(myExtractedTree); + + restoreViewer(); + myObj = GEOM::GEOM_Object::_nil(); + myMainShapeEdit->setEnabled(true); + myMainShapeEdit->setText(""); + myMainShapeEdit->setFocus(); + + updateSubShTypeCompo(); + + myFilteredList->clear(); + myRemovedList->clear(); + myModifiedList->clear(); + myAddedList->clear(); + myIndices.Clear(); + + // Clear myExtractedTree. + int i; + + for (i = 1; i < 8; i++) { + QList aListItems = myTopItems[i]->takeChildren(); + + foreach (QTreeWidgetItem *anItem, aListItems) { + delete anItem; + } + + myTopItems[i]->setHidden(true); + } + + myExtractedTree->clearSelection(); + + myMapExtractedIDs.Clear(); + + // Update viewer + eraseAll(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + + LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); + + if (aSel) { + connect(aSel, SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + } + + activateSelection(); +} + +//================================================================================= +// function : activateSelection +// purpose : activate selection of all shapes +//================================================================================= +void OperationGUI_ExtractionDlg::activateSelection() +{ + globalSelection(GEOM_ALLSHAPES); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::enterEvent(QEvent *) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) { + ActivateThisDialog(); + } +} + +//================================================================================= +// function : getResult +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::getResult + (GEOM::GEOM_Object_ptr &theResult, + GEOM::GEOM_IShapesOperations::ExtractionStats &theStats) +{ + if (myObj->_is_nil()) { + return false; + } + + // Get IDs of extracted shapes. + int i; + int aNbShapes = 0; + + for (i = 1; i < 8; i++) { + aNbShapes += myTopItems[i]->childCount(); + } + + if (aNbShapes == 0) { + return false; + } + + GEOM::ListOfLong_var aSubShapeIDs = new GEOM::ListOfLong; + int j; + int jCur; + + aSubShapeIDs->length(aNbShapes); + + for (jCur = 0, i = 1; i < 8; ++i) { + aNbShapes = myTopItems[i]->childCount(); + + for (j = 0; j < aNbShapes; ++j, ++jCur) { + aSubShapeIDs[jCur] = myTopItems[i]->child(j)->data(0, ID_ROLE).toInt(); + } + } + + GEOM::GEOM_IShapesOperations_var anOper = + GEOM::GEOM_IShapesOperations::_narrow(getOperation()); + + try { + GEOM::GEOM_Object_var anObj; + GEOM::GEOM_IShapesOperations::ExtractionStats_var aStats; + + anObj = anOper->MakeExtraction(myObj, aSubShapeIDs, aStats); + + if (anOper->IsDone() && aStats->length() > 0) { + theStats = aStats; + } + + if (!CORBA::is_nil(anObj)) { + theResult = anObj._retn(); + } + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + return false; + } + + return anOper->IsDone(); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::isValid(QString &) +{ + bool isOk = !myObj->_is_nil() && !isEmptyExtracted(); + + return isOk; +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr OperationGUI_ExtractionDlg::createOperation() +{ + return getGeomEngine()->GetIShapesOperations(getStudyId()); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool OperationGUI_ExtractionDlg::execute(ObjectList &objects) +{ + GEOM::GEOM_Object_var aResShape; + GEOM::GEOM_IShapesOperations::ExtractionStats aStats; + + if (!getResult(aResShape.out(), aStats)) { + return false; + } + + if (!aResShape->_is_nil()) { + objects.push_back(aResShape._retn()); + } + + return true; +} + +//================================================================================= +// function : getSubShapeEntry +// purpose : +//================================================================================= +QString OperationGUI_ExtractionDlg::getSubShapeEntry(const int theId) +{ + CORBA::String_var aMainEntry = myObj->GetStudyEntry(); + QString anEntry = QString("%1_").arg(TMP_STR) + + aMainEntry.in() + QString("_%1").arg(theId); + + return anEntry; +} + +//================================================================================= +// function : createIO +// purpose : +//================================================================================= +Handle_SALOME_InteractiveObject OperationGUI_ExtractionDlg::createIO + (const char *theEntry) +{ + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject + (theEntry, "GEOM", "TEMP_IO"); + + return anIO; +} + +//================================================================================= +// function : displaySubShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::displaySubShape(const int theId) +{ + if (theId < 1 || theId > myIndices.Extent()) { + return; + } + + // Create a presentation + const TopoDS_Shape &aSubShape = myIndices.FindKey(theId); + QString anEntry = getSubShapeEntry(theId); + SALOME_View *aView = GEOM_Displayer::GetActiveView(); + GEOM_Displayer *aDisplayer = getDisplayer(); + SALOME_Prs *aPrs = aDisplayer->buildSubshapePresentation + (aSubShape, anEntry, aView); + + if (aPrs) { + if (aView) { + aView->Display(aDisplayer, aPrs); + } + + delete aPrs; + + myMapDisplayedIDs.Add(theId); + } +} + +//================================================================================= +// function : eraseSubShape +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::eraseSubShape(const int theId) +{ + QString anEntry = getSubShapeEntry(theId); + Handle(SALOME_InteractiveObject) anIO = + createIO(anEntry.toLatin1().data()); + + getDisplayer()->Erase(anIO, false, false); + myMapDisplayedIDs.Remove(theId); +} + +//================================================================================= +// function : eraseAll +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::eraseAll() +{ + TColStd_MapIteratorOfMapOfInteger anIter(myMapDisplayedIDs); + + for (; anIter.More(); anIter.Next()) { + eraseSubShape(anIter.Key()); + } + + myMapDisplayedIDs.Clear(); + getDisplayer()->UpdateViewer(); +} + +//================================================================================= +// function : restoreViewer +// purpose : +//================================================================================= +void OperationGUI_ExtractionDlg::restoreViewer() +{ + if (!CORBA::is_nil(myObj)) { + if (myIsHiddenMain) { + getDisplayer()->Display(myObj, false); + myIsHiddenMain = false; + } + + eraseAll(); + } +} diff --git a/src/OperationGUI/OperationGUI_ExtractionDlg.h b/src/OperationGUI/OperationGUI_ExtractionDlg.h new file mode 100644 index 000000000..f10592aa5 --- /dev/null +++ b/src/OperationGUI/OperationGUI_ExtractionDlg.h @@ -0,0 +1,115 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef OPERATIONGUI_EXTRACTIONDLG_H +#define OPERATIONGUI_EXTRACTIONDLG_H + +#include + +#include +#include + +class QComboBox; +class QListWidget; +class QTreeWidget; +class QTreeWidgetItem; + + +//================================================================================= +// class : OperationGUI_ExtractionDlg +// purpose : +//================================================================================= +class OperationGUI_ExtractionDlg : public GEOMBase_Skeleton +{ + + Q_OBJECT + +public: + + OperationGUI_ExtractionDlg( GeometryGUI*, QWidget* ); + ~OperationGUI_ExtractionDlg(); + +protected: + + // redefined from GEOMBase_Helper and MeasureGUI_Skeleton + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool execute(ObjectList &); + virtual void activateSelection(); + virtual bool isValid( QString& ); + +private slots: + + void SelectionIntoArgument(); + void ClickOnOk(); + bool ClickOnApply(); + void onShapeTypeChanged(); + void onAddExtracted(); + void onRemoveExtracted(); + void onListSelectionChanged(); + void showOnlySelected(); + void hideSelected(); + void showAllSelected(); + void onRebuild(); + void ActivateThisDialog(); + void SetEditCurrentArgument(); + +private: + + void Init(); + bool updateSubShTypeCompo(); + void updateFilteredList(); + void resetBuildData(const bool isEnableBuild); + bool isEmptyExtracted(); + void selectMainShape(); + void selectSubShapes(); + void enterEvent(QEvent *); + bool getResult + (GEOM::GEOM_Object_ptr &theResult, + GEOM::GEOM_IShapesOperations::ExtractionStats &theStats); + QString getSubShapeEntry(const int theId); + Handle_SALOME_InteractiveObject createIO(const char *theEntry); + void displaySubShape(const int theId); + void eraseSubShape(const int theId); + void eraseAll(); + void restoreViewer(); + +private: + + GEOM::GEOM_Object_var myObj; + QPushButton *mySelBtn; + QLineEdit *myMainShapeEdit; + QComboBox *mySubShTypeCompo; + QListWidget *myFilteredList; + QTreeWidget *myExtractedTree; + QListWidget *myRemovedList; + QListWidget *myModifiedList; + QListWidget *myAddedList; + QTreeWidgetItem *myTopItems[8]; + QPushButton *myRebuildBtn; + TColStd_MapOfInteger myMapExtractedIDs; + bool myIsHiddenMain; + TColStd_MapOfInteger myMapDisplayedIDs; + TopTools_IndexedMapOfShape myIndices; + +}; + +#endif // OPERATIONGUI_EXTRACTIONDLG_H -- 2.39.2