From: skv Date: Tue, 3 Nov 2015 08:38:55 +0000 (+0300) Subject: 0023193: [CEA] Show sub-shapes with given tolerance X-Git-Tag: V8_0_0a1~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e6bcaa307fef3efd962a0959d0830ccb7dc659fb;p=modules%2Fgeom.git 0023193: [CEA] Show sub-shapes with given tolerance --- diff --git a/doc/salome/gui/GEOM/images/inspect_object.png b/doc/salome/gui/GEOM/images/inspect_object.png index 09d90d069..23065bd2e 100644 Binary files a/doc/salome/gui/GEOM/images/inspect_object.png and b/doc/salome/gui/GEOM/images/inspect_object.png differ 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 000000000..121e15275 Binary files /dev/null and b/doc/salome/gui/GEOM/images/inspect_object2.png differ 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 **********************/ - - 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 ) ); + /********************** Tolerance filter **********************/ + + 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; - - if ( !myViewWindow ) { - SUIT_ViewManager* occVm = myApp->getViewManager( OCCViewer_Viewer::Type(), true ); - myViewWindow = occVm->getActiveView(); - connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), - this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); - } + initSpinBox(myTolEdit, 0., 100., DEFAULT_TOLERANCE_VALUE, "len_tol_precision"); + myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); - TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); - if ( aShape.IsNull() ) - return; + // 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() ) ); - Handle(SALOME_InteractiveObject) anIO = selected.First(); - GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); - QString aName = anObject->GetName(); - CORBA::String_var anEntry = anObject->GetStudyEntry(); + connect( myGeomGUI->getApp()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), + this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); - myEditMainShape->setText( aName ); - myEditMainShape->setEnabled( false ); + // 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())); - // 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(); + if ( myViewWindow ) + connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); - TreeWidgetItem* anItem = new TreeWidgetItem( myTreeObjects, QStringList() << aName, aShape, anIO ); - if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) - anItem->setVisible( true, myVisible ); - else - anItem->setVisible( false, myInvisible ); + // Initialize the dialog with current selection. + onViewSelectionChanged(); +} - setMainObjectTransparency( 0.5 ); +//================================================================================= +// 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 ) ) ); +} - // add sub-objects in the tree - addSubObjects( anItem ); +//================================================================================= +// 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())); + + connect(theTreeObjects->header(), SIGNAL(sectionClicked(int)), + this, SLOT(onHeaderClicked(int))); +} - // 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;