From e6bcaa307fef3efd962a0959d0830ccb7dc659fb Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 3 Nov 2015 11:38:55 +0300 Subject: [PATCH] 0023193: [CEA] Show sub-shapes with given tolerance --- doc/salome/gui/GEOM/images/inspect_object.png | Bin 29765 -> 36455 bytes .../gui/GEOM/images/inspect_object2.png | Bin 0 -> 30954 bytes .../GEOM/input/inspect_object_operation.doc | 51 +- doc/salome/gui/GEOM/input/tui_test_all.doc | 3 + idl/GEOM_Gen.idl | 31 + src/GEOMGUI/GEOM_msg_en.ts | 30 +- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 100 ++ src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 22 + src/GEOMUtils/GEOMUtils.cxx | 55 ++ src/GEOMUtils/GEOMUtils.hxx | 40 + src/GEOM_I/GEOM_IShapesOperations_i.cc | 74 ++ src/GEOM_I/GEOM_IShapesOperations_i.hh | 6 + src/GEOM_SWIG/GEOM_TestAll.py | 6 + src/GEOM_SWIG/geomBuilder.py | 51 + src/RepairGUI/CMakeLists.txt | 2 + src/RepairGUI/RepairGUI.cxx | 2 +- src/RepairGUI/RepairGUI_InspectObjectDlg.cxx | 872 +++++++++++++++--- src/RepairGUI/RepairGUI_InspectObjectDlg.h | 60 +- 18 files changed, 1232 insertions(+), 173 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/inspect_object2.png mode change 100755 => 100644 doc/salome/gui/GEOM/input/inspect_object_operation.doc diff --git a/doc/salome/gui/GEOM/images/inspect_object.png b/doc/salome/gui/GEOM/images/inspect_object.png index 09d90d0699337e4314fb5409490731e33a5af3f9..23065bd2edba206a5ae4212b65474085ed186a46 100644 GIT binary patch literal 36455 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 literal 29765 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 diff --git a/doc/salome/gui/GEOM/images/inspect_object2.png b/doc/salome/gui/GEOM/images/inspect_object2.png new file mode 100644 index 0000000000000000000000000000000000000000..121e15275478299d874fe512cb54dee0cac7ec42 GIT binary patch literal 30954 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%0D|8+115)4opNSKjr zf9f#1c{8=}O8ORuj}CA7=}fbOqTX*HTCu^!XtcLWjP{yjfC z!$Et9laFDj@sE`0+)q6(%Fl$x($dQoimXSe9VVYfVXg7NS-3N6L}n=$b-j#H-{jVL7=pN2<*TXg{plDO2GDmkG4YB zSK9Jkg$@YZyuOR#D|}c>EEH6V2EaxDy9gBtMfgO?CZ;HnIwcy=CmJMi zn~OyBfFr4_scD?A%E`;@^XmV|N7T;3+}NiS5Td!c^gIL<445ohuKU?8>bnLb@&lEbLk96JDQS2_d5~690toC&6{6+w7;4nBaR$)m*$=%7`i|BW3O5|8ZzzQROocdcLIu%co6UPwl_PoG@7jxEL z6p!D}zlcp6Z+u<#dy)Pj~67XO6J+2j0vhra~S8Y!;TfYRnxtPf%d`=FS6zb<$Z z^xaE2dU#HPKVQ`6y%dof#gBp$GlPyr!yV9LyYj>eZ$5caO_-d-AJW@ZBDx+{>O!xD%Q zJw`}=2FGu1N*H#P=~3L$7g5$de6+vO@Fn9<6w{!_B@R0X5ja)6DB;k?yP*$X-z++A zv0pWQ5X8v;Fv^v~9ftWgfTO^4T#A&GFZ_@zQY!R6Vp9oX>@M;P(d5N+29%<~`myTZ zFk7jUj$c}&-eyO;wOa17^Lbw;lrO&4zr_*sxM5nRpu2_n>$ zMG$e1waoZ+c&Z3+f~hZf=&;eRnRXk{V@%xX&b~Eov`aJ;mtnoLHwsV9=3X>tjdu3* zluofIx(Ruh=vwCSO9yy_1$ZRqG#a!l2vNb5Mi&w z7gC1C!A0%)8X62e#h#>86oXW|3uwQp4~5Ni%*+~yX5nAaMhXoY zrb|A3VkISI^}X?3@j)StpfTg)s3^mvp8UhNOm>%}-pe9iiIvsv_w6RvBbNOJFgF8J zDZoM;#U6R7435rq5yMNr_taJMxEq!F@_)Sy+s_l<;W=qZN8C&HGKNl!*u`1#OG@$g z=Ft#<0gnDX+>92V#e#OThE4aJ{trU`4{uJ$002T*`v2n2G2kIspa{tw0fU%vUbZ1Dei^FL?#eZYUt{C~aqpG*8tXa48S|D5IbbN}|u|J>j212(h- zOkEs<;ek*juH)Vw(se?gs8zsF90?K?Hs|M$GcNP~dwBlSxqk~A6Os4+dh8`?S6oc> zc&%!DR<2odyIZ08=2muesOls0z+T1fRrIx*Ls|8BXthVp?&iUb6t}#`=VC%MZ@J{9 za1dkn%`J);Z-^PrH5Pg_MNn4?=`BQ>vy{lf-#0$K0z4g1?Q!A-`H|&B08pQklSt8C z{NuNA-h83m0XuoB1*brHotU5bi|4I-*r3DtMhP*c-soVMu zX3g{5Xb8d`>hajGHzVJW)#1xJ-o+ohONyjzybd`x`-&P4Bz1E_i7qkv(5u&Df;iXulOLR<3>IdzvX84XLo`P&qirEhU zhz&3}BgSCIJ0!CoVQ-lnYTZDgPy_{cpSf4}mYO|8)3!7x?7sic``uC=sg84I9xdPq zEs?WcKuh9fVih*=@n0wt4TD4}_gj~N>2B(RY<4M%_{75>{ zGqzZ~VbHqC>e`pr=lnEouv5W;YvUWiCo+1hpZcomDr|fKsf@Q(|$!5-M%C*R6NeqTAur)+$#VuR59533vdGXTJP2x*)PM50-ioQ>s zV5p0KtZW-xyZEf>lST(Gk*u55XHE+8aCQ@`6(m%q0iNBm5}mr?Eine~Rg lmLA71Z%#I~Em@)Vv08}UsHUx&a=`NP{{i>_jbH!( literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/input/inspect_object_operation.doc b/doc/salome/gui/GEOM/input/inspect_object_operation.doc old mode 100755 new mode 100644 index 0650bd47b..bff2fbd64 --- a/doc/salome/gui/GEOM/input/inspect_object_operation.doc +++ b/doc/salome/gui/GEOM/input/inspect_object_operation.doc @@ -6,12 +6,41 @@ This operation allows browsing the contents of the selected shape. To Inspect Object, in the Main Menu select Measures - > Inspect Object. -\image html inspect_object.png +The dialog can be used in two modes. The first one is a tree view mode: +\image html inspect_object.png "Dialog in the tree view mode" -In this dialog: +This is a default mode that allows to inspect an object in the form of tree +starting from the shape itself. Its children are its direct sub-shapes that +have they own children as sub-shapes etc. till most very base sub-shapes, +i.e. vertices. + +The second mode is a filtering one. It is activated when the user selects +Tolerance filter check box: +\image html inspect_object2.png "Dialog in the filtering mode" + +In this mode the user can check the type of sub-shapes to work with using +the radio-buttons. The type can be either \b Vertex, \b Edge or \b Face. +Then the user choses a tolerance criterion to be applied to filter out +sub-shapes. It is possible to chose one of the following values: +- \b > - greater than (default value) +- \b >= - greater than or equal to +- \b < - lower than +- \b <= - lower than or equal to + +The last parameter to be chosen is the tolerance value. The result is the shapes +of a certain type that satisfy the defined tolerance criterion. E.g. if the user +chooses \b Face, criterion \b > and tolerance value equal to \b 1.e-6 the faces +with the tolerance greater than \b 1.e-6 are displayed. + +It is possible to set maximal and minimal value of the tolerance using the +buttons Max value and Min value. These values are displayed in +the labels Max : and Min : + +In this dialog never mind of its mode it is possible to: - Click on the "selection" button and select an object to inspect in the Object Browser or in the viewer. -- Show/hide sub-shape(s) in the 3D viewer, by pressing “eye” icon in the first column of the tree view. -- Show/hide all sub-shapes in the 3D viewer, by pressing “eye” icon in the first column of the tree view header. +- Show/hide sub-shape(s) in the 3D viewer, by pressing "eye" icon in the first column of the tree view. +- Show/hide all sub-shapes in the tree, by pressing "eye" icon in the first column of the tree view header or + by pressing Show all/Hide all buttons. - Rename the selected sub-shape by double-clicking on the item or pressing key. - Show the selected sub-shape(s) in the 3D viewer by pressing Show Selected button. - Show the selected sub-shape(s) in the 3D viewer and erase all currently shown objects by pressing Show Only Selected button. @@ -19,4 +48,18 @@ In this dialog: - Publish the selected sub-shapes in the study, by pressing Publish Selected button. - Close dialog box, by pressing Close button. +\n TUI Command: + +A command to filter sub-shapes is defined: + +geompy.GetSubShapesWithTolerance(theShape, theShapeType, theCondition, theTolerance), \n +where \n +\em theShape is the shape to be exploded. \n +\em theShapeType is the type of sub-shapes to be returned. Can have + the values \b GEOM.FACE, \b GEOM.EDGE and \b GEOM.VERTEX only.\n +\em theCondition is the condition type (the value of GEOM.comparison_condition emuneration).\n +\em theTolerance is the tolerance filter. + +See also a \ref swig_GetSubShapesWithTolerance "TUI example". + */ diff --git a/doc/salome/gui/GEOM/input/tui_test_all.doc b/doc/salome/gui/GEOM/input/tui_test_all.doc index f2407ca29..5ed1334a0 100644 --- a/doc/salome/gui/GEOM/input/tui_test_all.doc +++ b/doc/salome/gui/GEOM/input/tui_test_all.doc @@ -102,6 +102,9 @@ \until geompy.RestoreSubShapes(Partition1) \anchor swig_GetSubShapeEdgeSorted +\until geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges") + +\anchor swig_GetSubShapesWithTolerance \until print "DONE" */ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 98af123bd..830fcc398 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -209,6 +209,17 @@ module GEOM SI_ALL // all interferences }; + /** + * This enumeration represents comparison conditions. + */ + enum comparison_condition + { + CC_GT, ///< Greater then + CC_GE, ///< Greater then or equal to + CC_LT, ///< Less then + CC_LE ///< Less then or equal to + }; + /*! * \brief Object creation parameters * @@ -2747,6 +2758,26 @@ module GEOM ListOfGO GetSubShapeEdgeSorted (in GEOM_Object theShape, in GEOM_Object theStartPoint); + /*! + * \brief Return the list of subshapes that satisfies a certain tolerance + * criterion. The user defines the type of shapes to be returned, the + * condition and the tolerance value. The operation is defined for + * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition + * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape + * that have tolerances greater then 1.e7. + * + * \param theShape the shape to be exploded + * \param theShapeType the type of shapes to be returned. Can have the + * values FACE, EDGE and VERTEX only. + * \param theCondition the condition type. + * \param theTolerance the tolerance filter. + * \return the list of shapes that satisfy the conditions. + */ + ListOfGO GetSubShapesWithTolerance(in GEOM_Object theShape, + in short theShapeType, + in comparison_condition theCondition, + in double theTolerance); + }; // # GEOM_IBlocksOperations: diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 491d964f8..2f225edbd 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -5440,6 +5440,14 @@ shells and solids on the other hand. GEOM_DIM_AXES Dimensions along local axes + + SHOW_ALL_BTN + Show all + + + HIDE_ALL_BTN + Hide all + GeometryGUI @@ -6507,14 +6515,6 @@ Number of sketch points too small REMOVE_BTN Remove - - SHOW_ALL_BTN - Show all - - - HIDE_ALL_BTN - Hide all - DISTANCE_ITEM Distance @@ -7231,7 +7231,19 @@ Do you want to create new material? Main shape - GEOM_INSPECT_OBJECT_SHOW + GEOM_INSPECT_TOLERANCE_FILTER + Tolerance filter + + + GEOM_INSPECT_RESET_MIN + Min value + + + GEOM_INSPECT_RESET_MAX + Max value + + + GEOM_INSPECT_OBJECT_SHOW Show Selected diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 96c8e49b1..3ed4513ec 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -3062,6 +3062,106 @@ Handle(TColStd_HSequenceOfTransient) return aSeq; } +//============================================================================= +/*! + * GetSubShapesWithTolerance + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) + GEOMImpl_IShapesOperations::GetSubShapesWithTolerance + (const Handle(GEOM_Object) &theShape, + const Standard_Integer theShapeType, + const GEOMUtils::ComparisonCondition theCondition, + const Standard_Real theTolerance) +{ + if (theShape.IsNull()) { + SetErrorCode("NULL GEOM object"); + return NULL; + } + + TopoDS_Shape aShape = theShape->GetValue(); + + if (aShape.IsNull()) { + SetErrorCode("NULL Shape"); + return NULL; + } + + if (theShapeType != TopAbs_FACE && theShapeType != TopAbs_EDGE && + theShapeType != TopAbs_VERTEX && aShape.ShapeType() >= theShapeType) { + SetErrorCode("Invalid shape type"); + return NULL; + } + + TopTools_IndexedMapOfShape anIndices; + TopTools_MapOfShape aMapFence; + TopExp_Explorer anExp(aShape, + (TopAbs_ShapeEnum) theShapeType); + Handle(TColStd_HSequenceOfInteger) anIDs = new TColStd_HSequenceOfInteger; + + TopExp::MapShapes(aShape, anIndices); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (aMapFence.Add(aSubShape)) { + // Compute tolerance + Standard_Real aTolerance = -1.; + + switch (aSubShape.ShapeType()) { + case TopAbs_FACE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape)); + break; + case TopAbs_EDGE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape)); + break; + case TopAbs_VERTEX: + aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape)); + break; + default: + break; + } + + if (aTolerance < 0.) { + continue; + } + + // Compare the tolerance with reference value. + if (GEOMUtils::IsFitCondition (theCondition, aTolerance, theTolerance)) { + anIDs->Append(anIndices.FindIndex(aSubShape)); + } + } + } + + if (anIDs->IsEmpty()) { + SetErrorCode("Empty sequence of sub-shapes"); + return NULL; + } + + // Get objects by indices. + TCollection_AsciiString anAsciiList; + Handle(TColStd_HSequenceOfTransient) aSeq = + getObjectsShapesOn(theShape, anIDs, anAsciiList); + + if (aSeq.IsNull() || aSeq->IsEmpty()) { + SetErrorCode("Empty sequence of edges"); + return NULL; + } + + // Make a Python command + Handle(GEOM_Object) anObj = + Handle(GEOM_Object)::DownCast(aSeq->Value(1)); + Handle(GEOM_Function) aFunction = anObj->GetLastFunction(); + + GEOM::TPythonDump(aFunction) + << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapesWithTolerance(" + << theShape << ", " << theShapeType << ", " << theCondition << ", " + << theTolerance << ")"; + + SetErrorCode(OK); + + return aSeq; +} + //======================================================================= //function : getShapesOnSurfaceIDs /*! diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 795a55d1b..5078a386a 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -33,6 +33,7 @@ #include "GEOM_IOperations.hxx" #include "GEOMAlgo_State.hxx" +#include "GEOMUtils.hxx" #include #include @@ -448,6 +449,27 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations GetSubShapeEdgeSorted (const Handle(GEOM_Object) &theShape, const Handle(GEOM_Object) &theStartPoint); + /*! + * \brief Return the list of subshapes that satisfies a certain tolerance + * criterion. The user defines the type of shapes to be returned, the + * condition and the tolerance value. The operation is defined for + * faces, edges and vertices only. E.g. for theShapeType FACE, theCondition + * CC_GT and theTolerance 1.e-7 this method returns all faces of theShape + * that have tolerances greater then 1.e7. + * + * \param theShape the shape to be exploded + * \param theShapeType the type of shapes to be returned. Can have the + * values FACE, EDGE and VERTEX only. + * \param theCondition the condition type. + * \param theTolerance the tolerance filter. + * \return the list of shapes that satisfy the conditions. + */ + Handle(TColStd_HSequenceOfTransient) GetSubShapesWithTolerance + (const Handle(GEOM_Object) &theShape, + const Standard_Integer theShapeType, + const GEOMUtils::ComparisonCondition theCondition, + const Standard_Real theTolerance); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx index 3e0b18977..c359c2567 100644 --- a/src/GEOMUtils/GEOMUtils.cxx +++ b/src/GEOMUtils/GEOMUtils.cxx @@ -104,6 +104,9 @@ #define STD_SORT_ALGO 1 +#define DEFAULT_TOLERANCE_TOLERANCE 1.e-02 +#define DEFAULT_MAX_TOLERANCE_TOLERANCE 1.e-06 + // When the following macro is defined, ShapeFix_ShapeTolerance function is used to set max tolerance of curve // in GEOMUtils::FixShapeCurves function; otherwise less restrictive BRep_Builder::UpdateEdge/UpdateVertex // approach is used @@ -1287,3 +1290,55 @@ bool GEOMUtils::IsOpenPath(const TopoDS_Shape &theShape) return isOpen; } + +//======================================================================= +//function : CompareToleranceValues +//purpose : +//======================================================================= +int GEOMUtils::CompareToleranceValues(const double theTolShape, + const double theTolRef) +{ + const double aTolTol = Min(DEFAULT_MAX_TOLERANCE_TOLERANCE, + theTolRef*DEFAULT_TOLERANCE_TOLERANCE); + + int aResult = 0; + + if (theTolShape < theTolRef - aTolTol) { + aResult = -1; + } else if (theTolShape > theTolRef + aTolTol) { + aResult = 1; + } + + return aResult; +} + +//======================================================================= +//function : IsFitCondition +//purpose : +//======================================================================= +bool GEOMUtils::IsFitCondition(const ComparisonCondition theCondition, + const double theTolShape, + const double theTolRef) +{ + const int aCompValue = CompareToleranceValues(theTolShape, theTolRef); + bool isFit = false; + + switch (theCondition) { + case CC_GT: + isFit = aCompValue == 1; + break; + case GEOMUtils::CC_GE: + isFit = aCompValue != -1; + break; + case GEOMUtils::CC_LT: + isFit = aCompValue == -1; + break; + case GEOMUtils::CC_LE: + isFit = aCompValue != 1; + break; + default: + break; + } + + return isFit; +} diff --git a/src/GEOMUtils/GEOMUtils.hxx b/src/GEOMUtils/GEOMUtils.hxx index 8ffa25be2..184bc9703 100644 --- a/src/GEOMUtils/GEOMUtils.hxx +++ b/src/GEOMUtils/GEOMUtils.hxx @@ -55,6 +55,16 @@ inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) namespace GEOMUtils { + /** + * This enumeration represents comparison conditions. + */ + enum ComparisonCondition { + CC_GT, ///< Greater then + CC_GE, ///< Greater then or equal to + CC_LT, ///< Less then + CC_LE ///< Less then or equal to + }; + typedef std::vector NodeLinks; typedef std::map LevelInfo; typedef std::vector LevelsList; @@ -341,6 +351,36 @@ namespace GEOMUtils */ Standard_EXPORT bool IsOpenPath(const TopoDS_Shape &theShape); + /** + * This function compares two tolerances. The shape tolerance (the first + * argument) is considered less than the reference tolerance (the second + * argument) if theTolShape < theTolRef - Tolerance(theTolRef). theTolShape is + * considered greater than theTolRef if theTolShape > theTolRef + + * Tolerance(theTolRef). Otherwise these tolerances are equal. + * Tolerance(theTolRef) = theTolRef*DEFAULT_TOLERANCE_TOLERANCE. But this value + * should not be greated than DEFAULT_MAX_TOLERANCE_TOLERANCE. + * + * \param theTolShape the shape tolerance + * \param theTolRef the reference tolerance + * \return -1 if theTolShape is less than theTolRef; 1 if theTolShape is greater + * than theTolRef; 0 if they are equal + */ + Standard_EXPORT int CompareToleranceValues(const double theTolShape, + const double theTolRef); + + /** + * Check if the comarison of tolerances fit the condition. The comparison of + * tolerances is performed using the function CompareToleranceValues. + * + * \param theCondition the condition + * \param theTolShape the shape tolerance + * \param theTolRef the reference tolerance + * \return true if the shape tolerance fits the condition; false otherwise. + */ + Standard_EXPORT bool IsFitCondition(const ComparisonCondition theCondition, + const double theTolShape, + const double theTolRef); + }; #endif diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 1e88b88f9..7561d9a16 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -35,6 +35,35 @@ #include #include +/** + * This function converts GEOM::comparison_condition type into + * GEOMUtils::ComparisonCondition type. + * + * \param theCondition the condition of GEOM::comparison_condition type + * \return the condition of GEOMUtils::ComparisonCondition type. + */ +static GEOMUtils::ComparisonCondition ComparisonCondition + (const GEOM::comparison_condition theCondition) +{ + GEOMUtils::ComparisonCondition aResult = GEOMUtils::CC_GT; + + switch (theCondition) { + case GEOM::CC_GE: + aResult = GEOMUtils::CC_GE; + break; + case GEOM::CC_LT: + aResult = GEOMUtils::CC_LT; + break; + case GEOM::CC_LE: + aResult = GEOMUtils::CC_LE; + break; + default: + break; + } + + return aResult; +} + //============================================================================= /*! * constructor: @@ -2156,3 +2185,48 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapeEdgeSorted return aSeq._retn(); } + +//============================================================================= +/*! + * GetSubShapesWithTolerance + */ +//============================================================================= +GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapesWithTolerance + (GEOM::GEOM_Object_ptr theShape, + CORBA::Short theShapeType, + GEOM::comparison_condition theCondition, + CORBA::Double theTolerance) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (aShape.IsNull()) { + return aSeq._retn(); + } + + //Get Shapes On Shape + const GEOMUtils::ComparisonCondition aCondition = + ComparisonCondition(theCondition); + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->GetSubShapesWithTolerance + (aShape, theShapeType, aCondition, theTolerance); + + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); + + const Standard_Integer aLength = aHSeq->Length(); + Standard_Integer i; + + aSeq->length(aLength); + + for (i = 1; i <= aLength; i++) { + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + } + + return aSeq._retn(); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index f8dba7caf..0f36a38c3 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -300,6 +300,12 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::ListOfGO* GetSubShapeEdgeSorted (GEOM::GEOM_Object_ptr theShape, GEOM::GEOM_Object_ptr theStartPoint); + GEOM::ListOfGO* GetSubShapesWithTolerance + (GEOM::GEOM_Object_ptr theShape, + CORBA::Short theShapeType, + GEOM::comparison_condition theCondition, + CORBA::Double theTolerance); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index 683918508..ea862293f 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -584,5 +584,11 @@ def TestAll (geompy, math): geompy.GetSubShapeEdgeSorted(Sketcher3d_1, p2, "OrderedEdges") geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges") + # GetSubShapesWithTolerance + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GT, 1.e-8, "gt") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_GE, 1.e-7, "ge") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LT, 2.e-7, "lt") + geompy.GetSubShapesWithTolerance(Box, GEOM.FACE, GEOM.CC_LE, 1.e-7, "le") + print "DONE" diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 46573011e..16e9ea4ca 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -6574,6 +6574,57 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(ListObj, theName, "SortedEdges") return ListObj + ## + # Return the list of subshapes that satisfies a certain tolerance + # criterion. The user defines the type of shapes to be returned, the + # condition and the tolerance value. The operation is defined for + # faces, edges and vertices only. E.g. for theShapeType FACE, + # theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns + # all faces of theShape that have tolerances greater then 1.e7. + # + # @param theShape the shape to be exploded + # @param theShapeType the type of sub-shapes to be returned (see + # ShapeType()). Can have the values FACE, EDGE and VERTEX only. + # @param theCondition the condition type (see GEOM::comparison_condition). + # @param theTolerance the tolerance filter. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # @return the list of shapes that satisfy the conditions. + # + # @ref swig_GetSubShapesWithTolerance "Example" + @ManageTransactions("ShapesOp") + def GetSubShapesWithTolerance(self, theShape, theShapeType, + theCondition, theTolerance, theName=None): + """ + Return the list of subshapes that satisfies a certain tolerance + criterion. The user defines the type of shapes to be returned, the + condition and the tolerance value. The operation is defined for + faces, edges and vertices only. E.g. for theShapeType FACE, + theCondition GEOM::CC_GT and theTolerance 1.e-7 this method returns + all faces of theShape that have tolerances greater then 1.e7. + + Parameters: + theShape the shape to be exploded + theShapeType the type of sub-shapes to be returned (see + ShapeType()). Can have the values FACE, + EDGE and VERTEX only. + theCondition the condition type (see GEOM::comparison_condition). + theTolerance the tolerance filter. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + The list of shapes that satisfy the conditions. + """ + # Example: see GEOM_TestAll.py + ListObj = self.ShapesOp.GetSubShapesWithTolerance(theShape, EnumToLong(theShapeType), + theCondition, theTolerance) + RaiseIfFailed("GetSubShapesWithTolerance", self.ShapesOp) + self._autoPublish(ListObj, theName, "SubShapeWithTolerance") + return ListObj + ## Check if the object is a sub-object of another GEOM object. # @param aSubObject Checked sub-object (or its parent object, in case if # \a theSubObjectIndex is non-zero). diff --git a/src/RepairGUI/CMakeLists.txt b/src/RepairGUI/CMakeLists.txt index 34310cf4c..d9ae6fa29 100755 --- a/src/RepairGUI/CMakeLists.txt +++ b/src/RepairGUI/CMakeLists.txt @@ -41,6 +41,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/DlgRef ${PROJECT_BINARY_DIR}/src/DlgRef ${PROJECT_SOURCE_DIR}/src/GEOMAlgo + ${PROJECT_SOURCE_DIR}/src/GEOMUtils ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -55,6 +56,7 @@ ADD_DEFINITIONS( # libraries to link to SET(_link_LIBRARIES GEOMBase + GEOMUtils ) # --- resources --- diff --git a/src/RepairGUI/RepairGUI.cxx b/src/RepairGUI/RepairGUI.cxx index 6c177ab85..3eadcbe21 100644 --- a/src/RepairGUI/RepairGUI.cxx +++ b/src/RepairGUI/RepairGUI.cxx @@ -98,7 +98,7 @@ bool RepairGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpRemoveExtraEdges: aDlg = new RepairGUI_RemoveExtraEdgesDlg (getGeometryGUI(), parent); break; case GEOMOp::OpFuseEdges: aDlg = new RepairGUI_FuseEdgesDlg (getGeometryGUI(), parent); break; case GEOMOp::OpUnionFaces: aDlg = new RepairGUI_UnionFacesDlg (getGeometryGUI(), parent); break; - case GEOMOp::OpInspectObj: aDlg = new RepairGUI_InspectObjectDlg (parent); break; + case GEOMOp::OpInspectObj: aDlg = new RepairGUI_InspectObjectDlg (getGeometryGUI(), parent); break; default: app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); break; diff --git a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx index e0c5ef0ba..a66f9c18e 100644 --- a/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx +++ b/src/RepairGUI/RepairGUI_InspectObjectDlg.cxx @@ -24,6 +24,7 @@ #include #include #include +#include // GUI includes #include @@ -35,19 +36,47 @@ #include #include +#include #include #include #include // OCCT includes +#include +#include +#include +#include #include +#include +#include // Qt includes +#include +#include #include +#include #include #include #include +#include +#include +#include +#include + +// Shape type definitions (values are equal to corresponding types of TopAbs_ShapeEnum). +#define TYPE_FACE 4 +#define TYPE_EDGE 6 +#define TYPE_VERTEX 7 + +// Comparison type definitions +#define COMPARE_GT 0 +#define COMPARE_GE 1 +#define COMPARE_LT 2 +#define COMPARE_LE 3 + +// Default tolerance values +#define DEFAULT_TOLERANCE_VALUE 1.e-07 //================================================================================= // class : RepairGUI_InspectObjectDlg::TreeWidgetItem @@ -56,8 +85,20 @@ class RepairGUI_InspectObjectDlg::TreeWidgetItem : public QTreeWidgetItem { public: - TreeWidgetItem( QTreeWidget*, const QStringList&, const TopoDS_Shape&, const Handle(SALOME_InteractiveObject)&, int = Type ); - TreeWidgetItem( QTreeWidgetItem*, const QStringList&, const TopoDS_Shape&, const QString&, int = Type ); + TreeWidgetItem(QTreeWidget*, + const QStringList&, + const TopoDS_Shape&, + const Handle(SALOME_InteractiveObject)&, + double = DEFAULT_TOLERANCE_VALUE, + int = Type); + + TreeWidgetItem(QTreeWidgetItem*, + const QStringList&, + const TopoDS_Shape&, + const QString&, + double = DEFAULT_TOLERANCE_VALUE, + int = Type); + ~TreeWidgetItem(); bool isVisible(); @@ -66,27 +107,43 @@ public: TopoDS_Shape getShape() const; Handle(SALOME_InteractiveObject) getIO() const; + double getTolerance() const; + void setTolerance(double theTolerance); + private: bool myIsVisible; TopoDS_Shape myShape; Handle(SALOME_InteractiveObject) myIO; + double myTolerance; }; -RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidget* view, const QStringList &strings, const TopoDS_Shape& shape, - const Handle(SALOME_InteractiveObject)& io, int type ) +RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem + (QTreeWidget *view, + const QStringList &strings, + const TopoDS_Shape &shape, + const Handle(SALOME_InteractiveObject) &io, + double theTolerance, + int type) : QTreeWidgetItem( view, strings, type ), myIsVisible( false ), myShape( shape ), - myIO( io ) + myIO( io ), + myTolerance (theTolerance) { } -RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings, - const TopoDS_Shape& shape, const QString& entry, int type ) +RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem + (QTreeWidgetItem *parent, + const QStringList &strings, + const TopoDS_Shape &shape, + const QString &entry, + double theTolerance, + int type) : QTreeWidgetItem( parent, strings, type ), myIsVisible( false ), - myShape( shape ) + myShape( shape ), + myTolerance (theTolerance) { myIO = new SALOME_InteractiveObject( entry.toAscii(), "GEOM", "TEMP_IO" ); setFlags( flags() | Qt::ItemIsEditable ); @@ -117,6 +174,16 @@ Handle(SALOME_InteractiveObject) RepairGUI_InspectObjectDlg::TreeWidgetItem::get return myIO; } +double RepairGUI_InspectObjectDlg::TreeWidgetItem::getTolerance() const +{ + return myTolerance; +} + +void RepairGUI_InspectObjectDlg::TreeWidgetItem::setTolerance(double theTolerance) +{ + myTolerance = theTolerance; +} + //================================================================================= // class : RepairGUI_InspectObjectDlg::Delegate // purpose : class for "Inspect Object" tree item editing @@ -169,120 +236,156 @@ QWidget* RepairGUI_InspectObjectDlg::Delegate::createEditor( QWidget* parent, // class : RepairGUI_InspectObjectDlg() // purpose : Constructs a RepairGUI_InspectObjectDlg which is a child of 'parent'. //================================================================================= -RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg( SUIT_Desktop* parent ) -: GEOMBase_Helper( parent ), - QDialog( parent ), - myTransparency( 0.0 ), - myIsSelectAll( false ) +RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg(GeometryGUI *theGeomGUI, SUIT_Desktop* parent ) +: GEOMBase_Helper (parent), + QDialog (parent), + myGeomGUI (theGeomGUI), + myTreeObjects (0), + myFilteredTreeObjects (0), + myCurrentTreeObjects (0), + myEditMainShape (0), + myTolFilterGrp (0), + myShapeTypeBtnGrp (0), + myComparisonCompo (0), + myMinTolValLabel (0), + myMaxTolValLabel (0), + myTolEdit (0), + myTreesLayout (0), + myTransparency (0.0), + myIsSelectAll (false), + myMaxTol (-1.), + myMinTol (-1.) { - QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); - myVisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); - myInvisible = QIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + QIcon iconSelect( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); + myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + + QPixmap anImageVtx(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX"))); + QPixmap anImageEdge(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_EDGE"))); + QPixmap anImageFace(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_FACE"))); setWindowTitle( tr( "GEOM_INSPECT_OBJECT_TITLE" ) ); setAttribute( Qt::WA_DeleteOnClose ); - myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); - myViewWindow = myApp->desktop()->activeWindow(); + myViewWindow = myGeomGUI->getApp()->desktop()->activeWindow(); QGridLayout* topLayout = new QGridLayout( this ); topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); /********************** Inspected Object **********************/ - QHBoxLayout* mainShapeLayout = new QHBoxLayout(); + QHBoxLayout* mainShapeLayout = new QHBoxLayout(this); - QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ) ); - QPushButton* selBtn = new QPushButton(); + QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ), this ); + QPushButton* selBtn = new QPushButton(this); selBtn->setIcon( iconSelect ); - myEditMainShape = new QLineEdit(); + myEditMainShape = new QLineEdit(this); myEditMainShape->setReadOnly(true); mainShapeLayout->addWidget( label ); mainShapeLayout->addWidget( selBtn ); mainShapeLayout->addWidget( myEditMainShape ); - /********************** Sub-objects tree **********************/ + /********************** Tolerance filter **********************/ - myTreeObjects = new QTreeWidget(); - myTreeObjects->setColumnCount( 2 ); - QStringList columnNames; - columnNames.append( tr( "GEOM_INSPECT_OBJECT_NAME" ) ); - columnNames.append(""); - myTreeObjects->setHeaderLabels( columnNames ); - QTreeWidgetItem* headerItem = new QTreeWidgetItem( columnNames ); - myTreeObjects->setHeaderItem( headerItem ); - myTreeObjects->header()->moveSection( 1, 0 ); - myTreeObjects->header()->setClickable( true ); - myTreeObjects->header()->setMovable( false ); - myTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents ); - myTreeObjects->setSelectionMode( QAbstractItemView::ExtendedSelection ); - myTreeObjects->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed ); - // set custom item delegate - myTreeObjects->setItemDelegate( new Delegate( myTreeObjects ) ); + myTolFilterGrp = new QGroupBox (tr("GEOM_INSPECT_TOLERANCE_FILTER"), this); + myShapeTypeBtnGrp = new QButtonGroup(myTolFilterGrp); + + // Filter on shape type + QRadioButton *aVtx = new QRadioButton(tr("GEOM_VERTEX"), myTolFilterGrp); + QRadioButton *anEdge = new QRadioButton(tr("GEOM_EDGE"), myTolFilterGrp); + QRadioButton *aFace = new QRadioButton(tr("GEOM_FACE"), myTolFilterGrp); + + aVtx->setIcon(anImageVtx); + anEdge->setIcon(anImageEdge); + aFace->setIcon(anImageFace); + myShapeTypeBtnGrp->addButton(aVtx, TYPE_VERTEX); + myShapeTypeBtnGrp->addButton(anEdge, TYPE_EDGE); + myShapeTypeBtnGrp->addButton(aFace, TYPE_FACE); + + // Filter on sub-shape tolerance + QLabel *aTolLabel = new QLabel(tr("GEOM_TOLERANCE"), myTolFilterGrp); + QLabel *aMinTolLabel = new QLabel(tr("GEOM_MIN"), myTolFilterGrp); + QLabel *aMaxTolLabel = new QLabel(tr("GEOM_MAX"), myTolFilterGrp); + QGridLayout *aFilterLayout = new QGridLayout(myTolFilterGrp); + + myMinTolValLabel = new QLabel(myTolFilterGrp); + myMaxTolValLabel = new QLabel(myTolFilterGrp); + myMinTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MIN"), myTolFilterGrp); + myMaxTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MAX"), myTolFilterGrp); + myComparisonCompo = new QComboBox(myTolFilterGrp); + myTolEdit = new SalomeApp_DoubleSpinBox(myTolFilterGrp); + myTolEdit->setMinimumWidth(120); + aFilterLayout->addWidget(aVtx, 0, 0); + aFilterLayout->addWidget(anEdge, 0, 1); + aFilterLayout->addWidget(aFace, 0, 2); + aFilterLayout->addWidget(aMaxTolLabel, 1, 0, Qt::AlignRight); + aFilterLayout->addWidget(aTolLabel, 2, 0); + aFilterLayout->addWidget(aMinTolLabel, 3, 0, Qt::AlignRight); + aFilterLayout->addWidget(myMaxTolValLabel, 1, 1); + aFilterLayout->addWidget(myComparisonCompo, 2, 1); + aFilterLayout->addWidget(myMinTolValLabel, 3, 1); + aFilterLayout->addWidget(myMaxTolResetBtn, 1, 2); + aFilterLayout->addWidget(myTolEdit, 2, 2); + aFilterLayout->addWidget(myMinTolResetBtn, 3, 2); + aFilterLayout->setRowMinimumHeight(0, 30); + + myTolFilterGrp->setCheckable(true); + + /********************** Sub-objects trees **********************/ + createTreeWidget(myTreeObjects); + createTreeWidget(myFilteredTreeObjects); + + myTreesLayout = new QStackedLayout(this); + myTreesLayout->addWidget(myTreeObjects); + myTreesLayout->addWidget(myFilteredTreeObjects); /********************** Buttons **********************/ - QVBoxLayout* buttonsLayout1 = new QVBoxLayout(); + QVBoxLayout* buttonsLayout1 = new QVBoxLayout(this); + + QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ), this ); + QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ), this ); + QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ), this ); + QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ), this ); + QPushButton* aShowAllBtn = new QPushButton(tr("SHOW_ALL_BTN"), this); + QPushButton* aHideAllBtn = new QPushButton(tr("HIDE_ALL_BTN"), this); - QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ) ); - QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ) ); - QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ) ); - QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ) ); buttonsLayout1->addWidget( buttonShow ); buttonsLayout1->addWidget( buttonShowOnly ); buttonsLayout1->addWidget( buttonHide ); - buttonsLayout1->addStretch(); + buttonsLayout1->addWidget( aShowAllBtn ); + buttonsLayout1->addWidget( aHideAllBtn ); buttonsLayout1->addWidget( buttonPublish ); buttonsLayout1->addStretch(); - QHBoxLayout* buttonsLayout2 = new QHBoxLayout(); + QHBoxLayout* buttonsLayout2 = new QHBoxLayout(this); - QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ) ); - QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ) ); + QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this ); + QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this ); buttonsLayout2->addWidget( buttonClose ); buttonsLayout2->addStretch(); buttonsLayout2->addWidget( buttonHelp ); topLayout->addLayout( mainShapeLayout, 0, 0 ); - topLayout->addWidget( myTreeObjects, 1, 0 ); - topLayout->addLayout( buttonsLayout1, 0, 1, 2, 1 ); - topLayout->addLayout( buttonsLayout2, 2, 0, 1, 2 ); - - // Signals and slots connections + topLayout->addWidget( myTolFilterGrp, 1, 0); + topLayout->addLayout( myTreesLayout, 2, 0 ); + topLayout->addLayout( buttonsLayout1, 0, 1, 3, 1 ); + topLayout->addLayout( buttonsLayout2, 3, 0, 1, 2 ); connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) ); - connect( myTreeObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), - this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) ); - connect( myTreeObjects, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ), - this, SLOT( onItemChanged( QTreeWidgetItem*, int ) ) ); - connect( myTreeObjects, SIGNAL( itemExpanded ( QTreeWidgetItem* ) ), - this, SLOT( onItemExpanded( QTreeWidgetItem* ) ) ); - connect( myTreeObjects, SIGNAL( itemSelectionChanged() ), - this, SLOT( onItemSelectionChanged() ) ); - - connect( myTreeObjects->header(), SIGNAL( sectionClicked( int ) ), this, SLOT( onHeaderClicked( int ) ) ); - connect( buttonShow, SIGNAL( clicked() ), this, SLOT( clickOnShow() ) ); connect( buttonShowOnly, SIGNAL( clicked() ), this, SLOT( clickOnShowOnly() ) ); connect( buttonHide, SIGNAL( clicked() ), this, SLOT( clickOnHide() ) ); connect( buttonPublish, SIGNAL( clicked() ), this, SLOT( clickOnPublish() ) ); - connect( buttonClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) ); - - connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ), - this, SLOT( onViewSelectionChanged() ) ); - - connect( myApp->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), - this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); - - if ( myViewWindow ) - connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), - this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); + connect( aShowAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnShowAll() ) ); + connect( aHideAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnHideAll() ) ); init(); } @@ -297,59 +400,133 @@ RepairGUI_InspectObjectDlg::~RepairGUI_InspectObjectDlg() // no need to delete child widgets, Qt does it all for us } +//================================================================================= +// function : createTreeWidget() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::createTreeWidget(QTreeWidget *&theTreeObjects) +{ + theTreeObjects = new QTreeWidget(this); + theTreeObjects->setColumnCount(2); + QStringList columnNames; + columnNames.append(tr("GEOM_INSPECT_OBJECT_NAME")); + columnNames.append(""); + theTreeObjects->setHeaderLabels(columnNames); + QTreeWidgetItem* headerItem = new QTreeWidgetItem(columnNames); + + headerItem->setIcon(1, myInvisible); + theTreeObjects->setHeaderItem(headerItem); + theTreeObjects->header()->moveSection(1, 0); + theTreeObjects->header()->setClickable(true); + theTreeObjects->header()->setMovable(false); + theTreeObjects->header()->setResizeMode( 1, QHeaderView::ResizeToContents); + theTreeObjects->setSelectionMode(QAbstractItemView::ExtendedSelection); + theTreeObjects->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); + // set custom item delegate + theTreeObjects->setItemDelegate(new Delegate(theTreeObjects)); +} + //================================================================================= // function : init() // purpose : initialize dialog data //================================================================================= void RepairGUI_InspectObjectDlg::init() { - //get shape from selection - SALOME_ListIO selected; - myApp->selectionMgr()->selectedObjects(selected); + myTolFilterGrp->setChecked(false); + myComparisonCompo->addItem(">", GEOMUtils::CC_GT); + myComparisonCompo->addItem(">=", GEOMUtils::CC_GE); + myComparisonCompo->addItem("<", GEOMUtils::CC_LT); + myComparisonCompo->addItem("<=", GEOMUtils::CC_LE); - if ( selected.Extent() != 1 ) - return; + initSpinBox(myTolEdit, 0., 100., DEFAULT_TOLERANCE_VALUE, "len_tol_precision"); + myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); - if ( !myViewWindow ) { - SUIT_ViewManager* occVm = myApp->getViewManager( OCCViewer_Viewer::Type(), true ); - myViewWindow = occVm->getActiveView(); - connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + // Signals and slots connections + initTreeWidget(myTreeObjects); + initTreeWidget(myFilteredTreeObjects); + myCurrentTreeObjects = myTreeObjects; + myMaxTolResetBtn->setEnabled(false); + myMinTolResetBtn->setEnabled(false); + + connect(myMinTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMin())); + connect(myMaxTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMax())); + connect(myShapeTypeBtnGrp, SIGNAL(buttonClicked(int)), this, SLOT(onInitFilteredData())); + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject())); + + connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), + this, SLOT( onViewSelectionChanged() ) ); + + connect( myGeomGUI->getApp()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), + this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); + + // Connect signals and slots for filter group box elements. + connect(myTolFilterGrp, SIGNAL(toggled(bool)), + this, SLOT(onFilterToggled(bool))); + connect(myComparisonCompo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onFilterData())); + connect(myTolEdit, SIGNAL(valueChanged(double)), + this, SLOT(onFilterData())); + + if ( myViewWindow ) + connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); - } - TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); - if ( aShape.IsNull() ) - return; + // Initialize the dialog with current selection. + onViewSelectionChanged(); +} - Handle(SALOME_InteractiveObject) anIO = selected.First(); - GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); - QString aName = anObject->GetName(); - CORBA::String_var anEntry = anObject->GetStudyEntry(); +//================================================================================= +// function : initSpinBox() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::initSpinBox(SalomeApp_DoubleSpinBox* spinBox, + double min, double max, + double step, const char* quantity) +{ + // Obtain precision from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int aPrecision = resMgr->integerValue( "Geometry", quantity, 6 ); + + spinBox->setPrecision( aPrecision ); + spinBox->setDecimals( qAbs( aPrecision ) ); // it's necessary to set decimals before the range setting, + // by default Qt rounds boundaries to 2 decimals at setRange + spinBox->setRange( min, max ); + spinBox->setSingleStep( step ); + + // Add a hint for the user saying how to tune precision + QString userPropName = QObject::tr( QString( "GEOM_PREF_%1" ).arg( quantity ).toLatin1().constData() ); + spinBox->setProperty( "validity_tune_hint", + QVariant( QObject::tr( "GEOM_PRECISION_HINT" ).arg( userPropName ) ) ); +} - myEditMainShape->setText( aName ); - myEditMainShape->setEnabled( false ); +//================================================================================= +// function : initTreeWidget() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::initTreeWidget(QTreeWidget *theTreeObjects) +{ + connect(theTreeObjects, SIGNAL(itemClicked (QTreeWidgetItem *, int)), + this, SLOT(onItemClicked(QTreeWidgetItem *, int))); + connect(theTreeObjects, SIGNAL(itemChanged (QTreeWidgetItem *, int)), + this, SLOT(onItemChanged(QTreeWidgetItem *, int))); + connect(theTreeObjects, SIGNAL(itemExpanded (QTreeWidgetItem *)), + this, SLOT(onItemExpanded(QTreeWidgetItem *))); + connect(theTreeObjects, SIGNAL(itemSelectionChanged()), + this, SLOT(onItemSelectionChanged())); - // remember initial transparency value - SalomeApp_Study* aStudy = dynamic_cast( myApp->activeStudy() ); - QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(), - QString( anEntry.in() ), - GEOM::propertyName( GEOM::Transparency ), myTransparency ); - if ( v.canConvert( QVariant::Double ) ) - myTransparency = v.toDouble(); + connect(theTreeObjects->header(), SIGNAL(sectionClicked(int)), + this, SLOT(onHeaderClicked(int))); +} - TreeWidgetItem* anItem = new TreeWidgetItem( myTreeObjects, QStringList() << aName, aShape, anIO ); - if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) - anItem->setVisible( true, myVisible ); - else - anItem->setVisible( false, myInvisible ); - - setMainObjectTransparency( 0.5 ); - - // add sub-objects in the tree - addSubObjects( anItem ); - - // check icon for tree header - checkVisibleIcon(); +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::enterEvent (QEvent*) +{ + if (!myTolFilterGrp->isEnabled()) + ActivateThisDialog(); } //================================================================================= @@ -359,20 +536,22 @@ void RepairGUI_InspectObjectDlg::init() void RepairGUI_InspectObjectDlg::checkVisibleIcon() { bool isInvisible = false; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( !anItem->isVisible() ) + if ( !anItem->isHidden() && !anItem->isVisible() ) { isInvisible = true; + break; + } ++it; } if ( isInvisible ) { - myTreeObjects->headerItem()->setIcon( 1, myInvisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); myIsSelectAll = false; } else { - myTreeObjects->headerItem()->setIcon( 1, myVisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); myIsSelectAll = true; } } @@ -381,20 +560,205 @@ void RepairGUI_InspectObjectDlg::checkVisibleIcon() // function : addSubObjects() // purpose : add sub-objects to parent object in the tree //================================================================================= -void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem ) +void RepairGUI_InspectObjectDlg::addSubObjects + (TreeWidgetItem *theParentItem, + const TopTools_IndexedMapOfShape &theIndices) { TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); TopoDS_Iterator it( theParentItem->getShape() ); for ( ; it.More(); it.Next() ) { TopoDS_Shape aSubShape = it.Value(); - int anIndex = GEOMBase::GetIndex( aSubShape, aMainItem->getShape() ); + int anIndex = theIndices.FindIndex(aSubShape); QString anEntry = QString( "TEMP_" ) + aMainItem->getIO()->getEntry() + QString("_%1").arg( anIndex ); TreeWidgetItem* anItem = new TreeWidgetItem( theParentItem, QStringList(), aSubShape, anEntry); anItem->setVisible( false, myInvisible ); - addSubObjects( anItem ); + addSubObjects(anItem, theIndices); } } +//================================================================================= +// function : onInitFilteredData() +// purpose : add sub-objects to parent object in the filtered tree +//================================================================================= +void RepairGUI_InspectObjectDlg::onInitFilteredData() +{ + TreeWidgetItem *aMainItem = + dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); + + if (!aMainItem) { + return; + } + + // Remove the children. + SALOME_ListIO aListOfIO; + QTreeWidgetItemIterator it(aMainItem); + + while (*it) { + TreeWidgetItem* anItem = dynamic_cast(*it); + if (aMainItem != anItem && (anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + aListOfIO.Append(anItem->getIO()); + } + + ++it; + } + + myFilteredTreeObjects->clearSelection(); + myFilteredTreeObjects->headerItem()->setIcon(1, myInvisible); + getDisplayer()->Erase(aListOfIO); + getDisplayer()->UpdateViewer(); + + // Delete child items. + QList aListItems = aMainItem->takeChildren(); + + foreach (QTreeWidgetItem *anItem, aListItems) { + delete anItem; + } + + // Initialize the tree with a new list. + TopoDS_Shape aShape = aMainItem->getShape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + + myShapeTypeBtnGrp->button(TYPE_FACE)->setVisible(aShapeType < TYPE_FACE); + myShapeTypeBtnGrp->button(TYPE_EDGE)->setVisible(aShapeType < TYPE_EDGE); + myShapeTypeBtnGrp->button(TYPE_VERTEX)->setVisible(aShapeType < TYPE_VERTEX); + + int anId = myShapeTypeBtnGrp->checkedId(); + + myMaxTol = -RealLast(); + myMinTol = RealLast(); + + if (anId != -1 && myShapeTypeBtnGrp->checkedButton()->isVisible()) { + // Get sub-shapes + TopTools_MapOfShape aMapFence; + TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)anId); + TopTools_IndexedMapOfShape anIndices; + + TopExp::MapShapes(aShape, anIndices); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aSubShape = anExp.Current(); + + if (aMapFence.Add(aSubShape)) { + // Compute tolerance + Standard_Real aTolerance = -1.; + + switch (aSubShape.ShapeType()) { + case TYPE_FACE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape)); + break; + case TYPE_EDGE: + aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape)); + break; + case TYPE_VERTEX: + aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape)); + break; + default: + break; + } + + if (aTolerance < 0.) { + continue; + } + + if (aTolerance > myMaxTol) { + myMaxTol = aTolerance; + } + + if (aTolerance < myMinTol) { + myMinTol = aTolerance; + } + + int anIndex = anIndices.FindIndex(aSubShape); + QString anEntry = QString( "TEMP_" ) + + aMainItem->getIO()->getEntry() + + QString::number(anIndex); + TreeWidgetItem* anItem = + new TreeWidgetItem(aMainItem, QStringList(), + aSubShape, anEntry, aTolerance); + anItem->setVisible( false, myInvisible ); + } + } + } + + // Compose names of sub-items if the main item is expanded. + if (aMainItem->isExpanded()) { + onItemExpanded(aMainItem); + } + + myMaxTolResetBtn->setEnabled(myMaxTol >= myMinTol); + myMinTolResetBtn->setEnabled(myMaxTol >= myMinTol); + + if (myMaxTol < myMinTol) { + myMinTol = DEFAULT_TOLERANCE_VALUE; + myMaxTol = DEFAULT_TOLERANCE_VALUE; + myMinTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); + myMaxTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); + myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); + } else { + myMinTolValLabel->setText(QString::number(myMinTol)); + myMaxTolValLabel->setText(QString::number(myMaxTol)); + + if (GEOMUtils::CompareToleranceValues(myMinTol, myTolEdit->value()) == 1) { + clickOnResetToMin(); + } else if (GEOMUtils::CompareToleranceValues + (myMaxTol, myTolEdit->value()) == -1) { + clickOnResetToMax(); + } else { + onFilterData(); + } + } +} + +//================================================================================= +// function : onFilterData() +// purpose : filter objects in the filtered tree +//================================================================================= +void RepairGUI_InspectObjectDlg::onFilterData() +{ + TreeWidgetItem *aMainItem = + dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); + + if (!aMainItem) { + return; + } + + SALOME_ListIO aListOfIOToHide; + QTreeWidgetItemIterator anIt(aMainItem); + const int aCompValue = + myComparisonCompo->itemData(myComparisonCompo->currentIndex()).toInt(); + const double aTolValue = myTolEdit->value(); + + while (*anIt) { + TreeWidgetItem* anItem = dynamic_cast(*anIt); + + if (aMainItem != anItem) { + const bool isToFilter = !GEOMUtils::IsFitCondition + ((GEOMUtils::ComparisonCondition) aCompValue, + anItem->getTolerance(), aTolValue); + + if (isToFilter && !anItem->isHidden()) { + if (anItem->isVisible()) { + aListOfIOToHide.Append(anItem->getIO()); + } + + anItem->setVisible(false, myInvisible); + } + + anItem->setHidden(isToFilter); + } + + ++anIt; + } + + if (!aListOfIOToHide.IsEmpty()) { + getDisplayer()->Erase(aListOfIOToHide); + getDisplayer()->UpdateViewer(); + } + + checkVisibleIcon(); +} + //================================================================================= // function : displayItem() // purpose : display sub-object of inspected object according its tree item @@ -402,7 +766,7 @@ void RepairGUI_InspectObjectDlg::addSubObjects( TreeWidgetItem* theParentItem ) void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem ) { GEOM_Displayer* aDisplayer = getDisplayer(); - if ( theItem == myTreeObjects->topLevelItem(0) ) { + if ( theItem == myCurrentTreeObjects->topLevelItem(0) ) { aDisplayer->UnsetColor(); aDisplayer->UnsetWidth(); } @@ -423,7 +787,7 @@ void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem ) //================================================================================= void RepairGUI_InspectObjectDlg::setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible ) { - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( theItem->getShape() ) ) @@ -440,9 +804,14 @@ void RepairGUI_InspectObjectDlg::setMainObjectTransparency( double theTransparen { SUIT_ViewManager* aViewMan = myViewWindow->getViewManager(); SALOME_View* aView = dynamic_cast( aViewMan->getViewModel() ); - SalomeApp_Study* aStudy = dynamic_cast( myApp->activeStudy() ); + SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); + + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + + if (!aMainItem) { + return; + } - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); aStudy->setObjectProperty( myViewWindow->getViewManager()->getGlobalId(), QString( aMainItem->getIO()->getEntry() ), GEOM::propertyName( GEOM::Transparency ), theTransparency ); @@ -468,8 +837,8 @@ void RepairGUI_InspectObjectDlg::restoreParam() setMainObjectTransparency( myTransparency ); // erase sub-shapes - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); - QTreeWidgetItemIterator it( myTreeObjects ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { if ( *it != aMainItem ) { TreeWidgetItem* anItem = dynamic_cast(*it); @@ -496,6 +865,7 @@ void RepairGUI_InspectObjectDlg::onEditMainShape() myEditMainShape->setText(""); myEditMainShape->setFocus(); myTreeObjects->clear(); + myFilteredTreeObjects->clear(); } //================================================================================= @@ -533,7 +903,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th return; // rename the same items in the tree - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( dynamic_cast( theItem )->getShape() ) ) @@ -548,7 +918,7 @@ void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int th //================================================================================= void RepairGUI_InspectObjectDlg::onItemExpanded( QTreeWidgetItem* theItem ) { - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); for ( int i = 0; i < theItem->childCount(); i++ ) { @@ -573,13 +943,13 @@ void RepairGUI_InspectObjectDlg::onItemSelectionChanged() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); SALOME_ListIO aSelected; for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); aSelected.Append( anItem->getIO() ); } - myApp->selectionMgr()->setSelectedObjects( aSelected ); + myGeomGUI->getApp()->selectionMgr()->setSelectedObjects( aSelected ); } //================================================================================= @@ -595,12 +965,13 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) if ( myIsSelectAll ) { myIsSelectAll = false; - myTreeObjects->headerItem()->setIcon( 1, myInvisible ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); SALOME_ListIO aListOfIO; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } @@ -610,11 +981,12 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) } else { myIsSelectAll = true; - myTreeObjects->headerItem()->setIcon( 1, myVisible ); - QTreeWidgetItemIterator it( myTreeObjects ); + myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && !anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + !anItem->isVisible() ) { displayItem( anItem ); anItem->setVisible( true, myVisible ); } @@ -631,8 +1003,68 @@ void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) //================================================================================= void RepairGUI_InspectObjectDlg::onViewSelectionChanged() { - if ( myEditMainShape->isEnabled() ) - init(); + if (!myEditMainShape->isEnabled()) + return; + + //get shape from selection + SALOME_ListIO selected; + myGeomGUI->getApp()->selectionMgr()->selectedObjects(selected); + + if ( selected.Extent() != 1 ) + return; + + if ( !myViewWindow ) { + SUIT_ViewManager* occVm = myGeomGUI->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ); + myViewWindow = occVm->getActiveView(); + connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); + } + + TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); + if ( aShape.IsNull() ) + return; + + Handle(SALOME_InteractiveObject) anIO = selected.First(); + GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); + QString aName = anObject->GetName(); + CORBA::String_var anEntry = anObject->GetStudyEntry(); + + myEditMainShape->setText( aName ); + myEditMainShape->setEnabled( false ); + + // remember initial transparency value + SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); + QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(), + QString( anEntry.in() ), + GEOM::propertyName( GEOM::Transparency ), myTransparency ); + if ( v.canConvert( QVariant::Double ) ) + myTransparency = v.toDouble(); + + TreeWidgetItem* anItem = new TreeWidgetItem + (myTreeObjects, QStringList() << aName, aShape, anIO); + TreeWidgetItem* anItemFiltered = new TreeWidgetItem + (myFilteredTreeObjects, QStringList() << aName, aShape, anIO); + + if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) { + anItem->setVisible( true, myVisible ); + anItemFiltered->setVisible( true, myVisible ); + } else { + anItem->setVisible( false, myInvisible ); + anItemFiltered->setVisible( false, myInvisible ); + } + + setMainObjectTransparency( 0.5 ); + + // add sub-objects in the tree + TopTools_IndexedMapOfShape anIndices; + + TopExp::MapShapes(aShape, anIndices); + addSubObjects(anItem, anIndices); + onInitFilteredData(); + updateViewer(false); + + // check icon for tree header + checkVisibleIcon(); } //================================================================================= @@ -654,9 +1086,9 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind } myViewWindow = theViewWindow; - if ( myTreeObjects->topLevelItemCount() > 0 ) { + if ( myCurrentTreeObjects->topLevelItemCount() > 0 ) { setMainObjectTransparency( 0.5 ); - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); if ( getDisplayer()->IsDisplayed( aMainItem->getIO()->getEntry() ) ) aMainItem->setVisible( true, myVisible ); else @@ -671,7 +1103,7 @@ void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWind //================================================================================= void RepairGUI_InspectObjectDlg::onCloseView( SUIT_ViewWindow* ) { - if ( myApp->desktop()->windows().size() == 0 ) { + if ( myGeomGUI->getApp()->desktop()->windows().size() == 0 ) { restoreParam(); myViewWindow = 0; } @@ -686,7 +1118,7 @@ void RepairGUI_InspectObjectDlg::clickOnShow() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( !anItem->isVisible() ) { @@ -708,10 +1140,11 @@ void RepairGUI_InspectObjectDlg::clickOnShowOnly() return; SALOME_ListIO aListOfIO; - QTreeWidgetItemIterator it( myTreeObjects ); + QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); - if ( ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { + if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && + anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } @@ -731,7 +1164,7 @@ void RepairGUI_InspectObjectDlg::clickOnHide() if ( !myViewWindow ) return; - QList listItem = myTreeObjects->selectedItems(); + QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( anItem->isVisible() ) { @@ -749,14 +1182,19 @@ void RepairGUI_InspectObjectDlg::clickOnHide() //================================================================================= void RepairGUI_InspectObjectDlg::clickOnPublish() { - _PTR(Study) studyDS = dynamic_cast( myApp->activeStudy() )->studyDS(); + _PTR(Study) studyDS = dynamic_cast( myGeomGUI->getApp()->activeStudy() )->studyDS(); // find main object - TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); + TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); + + if (!aMainItem) { + return; + } + GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); // find unique indices of selected objects - QList selectedItems = myTreeObjects->selectedItems(); + QList selectedItems = myCurrentTreeObjects->selectedItems(); QMap< int, QString > anIndices; GEOM::ListOfLong_var anArray = new GEOM::ListOfLong; anArray->length( selectedItems.size() ); @@ -790,5 +1228,139 @@ void RepairGUI_InspectObjectDlg::clickOnPublish() //================================================================================= void RepairGUI_InspectObjectDlg::clickOnHelp() { - myApp->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" ); + myGeomGUI->getApp()->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" ); +} + +//================================================================================= +// function : clickOnResetToMin() +// purpose : called when Reset button was clicked to reset tolerance filter to minimal value. +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnResetToMin() +{ + if (myMinTol >= myTolEdit->minimum() && myMinTol <= myTolEdit->maximum()) { + myTolEdit->setValue(myMinTol); + } +} + +//================================================================================= +// function : clickOnResetToMax() +// purpose : called when Reset button was clicked to reset tolerance filter to maximal value. +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnResetToMax() +{ + if (myMaxTol >= myTolEdit->minimum() && myMaxTol <= myTolEdit->maximum()) { + myTolEdit->setValue(myMaxTol); + } +} + +//================================================================================= +// function : clickOnShowAll() +// purpose : called when Help button was clicked to show all shapes +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnShowAll() +{ + myIsSelectAll = false; + onHeaderClicked(1); +} + +//================================================================================= +// function : clickOnHideAll() +// purpose : called when Help button was clicked to hide all shapes +//================================================================================= +void RepairGUI_InspectObjectDlg::clickOnHideAll() +{ + myIsSelectAll = true; + onHeaderClicked(1); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::DeactivateActiveDialog() +{ + setEnabled(false); + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + myGeomGUI->SetActiveDialogBox(0); + globalSelection(); + erasePreview(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + myGeomGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + myGeomGUI->SetActiveDialogBox( (QDialog*)this ); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(onViewSelectionChanged())); + + updateViewer(false); +} + +//================================================================================= +// function : onFilterToggled() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::onFilterToggled(bool isOn) +{ + if (isOn) { + myCurrentTreeObjects = myFilteredTreeObjects; + myTreesLayout->setCurrentIndex(1); + } else { + myCurrentTreeObjects = myTreeObjects; + myTreesLayout->setCurrentIndex(0); + } + + updateViewer(true); +} + +//================================================================================= +// function : updateViewer() +// purpose : +//================================================================================= +void RepairGUI_InspectObjectDlg::updateViewer(const bool theIsHideOtherTree) +{ + GEOM_Displayer *aDisplayer = getDisplayer(); + + if (theIsHideOtherTree) { + QTreeWidget *aTreeToHide = myCurrentTreeObjects == myTreeObjects ? + myFilteredTreeObjects: myTreeObjects; + + // Hide the objects of disappeared tree, do not switch off flags. + SALOME_ListIO aListOfIO; + QTreeWidgetItemIterator it(aTreeToHide); + + while (*it) { + TreeWidgetItem* anItem = dynamic_cast(*it); + if ((anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + aListOfIO.Append(anItem->getIO()); + } + + ++it; + } + + aDisplayer->Erase(aListOfIO); + } + + // Show the objects that are marked as shown in the appeared tree. + QTreeWidgetItemIterator it2(myCurrentTreeObjects); + + while (*it2) { + TreeWidgetItem* anItem = dynamic_cast(*it2); + if ((anItem->flags() & Qt::ItemIsSelectable) && + anItem->isVisible() && !anItem->isHidden()) { + displayItem(anItem); + } + + ++it2; + } + + aDisplayer->UpdateViewer(); } diff --git a/src/RepairGUI/RepairGUI_InspectObjectDlg.h b/src/RepairGUI/RepairGUI_InspectObjectDlg.h index d696ac904..d8ffff0d4 100644 --- a/src/RepairGUI/RepairGUI_InspectObjectDlg.h +++ b/src/RepairGUI/RepairGUI_InspectObjectDlg.h @@ -25,10 +25,23 @@ // Qt includes #include -#include -#include -#include #include +#include + +class GeometryGUI; +class SalomeApp_DoubleSpinBox; + +class QButtonGroup; +class QComboBox; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QStackedLayout; +class QTreeWidget; +class QTreeWidgetItem; + +class TopTools_IndexedMapOfShape; class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper { @@ -38,7 +51,7 @@ class RepairGUI_InspectObjectDlg : public QDialog, public GEOMBase_Helper class Delegate; public: - RepairGUI_InspectObjectDlg( SUIT_Desktop* ); + RepairGUI_InspectObjectDlg(GeometryGUI*, SUIT_Desktop* ); ~RepairGUI_InspectObjectDlg(); private slots: @@ -60,25 +73,54 @@ private slots: void clickOnHide(); void clickOnPublish(); void clickOnHelp(); + void clickOnResetToMin(); + void clickOnResetToMax(); + void clickOnShowAll(); + void clickOnHideAll(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onFilterToggled(bool); + void onInitFilteredData(); + void onFilterData(); private: + void createTreeWidget(QTreeWidget *&theTreeObjects); void init(); + void initSpinBox(SalomeApp_DoubleSpinBox* spinBox, + double min, double max, + double step, const char* quantity); + void initTreeWidget(QTreeWidget *theTopLevelItem); + void enterEvent( QEvent* ); void checkVisibleIcon(); - void addSubObjects( TreeWidgetItem* ); + void addSubObjects( TreeWidgetItem*, const TopTools_IndexedMapOfShape &); + void displayItem( TreeWidgetItem* ); void setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible ); void setMainObjectTransparency( double ); void restoreParam(); + void updateViewer(const bool theIsHideOtherTree); - SalomeApp_Application* myApp; QPointer myViewWindow; + GeometryGUI* myGeomGUI; QIcon myVisible; QIcon myInvisible; - QTreeWidget* myTreeObjects; - QLineEdit* myEditMainShape; - + QTreeWidget *myTreeObjects; + QTreeWidget *myFilteredTreeObjects; + QTreeWidget *myCurrentTreeObjects; + QLineEdit *myEditMainShape; + QGroupBox *myTolFilterGrp; + QButtonGroup *myShapeTypeBtnGrp; + QComboBox *myComparisonCompo; + SalomeApp_DoubleSpinBox *myTolEdit; + QLabel *myMinTolValLabel; + QLabel *myMaxTolValLabel; + QStackedLayout *myTreesLayout; + QPushButton *myMinTolResetBtn; + QPushButton *myMaxTolResetBtn; + double myMaxTol; + double myMinTol; bool myIsSelectAll; double myTransparency;