From: akl Date: Tue, 28 Apr 2015 08:21:22 +0000 (+0400) Subject: 0022762: [EDF] Fast detection of face/face face/solid solid/solid interference X-Git-Tag: V7_7_0a1~24 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=7c036f24ffc367e0d6d83240860a5c39591d25aa;p=modules%2Fgeom.git 0022762: [EDF] Fast detection of face/face face/solid solid/solid interference - Part 2: introduce CheckSelfIntersectionsFast function --- diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index a437b4078..e9dc70f96 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -56,6 +56,7 @@ SET(GOOD_TESTS center_of_mass.py check_compound_of_blocks.py check_self_intersections.py + check_self_intersections_fast.py check_shape.py complex_objs_ex01.py complex_objs_ex02.py diff --git a/doc/salome/examples/check_self_intersections.py b/doc/salome/examples/check_self_intersections.py index 8df91b9fe..f70a54540 100644 --- a/doc/salome/examples/check_self_intersections.py +++ b/doc/salome/examples/check_self_intersections.py @@ -7,9 +7,15 @@ from salome.geom import geomBuilder geompy = geomBuilder.New(salome.myStudy) # create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -IsValid = geompy.CheckSelfIntersections(box) -if IsValid == 0: - raise RuntimeError, "Box with self-intersections created" +box = geompy.MakeBoxDXDYDZ(100,100,100) +# create a cylinder +cylinder = geompy.MakeCylinderRH(100, 300) +# make a compound +compound = geompy.MakeCompound([box, cylinder]) + +# check self-intersection +IsValid = geompy.CheckSelfIntersections(compound) +if not IsValid: + print "Shape is self-intersected!" else: - print "\nBox is valid" + print "No self-intersection detected in a shape" diff --git a/doc/salome/examples/check_self_intersections_fast.py b/doc/salome/examples/check_self_intersections_fast.py new file mode 100644 index 000000000..83c8a741e --- /dev/null +++ b/doc/salome/examples/check_self_intersections_fast.py @@ -0,0 +1,21 @@ +# Detect Self-intersections fast + +import salome +salome.salome_init() +import GEOM +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +# create a box +box = geompy.MakeBoxDXDYDZ(100,100,100) +# create a cylinder +cylinder = geompy.MakeCylinderRH(100, 300) +# make a compound +compound = geompy.MakeCompound([box, cylinder]) + +# check self-intersection +IsValid = geompy.CheckSelfIntersectionsFast(compound) +if not IsValid: + print "Shape is self-intersected!" +else: + print "No self-intersection detected in a shape" diff --git a/doc/salome/gui/GEOM/images/measures11.png b/doc/salome/gui/GEOM/images/measures11.png index 6ee449874..562714d31 100644 Binary files a/doc/salome/gui/GEOM/images/measures11.png and b/doc/salome/gui/GEOM/images/measures11.png differ diff --git a/doc/salome/gui/GEOM/images/measures13.png b/doc/salome/gui/GEOM/images/measures13.png new file mode 100644 index 000000000..6e9deb566 Binary files /dev/null and b/doc/salome/gui/GEOM/images/measures13.png differ diff --git a/doc/salome/gui/GEOM/input/check_self_intersections.doc b/doc/salome/gui/GEOM/input/check_self_intersections.doc index 41658151a..f806d4dd6 100644 --- a/doc/salome/gui/GEOM/input/check_self_intersections.doc +++ b/doc/salome/gui/GEOM/input/check_self_intersections.doc @@ -2,6 +2,14 @@ \page check_self_intersections_page Detect Self-intersections +\n To Detect Self-intersections in the Main Menu select +Inspection - > Detect Self-intersections. + +There are two ways to check self-intersections. + +\anchor check_self_intersections_topological +

Check topological intersections

+ This operation checks the topology of the selected shape to detect self-intersections. \image html measures11.png @@ -29,5 +37,28 @@ where: \n See also a \ref tui_check_self_intersections_page "TUI example". +\anchor check_self_intersections_fast +

Fast intersection

+ +This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections. + +\image html measures13.png + +This algorithm works on the faces level, i.e. it computes only face-to-face intersections. No additional types of intersections is computed. +This case can be useful in order to detect all the intersections between the subshapes of type "surface" inside assembly. +Quality of result will depend on the quality of tesselation (managed via the deflection parameter). However, small values of deflection can +significantly decrease performance of the algorithm. +Nevertheless, performance of Fast Intersect algorithm is much higher than topological intersection. + +\n Result: Boolean. +\n TUI Command: geompy.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance), \n +where: \n +\em theShape is the shape checked for validity. \n +\em theDeflection is a linear deflection coefficient that specifies quality of tesselation. If theDeflection <= 0, default deflection 0.001 is used. +\em theTolerance Specifies a distance between shapes used for detecting gaps: + - if theTolerance <= 0, algorithm detects intersections; + - if theTolerance > 0, algorithm detects gaps. + +See also a \ref tui_check_self_intersections_fast_page "TUI example". */ \ No newline at end of file diff --git a/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc b/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc new file mode 100644 index 000000000..c8266e331 --- /dev/null +++ b/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc @@ -0,0 +1,6 @@ +/*! + +\page tui_check_self_intersections_fast_page Detect Self-intersections fast +\tui_script{check_self_intersections_fast.py} + +*/ diff --git a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc index 6e83325c3..be111dbb1 100644 --- a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc @@ -19,6 +19,7 @@
  • \subpage tui_check_compound_of_blocks_page
  • \subpage tui_get_non_blocks_page
  • \subpage tui_check_self_intersections_page
  • +
  • \subpage tui_check_self_intersections_fast_page
  • \subpage tui_fast_intersection_page
  • diff --git a/doc/salome/gui/GEOM/input/tui_test_measures.doc b/doc/salome/gui/GEOM/input/tui_test_measures.doc index b954b7f60..3e147f388 100644 --- a/doc/salome/gui/GEOM/input/tui_test_measures.doc +++ b/doc/salome/gui/GEOM/input/tui_test_measures.doc @@ -17,7 +17,10 @@ \until Detect Self-intersections \anchor swig_CheckSelfIntersections -\until Detect Fast intersection +\until Detect Self-intersections fast + +\anchor swig_CheckSelfIntersectionsFast +\until Fast intersection \anchor swig_FastIntersection \until WhatIs diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 87a912edc..88edc8f07 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4448,6 +4448,21 @@ module GEOM in long theCheckLevel, out ListOfLong theIntersections); + /*! + * \brief Detect self-intersections of the given shape with algorithm based on mesh intersections. + * \param theShape Shape to check validity of. + * \param theDeflection Linear deflection coefficient that specifies quality of tesselation. + * \param theTolerance Specifies a distance between sub-shapes used for detecting gaps: + * - if \a theTolerance <= 0, algorithm detects intersections + * - if \a theTolerance > 0, algorithm detects gaps + * \param theIntersections Output. List of intersected sub-shapes IDs, it contains pairs of IDs. + * \return TRUE, if the shape does not have any self-intersections. + */ + boolean CheckSelfIntersectionsFast (in GEOM_Object theShape, + in float theDeflection, + in double theTolerance, + out ListOfLong theIntersections); + /*! * \brief Detect intersections of the given shapes with algorithm based on mesh intersections. * \param theShape1 First source object diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 8c43d9c84..9d86a99db 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -7274,6 +7274,10 @@ Do you want to create new material? MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS Self-intersections @@ -7338,6 +7342,14 @@ Do you want to create new material? GEOM_CHECK_INTE_ALL Face to Face + all above + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 0d8d4623c..06169dafb 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -7274,6 +7274,10 @@ Voulez-vous en créer un nouveau ? MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS Auto-intersections @@ -7338,6 +7342,14 @@ Voulez-vous en créer un nouveau ? GEOM_CHECK_INTE_ALL Face à Face + tout au-delà + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 6efba76e0..a92a3e60b 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -7271,6 +7271,10 @@ MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS 自己交差 @@ -7335,6 +7339,14 @@ GEOM_CHECK_INTE_ALL 面から面と上記すべて + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index d1d23d51c..5e33ac622 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -50,8 +50,9 @@ #include #include #include -#if OCC_VERSION_LARGE > 0x06080000 #include +#if OCC_VERSION_LARGE > 0x06090000 +#include #endif #include #include @@ -71,10 +72,13 @@ #include #include #include +#include #include #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC +#include + //============================================================================= /*! * Constructor @@ -1510,7 +1514,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections Handle(TColStd_HSequenceOfInteger)& theIntersections) { SetErrorCode(KO); - bool isGood = false; if (theIntersections.IsNull()) theIntersections = new TColStd_HSequenceOfInteger; @@ -1518,13 +1521,13 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections theIntersections->Clear(); if (theShape.IsNull()) - return isGood; + return false; Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return isGood; + if (aRefShape.IsNull()) return false; TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) return isGood; + if (aShape.IsNull()) return false; // 0. Prepare data TopoDS_Shape aScopy; @@ -1546,7 +1549,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections aCSI.Perform(); Standard_Integer iErr = aCSI.ErrorStatus(); - isGood = true; // Standard_Integer aNbS, n1, n2; BOPDS_MapIteratorMapOfPassKey aItMPK; @@ -1570,14 +1572,82 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections theIntersections->Append(anIndices.FindIndex(aS1)); theIntersections->Append(anIndices.FindIndex(aS2)); - isGood = false; } if (!iErr) { SetErrorCode(OK); } - return isGood; + return theIntersections->IsEmpty(); +} + +//============================================================================= +/*! + * CheckSelfIntersectionsFast + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast + (Handle(GEOM_Object) theShape, + float theDeflection, double theTolerance, + Handle(TColStd_HSequenceOfInteger)& theIntersections) +{ + SetErrorCode(KO); + + if (theIntersections.IsNull()) + theIntersections = new TColStd_HSequenceOfInteger; + else + theIntersections->Clear(); + + if (theShape.IsNull()) + return false; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return false; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return false; + + // Prepare data + TopoDS_Shape aScopy; + + GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy); + GEOMUtils::MeshShape(aScopy, theDeflection); + + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aScopy, anIndices); + +#if OCC_VERSION_LARGE > 0x06090000 + // Checker of fast interferences + BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance); + + // Launch the checker + aTool.Perform(); + + const BRepExtrema_OverlapTool::OverlapSubShapes& intersections = aTool.OverlapElements(); + + std::set processed; + + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator it(intersections); it.More(); it.Next()) { + Standard_Integer idxLeft = it.Key(); + if (processed.count(idxLeft) > 0) continue; // already added + processed.insert(idxLeft); + const TColStd_PackedMapOfInteger& overlaps = it.Value(); + for (TColStd_MapIteratorOfPackedMapOfInteger subit(overlaps); subit.More(); subit.Next()) { + Standard_Integer idxRight = subit.Key(); + if (processed.count(idxRight) > 0) continue; // already added + const TopoDS_Shape& aS1 = aTool.GetSubShape(idxLeft); + const TopoDS_Shape& aS2 = aTool.GetSubShape(idxRight); + theIntersections->Append(anIndices.FindIndex(aS1)); + theIntersections->Append(anIndices.FindIndex(aS2)); + } + } + + if (aTool.IsDone()) + SetErrorCode(OK); +#endif + + return theIntersections->IsEmpty(); } //============================================================================= @@ -1593,8 +1663,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, SetErrorCode(KO); bool isGood = false; -#if OCC_VERSION_LARGE > 0x06080000 - if (theIntersections1.IsNull()) theIntersections1 = new TColStd_HSequenceOfInteger; else @@ -1646,12 +1714,22 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, aBSP.Perform(); // 2. Get sets of IDs of overlapped faces - for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { +#if OCC_VERSION_LARGE > 0x06090000 + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) +#else + for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) +#endif + { const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key()); theIntersections1->Append(anIndices1.FindIndex(aS1)); } - for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { +#if OCC_VERSION_LARGE > 0x06090000 + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) +#else + for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) +#endif + { const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key()); theIntersections2->Append(anIndices2.FindIndex(aS2)); } @@ -1661,8 +1739,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, if (aBSP.IsDone()) SetErrorCode(OK); -#endif // OCC_VERSION_LARGE > 0x06080000 - return isGood; } diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 3798af25e..e81e5db1f 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -158,6 +158,11 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { const SICheckLevel theCheckLevel, Handle(TColStd_HSequenceOfInteger)& theIntersections); + Standard_EXPORT bool CheckSelfIntersectionsFast (Handle(GEOM_Object) theShape, + float deflection, + double tolerance, + Handle(TColStd_HSequenceOfInteger)& theIntersections); + Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, double tolerance, float deflection, Handle(TColStd_HSequenceOfInteger)& theIntersections1, diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index f75787a3c..407d71f05 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -765,6 +765,49 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Obj return isGood; } +//============================================================================= +/*! + * CheckSelfIntersectionsFast + */ +//============================================================================= +CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersectionsFast + (GEOM::GEOM_Object_ptr theShape, + CORBA::Float theDeflection, + CORBA::Double theTolerance, + GEOM::ListOfLong_out theIntersections) +{ + // Set a not done flag + GetOperations()->SetNotDone(); + + bool isGood = false; + + // Allocate the CORBA arrays + GEOM::ListOfLong_var anIntegersArray = new GEOM::ListOfLong(); + + // Get the reference shape + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (!aShape.IsNull()) { + Handle(TColStd_HSequenceOfInteger) anIntegers = new TColStd_HSequenceOfInteger; + + // Detect self-intersections + isGood = GetOperations()->CheckSelfIntersectionsFast + (aShape, theDeflection, theTolerance, anIntegers); + + int nbInts = anIntegers->Length(); + + anIntegersArray->length(nbInts); + + for (int ii = 0; ii < nbInts; ii++) { + anIntegersArray[ii] = anIntegers->Value(ii + 1); + } + } + + // Initialize out-parameters with local arrays + theIntersections = anIntegersArray._retn(); + return isGood; +} + //============================================================================= /*! * FastIntersect diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index 27e2e5d42..71e6194ba 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -100,6 +100,11 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Long theCheckLevel, GEOM::ListOfLong_out theIntersections); + CORBA::Boolean CheckSelfIntersectionsFast (GEOM::GEOM_Object_ptr theShape, + CORBA::Float theDeflection, + CORBA::Double theTolerance, + GEOM::ListOfLong_out theIntersections); + CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1, GEOM::GEOM_Object_ptr theShape2, CORBA::Double theTolerance, diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index 87c9a0d11..7ad571552 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -33,8 +33,12 @@ def TestMeasureOperations (geompy, math): p678 = geompy.MakeVertex(60, 70, 80) p789 = geompy.MakeVertex(70, 80, 90) + vz = geompy.MakeVectorDXDYDZ(0, 0, 1) + cube = geompy.MakeBoxTwoPnt(p678, p789) + cylinder = geompy.MakeCylinder(p0, vz, 5, 70) + ####### PointCoordinates ####### Coords = geompy.PointCoordinates(p137) @@ -52,18 +56,20 @@ def TestMeasureOperations (geompy, math): ####### Detect Self-intersections ####### - [Face_1,Face_2] = geompy.SubShapes(box, [33, 23]) - Translation_1 = geompy.MakeTranslation(Face_1, 5, -15, -40) - Compound_1 = geompy.MakeCompound([Face_2, Translation_1]) - if geompy.CheckSelfIntersections(Compound_1) == True: + selfIntersected = geompy.MakeCompound([box, cylinder]) + if geompy.CheckSelfIntersections(selfIntersected): raise RuntimeError, "Existing self-intersection is not detected" - ####### Detect Fast intersection ####### + ####### Detect Self-intersections fast ####### + + if salome_version.getXVersion() > "0x70600": + if geompy.CheckSelfIntersectionsFast(selfIntersected): + raise RuntimeError, "Existing self-intersection is not detected" + + ####### Fast intersection ####### - if salome_version.getXVersion() > "0x70501": - cylinder = geompy.MakeCylinderRH(100, 300) - if geompy.FastIntersect(box, cylinder)[0] == False: - raise RuntimeError, "Existing intersection is not detected" + if not geompy.FastIntersect(box, cylinder)[0]: + raise RuntimeError, "Existing intersection is not detected" ####### WhatIs ####### diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index f932a632a..982a45dc5 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -11257,6 +11257,37 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("CheckSelfIntersections", self.MeasuOp) return IsValid + ## Detect self-intersections of the given shape with algorithm based on mesh intersections. + # @param theShape Shape to check. + # @param theDeflection Linear deflection coefficient that specifies quality of tesselation: + # - if \a theDeflection <= 0, default deflection 0.001 is used + # @param theTolerance Specifies a distance between sub-shapes used for detecting gaps: + # - if \a theTolerance <= 0, algorithm detects intersections (default behavior) + # - if \a theTolerance > 0, algorithm detects gaps + # @return TRUE, if the shape contains no self-intersections. + # + # @ref tui_check_self_intersections_fast_page "Example" + @ManageTransactions("MeasuOp") + def CheckSelfIntersectionsFast(self, theShape, theDeflection = 0.001, theTolerance = 0.0): + """ + Detect self-intersections of the given shape with algorithm based on mesh intersections. + + Parameters: + theShape Shape to check. + theDeflection Linear deflection coefficient that specifies quality of tesselation: + - if theDeflection <= 0, default deflection 0.001 is used + theTolerance Specifies a distance between shapes used for detecting gaps: + - if theTolerance <= 0, algorithm detects intersections (default behavior) + - if theTolerance > 0, algorithm detects gaps + + Returns: + TRUE, if the shape contains no self-intersections. + """ + # Example: see GEOM_TestMeasures.py + (IsValid, Pairs) = self.MeasuOp.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance) + RaiseIfFailed("CheckSelfIntersectionsFast", self.MeasuOp) + return IsValid + ## Detect intersections of the given shapes with algorithm based on mesh intersections. # @param theShape1 First source object # @param theShape2 Second source object diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx index a07e919e5..97b3d170e 100644 --- a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx @@ -26,6 +26,7 @@ #include "MeasureGUI_CheckSelfIntersectionsDlg.h" #include "MeasureGUI.h" +#include #include #include #include @@ -58,81 +59,145 @@ //================================================================================= MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent) : GEOMBase_Skeleton (GUI, parent, false), - myTextView (0), - mySelButton (0), - myEditObjName (0), + myTextView1 (0), + myTextView2 (0), + mySelButton1 (0), + mySelButton2 (0), + myEditObjName1 (0), + myEditObjName2 (0), myLevelBox (0), - myComputeButton (0), - myInteList (0), - myShapeList (0) + myComputeButton1 (0), + myComputeButton2 (0), + myInteList1 (0), + myShapeList1 (0), + myInteList2 (0), + myShapeList2 (0), + myCurrConstrId (-1) { SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS"))); QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FAST_CHECK_INTERSECTIONS"))); setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); /***************************************************************/ - mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); + mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_INTERSECT_TYPE")); mainFrame()->RadioButton1->setIcon(image0); - mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); - mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton2->setIcon(image2);; mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); mainFrame()->RadioButton3->close(); - QGroupBox *aGrp = new QGroupBox(tr("GEOM_CHECK_INFOS")); - QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT")); - QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS")); - QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES")); - QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL")); - QLabel *aSummaryLbl = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); + /***************************************************************/ + /* SIMPLE SELF-INTERSECTION constructor + /***************************************************************/ + mySimpleGrp = new QGroupBox(tr("GEOM_CHECK_INFOS")); + QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT")); + QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS")); + QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES")); + QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL")); + QLabel *aSummaryLbl1 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE); aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias); - myTextView = new QTextBrowser; - myTextView->setReadOnly(true); - myTextView->setFont(aFont); + myTextView1 = new QTextBrowser; + myTextView1->setReadOnly(true); + myTextView1->setFont(aFont); - mySelButton = new QPushButton; - mySelButton->setIcon(image1); - mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mySelButton1 = new QPushButton; + mySelButton1->setIcon(image1); + mySelButton1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - myEditObjName = new QLineEdit; - myEditObjName->setReadOnly(true); + myEditObjName1 = new QLineEdit; + myEditObjName1->setReadOnly(true); myLevelBox = new QComboBox; - myComputeButton = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); + myComputeButton1 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); - myInteList = new QListWidget; - myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection); - myShapeList = new QListWidget; - myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection); + myInteList1 = new QListWidget; + myInteList1->setSelectionMode(QAbstractItemView::ExtendedSelection); + myShapeList1 = new QListWidget; + myShapeList1->setSelectionMode(QAbstractItemView::ExtendedSelection); - QGridLayout *aGrpLayout = new QGridLayout(aGrp); + QGridLayout *aGrpLayout1 = new QGridLayout(mySimpleGrp); - aGrpLayout->setMargin(9); - aGrpLayout->setSpacing(6); - aGrpLayout->addWidget(anObjLbl, 0, 0); - aGrpLayout->addWidget(anInteLbl, 5, 0); - aGrpLayout->addWidget(aShapeLbl, 5, 2); - aGrpLayout->addWidget(aLevelLbl, 1, 0); - aGrpLayout->addWidget(myLevelBox, 1, 1, 1, 2); - aGrpLayout->addWidget(myComputeButton, 2, 0, 1, 3); - aGrpLayout->addWidget(aSummaryLbl, 3, 0); - aGrpLayout->addWidget(myTextView, 4, 0, 1, 3); - aGrpLayout->addWidget(mySelButton, 0, 1); - aGrpLayout->addWidget(myEditObjName, 0, 2); - aGrpLayout->addWidget(myInteList, 6, 0, 1, 2); - aGrpLayout->addWidget(myShapeList, 6, 2); - - QVBoxLayout* layout = new QVBoxLayout (centralWidget()); - layout->setMargin(0); layout->setSpacing(6); - layout->addWidget(aGrp); + aGrpLayout1->setMargin(9); + aGrpLayout1->setSpacing(6); + aGrpLayout1->addWidget(anObjLbl, 0, 0); + aGrpLayout1->addWidget(mySelButton1, 0, 1); + aGrpLayout1->addWidget(myEditObjName1, 0, 2); + aGrpLayout1->addWidget(aLevelLbl, 1, 0); + aGrpLayout1->addWidget(myLevelBox, 1, 1, 1, 2); + aGrpLayout1->addWidget(myComputeButton1, 2, 0, 1, 3); + aGrpLayout1->addWidget(aSummaryLbl1, 3, 0); + aGrpLayout1->addWidget(myTextView1, 4, 0, 1, 3); + aGrpLayout1->addWidget(anInteLbl, 5, 0); + aGrpLayout1->addWidget(aShapeLbl, 5, 2); + aGrpLayout1->addWidget(myInteList1, 6, 0, 1, 2); + aGrpLayout1->addWidget(myShapeList1, 6, 2); + /***************************************************************/ + /* FAST SELF-INTERSECTION constructor + /***************************************************************/ + + myFastGrp = new QGroupBox(tr("GEOM_CHECK_INFOS"), centralWidget()); + QLabel *anObjLbl2 = new QLabel(tr("GEOM_OBJECT"), myFastGrp); + QLabel *aDeflectLbl = new QLabel(tr("GEOM_CHECK_INT_DEFLECT"), myFastGrp); + QLabel *aSummaryLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); + QLabel *anInteLbl2 = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"), myFastGrp); + QLabel *aShapeLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"), myFastGrp); + + mySelButton2 = new QPushButton(myFastGrp); + mySelButton2->setIcon(image1); + mySelButton2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + myEditObjName2 = new QLineEdit(myFastGrp); + myEditObjName2->setReadOnly(true); + + myDeflection = new SalomeApp_DoubleSpinBox(myFastGrp); + myDetGaps = new QCheckBox(tr( "GEOM_CHECK_INT_DETECT_GAPS" )); + myTolerance = new SalomeApp_DoubleSpinBox(myFastGrp); + + myComputeButton2 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); + + myTextView2 = new QTextBrowser; + myTextView2->setReadOnly(true); + myTextView2->setFont(aFont); + + myInteList2 = new QListWidget(myFastGrp); + myInteList2->setSelectionMode(QAbstractItemView::ExtendedSelection); + myShapeList2 = new QListWidget(myFastGrp); + myShapeList2->setSelectionMode(QAbstractItemView::ExtendedSelection); + + QGridLayout *aGrpLayout2 = new QGridLayout(myFastGrp); + aGrpLayout2->setMargin(9); + aGrpLayout2->setSpacing(6); + aGrpLayout2->addWidget(anObjLbl2, 0, 0); + aGrpLayout2->addWidget(mySelButton2, 0, 1); + aGrpLayout2->addWidget(myEditObjName2, 0, 2); + aGrpLayout2->addWidget(aDeflectLbl, 1, 0); + aGrpLayout2->addWidget(myDeflection, 1, 1, 1, 2); + aGrpLayout2->addWidget(myDetGaps, 2, 0); + aGrpLayout2->addWidget(myTolerance, 2, 1, 1, 2); + aGrpLayout2->addWidget(myComputeButton2, 3, 0, 1, 3); + aGrpLayout2->addWidget(aSummaryLbl2, 4, 0); + aGrpLayout2->addWidget(myTextView2, 5, 0, 1, 3); + aGrpLayout2->addWidget(anInteLbl2, 6, 0); + aGrpLayout2->addWidget(aShapeLbl2, 6, 1, 1, 2); + aGrpLayout2->addWidget(myInteList2, 7, 0); + aGrpLayout2->addWidget(myShapeList2, 7, 1, 1, 2); + /***************************************************************/ + QVBoxLayout* layout2 = new QVBoxLayout (centralWidget()); + layout2->setMargin(0); layout2->setSpacing(6); + layout2->addWidget(mySimpleGrp); + layout2->addWidget(myFastGrp); + + /***************************************************************/ + myHelpFileName = "check_self_intersections_page.html"; /* Initialisation */ @@ -161,32 +226,65 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init() myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F")); myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL")); myLevelBox->setCurrentIndex(GEOM::SI_ALL); + myComputeButton1->setEnabled(false); - connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), - this, SLOT(DeactivateActiveDialog())); - connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), - this, SLOT(ClickOnCancel())); - connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); - connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); - connect(mySelButton, SIGNAL(clicked()), + connect(mySelButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(myInteList, SIGNAL(itemSelectionChanged()), + connect(myInteList1, SIGNAL(itemSelectionChanged()), SLOT(onInteListSelectionChanged())); - connect(myShapeList, SIGNAL(itemSelectionChanged()), + connect(myShapeList1, SIGNAL(itemSelectionChanged()), SLOT(onSubShapesListSelectionChanged())); connect(myLevelBox, SIGNAL(currentIndexChanged(int)), this, SLOT(clear())); - connect(myComputeButton, SIGNAL(clicked()), this, SLOT(onCompute())); + connect(myComputeButton1, SIGNAL(clicked()), this, SLOT(onCompute())); - LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); + /***************************************************************/ + myObj2.nullify(); + myEditObjName2->setText(""); + myEditObjName2->setEnabled(true); + + myDetGaps->setChecked(false); + initSpinBox(myTolerance, 0, MAX_NUMBER, 1); + myTolerance->setValue(0); + myTolerance->setEnabled(false); + myComputeButton2->setEnabled(false); + + // Obtain deflection from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + initSpinBox(myDeflection, 1e-3, 1.0, 1e-3); + myDeflection->setValue(qMax(1e-3, resMgr->doubleValue("Geometry", "deflection_coeff", 1e-3))); + + connect( mySelButton2, SIGNAL(clicked()), + this, SLOT(SetEditCurrentArgument())); + connect( myDetGaps, SIGNAL(toggled(bool)), this, SLOT(OnGaps(bool))); + connect( myTolerance, SIGNAL(valueChanged(double)), this, SLOT(clear())); + connect( myDeflection, SIGNAL(valueChanged(double)), this, SLOT(clear())); + connect( myInteList2, SIGNAL(itemSelectionChanged()), + SLOT(onInteListSelectionChanged())); + connect( myShapeList2, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect( myComputeButton2, SIGNAL(clicked()), this, SLOT(onCompute())); + /***************************************************************/ + + connect(this, SIGNAL(constructorsClicked(int)), + this, SLOT(ConstructorsClicked(int))); + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), + this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), + this, SLOT(ClickOnCancel())); + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); connect(aSel, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); initName( tr( "GEOM_SELF_INTERSECTION_NAME") ); buttonOk()->setEnabled(false); buttonApply()->setEnabled(false); - myComputeButton->setEnabled(false); + + ConstructorsClicked(0); + activateSelection(); SelectionIntoArgument(); } @@ -197,20 +295,56 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init() //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::clear() { - myTextView->setText(""); + getTextView()->setText(""); + getComputeButton()->setEnabled(true); - myInteList->blockSignals(true); - myShapeList->blockSignals(true); - myInteList->clear(); - myShapeList->clear(); - myInteList->blockSignals(false); - myShapeList->blockSignals(false); + getInteList()->blockSignals(true); + getShapeList()->blockSignals(true); + getInteList()->clear(); + getShapeList()->clear(); + getInteList()->blockSignals(false); + getShapeList()->blockSignals(false); erasePreview(); - buttonOk()->setEnabled(false); buttonApply()->setEnabled(false); - myComputeButton->setEnabled(true); +} + +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::ConstructorsClicked(int constructorId) +{ + if (myCurrConstrId == constructorId) + return; + + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + + switch (constructorId) { + case 0: + mySimpleGrp->show(); + myFastGrp->hide(); + break; + case 1: + mySimpleGrp->hide(); + myFastGrp->show(); + break; + } + + myCurrConstrId = constructorId; + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + qApp->processEvents(); + updateGeometry(); + resize(minimumSizeHint()); + + processPreview(); + //updateButtonState(); + activateSelection(); + SelectionIntoArgument(); } //================================================================================= @@ -223,7 +357,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() QString anErrMsg(""); if (!findSelfIntersections(hasSelfInte, anErrMsg)) { - myTextView->setText(anErrMsg); + getTextView()->setText(anErrMsg); return; } @@ -243,12 +377,12 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() aMsg += anErrMsg; } - myTextView->setText(aMsg); + getTextView()->setText(aMsg); // Pairs QStringList anInteList; QString anInteStr (""); - int nbPairs = myInters->length()/2; + int nbPairs = getInters()->length()/2; for (int i = 1; i <= nbPairs; i++) { anInteStr = "Intersection # "; @@ -256,8 +390,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() anInteList.append(anInteStr); } - myInteList->addItems(anInteList); - myComputeButton->setEnabled(false); + getInteList()->addItems(anInteList); + getComputeButton()->setEnabled(false); } //================================================================================= @@ -291,7 +425,23 @@ void MeasureGUI_CheckSelfIntersectionsDlg::DeactivateActiveDialog() //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection() { - globalSelection(GEOM_ALLSHAPES); + switch (getConstructorId()) { + case 0: + globalSelection(GEOM_ALLSHAPES); + break; + case 1: + TColStd_MapOfInteger aTypes; + aTypes.Add(GEOM_COMPOUND ); + aTypes.Add(GEOM_SOLID ); + aTypes.Add(GEOM_SHELL); + aTypes.Add(GEOM_FACE); + globalSelection(aTypes); + + std::list needTypes; + needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); + localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + break; + } } //================================================================================= @@ -313,7 +463,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply() if ( !onAccept() ) return false; + clear(); initName(); + + ConstructorsClicked(getConstructorId()); + return true; } @@ -341,7 +495,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation //================================================================================= bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) { - return !myObj->_is_nil(); + return !getObj().isNull(); } //================================================================================= @@ -350,37 +504,51 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument() { - myEditObjName->setFocus(); + getEditObjName()->setFocus(); SelectionIntoArgument(); } +//================================================================================= +// function : OnGaps() +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::OnGaps(bool checked) +{ + clear(); + myTolerance->setEnabled(checked); +} //================================================================================= // function : SelectionIntoArgument // purpose : //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument() { + QList typesLst; + + if ( getConstructorId() == 0 ) { + typesLst << TopAbs_COMPOUND + << TopAbs_COMPSOLID + << TopAbs_SOLID + << TopAbs_SHELL + << TopAbs_FACE + << TopAbs_WIRE + << TopAbs_EDGE + << TopAbs_VERTEX + << TopAbs_SHAPE; + } else { + typesLst << TopAbs_FACE + << TopAbs_SHELL + << TopAbs_SOLID + << TopAbs_COMPOUND; + } + // Clear the dialog. clear(); - myObj = GEOM::GEOM_Object::_nil(); - - LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); - SALOME_ListIO aSelList; - aSelMgr->selectedObjects(aSelList); - - GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil(); - if (aSelList.Extent() > 0) { - aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() ); - } - - if (aSelectedObject->_is_nil()) { - myEditObjName->setText(""); - return; - } + GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst ); - myObj = aSelectedObject; - myEditObjName->setText(GEOMBase::GetName(myObj)); + (getConstructorId() == 0 ? myObj1 :myObj2) = aSelectedObject; + getEditObjName()->setText(getObj() ? GEOMBase::GetName(getObj().get()) : ""); } //================================================================================= @@ -400,7 +568,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::enterEvent(QEvent *) bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections (bool &HasSelfInte, QString &theErrMsg) { - if (myObj->_is_nil()) { + if (getObj()->_is_nil()) { return false; } @@ -413,10 +581,14 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections SUIT_OverrideCursor wc; try { - HasSelfInte = !anOper->CheckSelfIntersections(myObj, aLevel, myInters); - nbPairs = myInters->length()/2; + if ( getConstructorId() == 0 ) { + HasSelfInte = !anOper->CheckSelfIntersections(myObj1.get(), aLevel, myInters1); + } else { + HasSelfInte = !anOper->CheckSelfIntersectionsFast(myObj2.get(), getDeflection(), getTolerance(), myInters2); + } + nbPairs = getInters()->length()/2; - if (nbPairs*2 != myInters->length()) { + if (nbPairs*2 != getInters()->length()) { isOK = false; } } @@ -426,7 +598,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections } if (!anOper->IsDone()) { - if (myInters->length() == 0) { + if (getInters()->length() == 0) { theErrMsg = tr(anOper->GetErrorCode()); isOK = false; } else { @@ -447,24 +619,24 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged() { erasePreview(); - myShapeList->clear(); + getShapeList()->clear(); TopoDS_Shape aSelShape; - if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) { TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aSelShape, anIndices); - int nbSelected = myInteList->selectedItems().size(); + int nbSelected = getInteList()->selectedItems().size(); - for (int i = 0; i < myInteList->count(); i++) { - if ( myInteList->item(i)->isSelected() ) { + for (int i = 0; i < getInteList()->count(); i++) { + if ( getInteList()->item(i)->isSelected() ) { if ( nbSelected > 1 ) - myShapeList->addItem(QString("--- #%1 ---").arg(i+1)); + getShapeList()->addItem(QString("--- #%1 ---").arg(i+1)); for (int j = 0; j < 2; j++) { - TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]); + TopoDS_Shape aSubShape = anIndices.FindKey(getInters()[i*2+j]); QString aType = GEOMBase::GetShapeTypeString(aSubShape); - myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j])); - myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]); + getShapeList()->addItem(QString("%1_%2").arg(aType).arg(getInters()[i*2+j])); + getShapeList()->item(getShapeList()->count()-1)->setData(Qt::UserRole, getInters()[i*2+j]); } } } @@ -480,7 +652,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() erasePreview(); // Selected IDs - QList selected = myShapeList->selectedItems(); + QList selected = getShapeList()->selectedItems(); QList aIds; foreach(QListWidgetItem* item, selected) { int idx = item->data(Qt::UserRole).toInt(); @@ -492,7 +664,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() TopoDS_Shape aSelShape; TopoDS_Shape aSubShape; TopTools_IndexedMapOfShape anIndices; - if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) { TopExp::MapShapes(aSelShape, anIndices); getDisplayer()->SetColor(Quantity_NOC_RED); getDisplayer()->SetWidth(3); @@ -500,11 +672,11 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() foreach(int idx, aIds) { aSubShape = anIndices.FindKey(idx); try { - SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; - if (aPrs) displayPreview(aPrs, true); + SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; + if (aPrs) displayPreview(aPrs, true); } catch (const SALOME::SALOME_Exception& e) { - SalomeApp_Tools::QtCatchCorbaException(e); + SalomeApp_Tools::QtCatchCorbaException(e); } } } @@ -526,15 +698,15 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) TColStd_IndexedMapOfInteger aMapIndex; QList pairs; - int nbSelected = myInteList->selectedItems().size(); + int nbSelected = getInteList()->selectedItems().size(); // Collect the map of indices - for (int i = 0; i < myInteList->count(); i++) { - if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) { - aMapIndex.Add(myInters[i*2]); - aMapIndex.Add(myInters[i*2 + 1]); - pairs << myInters[i*2]; - pairs << myInters[i*2 + 1]; + for (int i = 0; i < getInteList()->count(); i++) { + if ( nbSelected < 1 || getInteList()->item(i)->isSelected() ) { + aMapIndex.Add(getInters()[i*2]); + aMapIndex.Add(getInters()[i*2 + 1]); + pairs << getInters()[i*2]; + pairs << getInters()[i*2 + 1]; } } @@ -547,7 +719,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) for (int i = 1; i <= aMapIndex.Extent(); i++) anArray[i-1] = aMapIndex.FindKey(i); - GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray); + GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(getObj().get(), anArray); // Make compounds for (int i = 0; i < pairs.count()/2; i++) { @@ -562,6 +734,27 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) return true; } +//================================================================================= +// function : getDeflection +// purpose : +//================================================================================= +float MeasureGUI_CheckSelfIntersectionsDlg::getDeflection() +{ + return (float)myDeflection->value(); +} + +//================================================================================= +// function : getTolerance +// purpose : +//================================================================================= +double MeasureGUI_CheckSelfIntersectionsDlg::getTolerance() +{ + double aVal = myTolerance->value(); + if (!myDetGaps->isChecked() || aVal < 0.0) + return 0.0; + return aVal; +} + //================================================================ // Function : getFather // Purpose : Get father object for object to be added in study @@ -570,5 +763,54 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather (GEOM::GEOM_Object_ptr) { - return myObj; + return getObj().get(); +} + +//================================================================================= +// function : getSourceObjects +// purpose : virtual method to get source objects +//================================================================================= +QList MeasureGUI_CheckSelfIntersectionsDlg::getSourceObjects() +{ + QList res; + res << getObj(); + return res; +} + +//================================================================================= +// GETTERS +//================================================================================= +QTextBrowser* MeasureGUI_CheckSelfIntersectionsDlg::getTextView() +{ + return ( getConstructorId() == 0 ? myTextView1 : myTextView2 ); +} + +QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getInteList() +{ + return ( getConstructorId() == 0 ? myInteList1 : myInteList2 ); +} + +QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getShapeList() +{ + return ( getConstructorId() == 0 ? myShapeList1 : myShapeList2 ); +} + +QPushButton* MeasureGUI_CheckSelfIntersectionsDlg::getComputeButton() +{ + return ( getConstructorId() == 0 ? myComputeButton1 : myComputeButton2 ); +} + +QLineEdit* MeasureGUI_CheckSelfIntersectionsDlg::getEditObjName() +{ + return ( getConstructorId() == 0 ? myEditObjName1 : myEditObjName2 ); +} + +GEOM::GeomObjPtr MeasureGUI_CheckSelfIntersectionsDlg::getObj() +{ + return ( getConstructorId() == 0 ? myObj1 : myObj2 ); +} + +GEOM::ListOfLong_var MeasureGUI_CheckSelfIntersectionsDlg::getInters() +{ + return ( getConstructorId() == 0 ? myInters1 : myInters2 ); } diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h index f05dd8109..ac0f2d935 100644 --- a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h @@ -54,6 +54,7 @@ protected: virtual bool execute(ObjectList &); virtual bool extractPrefix() const; virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr); + virtual QList getSourceObjects(); private slots: @@ -67,6 +68,9 @@ private slots: void DeactivateActiveDialog(); void SelectionIntoArgument(); void SetEditCurrentArgument(); + void ConstructorsClicked (int); + void OnGaps(bool); + private: @@ -76,18 +80,46 @@ private: bool findSelfIntersections (bool &HasSelfInte, QString &theErrMsg); + float getDeflection(); + double getTolerance(); + +// Getters + QTextBrowser* getTextView(); + QListWidget* getInteList(); + QListWidget* getShapeList(); + QPushButton* getComputeButton(); + QLineEdit* getEditObjName(); + GEOM::GeomObjPtr getObj(); + GEOM::ListOfLong_var getInters(); -private: - QTextBrowser *myTextView; - QPushButton *mySelButton; - QLineEdit *myEditObjName; +private: + int myCurrConstrId; + // simple + QPushButton *myComputeButton1; + QGroupBox *mySimpleGrp; + QTextBrowser *myTextView1; + QPushButton *mySelButton1; + QLineEdit *myEditObjName1; QComboBox *myLevelBox; - QPushButton *myComputeButton; - QListWidget *myInteList; - QListWidget *myShapeList; - GEOM::GEOM_Object_var myObj; - GEOM::ListOfLong_var myInters; + QListWidget *myInteList1; + QListWidget *myShapeList1; + GEOM::GeomObjPtr myObj1; + GEOM::ListOfLong_var myInters1; + // fast + QPushButton *myComputeButton2; + QGroupBox *myFastGrp; + QTextBrowser *myTextView2; + QPushButton *mySelButton2; + QLineEdit *myEditObjName2; + QCheckBox *myDetGaps; + SalomeApp_DoubleSpinBox *myTolerance; + SalomeApp_DoubleSpinBox *myDeflection; + QListWidget *myInteList2; + QListWidget *myShapeList2; + GEOM::GeomObjPtr myObj2; + GEOM::ListOfLong_var myInters2; + GEOM::GEOM_IShapesOperations_var myShapesOper; }; #endif // MEASUREGUI_CHECKSELFINTERDLG_H