From 9eecc554ac038d95cd71d497b91084e3ee18ac35 Mon Sep 17 00:00:00 2001 From: akl Date: Tue, 28 Apr 2015 12:21:22 +0400 Subject: [PATCH] 22762 (part 2): add second 'Detect Self-Intersections Fast' tab in the 'Check Self-Intersections' dialog box. --- doc/salome/examples/CMakeLists.txt | 1 + .../examples/check_self_intersections_fast.py | 15 + doc/salome/gui/GEOM/images/measures11.png | Bin 33219 -> 950456 bytes doc/salome/gui/GEOM/images/measures13.png | Bin 0 -> 891574 bytes .../GEOM/input/check_self_intersections.doc | 37 +- .../tui_check_self_intersections_fast.doc | 6 + .../gui/GEOM/input/tui_measurement_tools.doc | 1 + .../gui/GEOM/input/tui_test_measures.doc | 3 + idl/GEOM_Gen.idl | 15 + src/GEOMGUI/GEOM_msg_en.ts | 10 +- src/GEOMGUI/GEOM_msg_fr.ts | 10 +- src/GEOMGUI/GEOM_msg_ja.ts | 10 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 55 ++ src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 5 + src/GEOM_I/GEOM_IMeasureOperations_i.cc | 43 ++ src/GEOM_I/GEOM_IMeasureOperations_i.hh | 5 + src/GEOM_SWIG/GEOM_TestMeasures.py | 9 +- src/GEOM_SWIG/geomBuilder.py | 31 ++ .../MeasureGUI_CheckSelfIntersectionsDlg.cxx | 482 +++++++++++++----- .../MeasureGUI_CheckSelfIntersectionsDlg.h | 50 +- 20 files changed, 648 insertions(+), 140 deletions(-) create mode 100644 doc/salome/examples/check_self_intersections_fast.py create mode 100644 doc/salome/gui/GEOM/images/measures13.png create mode 100644 doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc 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_fast.py b/doc/salome/examples/check_self_intersections_fast.py new file mode 100644 index 000000000..fae1c278f --- /dev/null +++ b/doc/salome/examples/check_self_intersections_fast.py @@ -0,0 +1,15 @@ +# 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,30,100) +IsValid = geompy.CheckSelfIntersectionsFast(box, 0.002, 0) +if IsValid == 0: + raise RuntimeError, "Box with self-intersections created" +else: + print "\nBox is valid" diff --git a/doc/salome/gui/GEOM/images/measures11.png b/doc/salome/gui/GEOM/images/measures11.png index 6ee44987416555bf22ca65b9ea84c5a5835cb1b6..6240af4f0e642e1573deba6620d159f9a58438e6 100644 GIT binary patch literal 950456 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 K0<^<(Q; zXD$<0;u2}@q61sDWEI*F+*=fRlqnLQ-H$hmN-P$MBJ%p@_F{kFBi$sBXD; z+uHhq4iy}Eu#vceNvvH`LYIdZc9l~%!H^;VOM#BYM0t!y3K<}oNP6(-5jl}wB@v!# zO-)J>w7zn=Z5pd0{W(n~qhe&E2(IjrxiCOuT>7WVN(E;N3ERl?F8!4blI+VE>O(fa zY0ig9KL+KocpJeS!ZnU428n@{l?u_C#dQ==TZZCv^w-u=clpA3RMOJIf>q{5ByJYb z$G9B0KaHR#EIU|`nwglHNla5y*8^W3^(+SEO7xB*EMdYTFM;P0_|Iw`9z#b9_o=+R zJUpysn;Z8}1V_-#cKi9zBfHmIYC+x*X-hG&3Xj2s&zZOisq%pKlmk7zg+WJDV~VGG z3)xwl=r|8Okhog)bIEsP3xOnhO01}Uu?Dsz>r!8OL6g2~JAU#GtSWeCJ$a^iX=**+ zcAOHbr$uLus$od2AMA1nR*H8OCGm(X7lSpTpd- ze*56cJ7IVJApEzJYg6+H=a$jbzG7H1;rSjV`AA_#DBPuR==6_}ZQRJp&2CHwxHhIrg`8;agGPP`LzDKJ?^O;tNDF+%EMxTgunm8UOV-Ymg@TP33gRyY z%Icf#3$SPOmD9_~5B|P@)-{A`kIqoZbN2hYUq3#_A=Q(4MrB-q;MI&jt;7@{>eVwa zf>Q>(sX(IM2c4qil{E_VCq*Bcw{T}d0nz)wo_3&B_S;su>)B1t(VO{L{+e`_ak~Pe zjL5+Yv2hGW?vYdKr?bnld$#*={`Nh8JNGkdwYz1VZV66ZOlsAdLk6E$f`^gXk@dkV z2dgdz$u-TBy6qXsI!56)l5K08zt1#{rTA(D`s4iXoeS*{%5K~*e%#Jk0=-Xy=dT#X z&oPJC;aL;dcgggfW|;?=%z6)64qna9kS$$n%Nx0<)=_-v3-dulcuB|B*H#mBUH)_) z{$@%K^;Jhl2g&OT3#V8mQ`G4CE%lhvEV~+(-G!o&sa1m{}Qh} zZP9i~)l^H_yU|QaH{{@{kn9TCZ*Qpv7f2-1pEL5u)z$HRFRjnU-`rU-r$rf{x$XI3 zBOVkMFJShytj)WoyOoT3lHya|u9n?o)EpsV21Y0`wrjIDP$kG3h?uiw368w5JyUyN zkoE;Cp7iG5lxIXVIZ!zX{F{jSSMl@j6%g?%vg$&DpzamjE0=8K<<;d}6#{lK**c){ z=>J-5{i{y<+djm$?dG$l{o;nc42-I)2U&}L)U&-CEH&w{XD>nIl?vb-= ZT>HvOx3_pmrr^p+XB5uMC!a8I`wyB{j7tCj diff --git a/doc/salome/gui/GEOM/images/measures13.png b/doc/salome/gui/GEOM/images/measures13.png new file mode 100644 index 0000000000000000000000000000000000000000..fe2550621ea2dd9ce8a33cf9a4536332f1aacc8f GIT binary patch literal 891574 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%0D(*iAi-pc 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 Self-intersections in the Main Menu select +Inspection - > Detect Self-intersections. + +

    +
  1. This operation checks the topology of the selected shape to detect self-intersections. \image html measures11.png In this dialog: - \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser. -- Level of check - The combo box that allows to set the level of checking shape on self-interference. - It defines which interferferences will be checked. Default value is "All interferences". +- Level of check - The combo box that allows to set the level of checking shape on self-interference. It defines which interferferences will be checked. Default value is "All interferences". - Compute self-intersections button computes self-interferences. - \b Summary section contains the general report if the object has self-intersections and/or if errors are occured during computation. - \b Self-intersections list contains the list of self-intersections detected. Select the intersection(s) to show Sub-shapes in the field to the right. - \b Apply and Apply and Close buttons are used to store interferences selected in the "Self-intersections" list box in the study for further analysis. -If no any interference is selected, all interferences are published in the study. Each interference is published as a child -compound of the source shape and contains a couple of intersecting sub-shapes. +If no any interference is selected, all interferences are published in the study. Each interference is published as a child compound of the source shape and contains a couple of intersecting sub-shapes. -\note This tool is useful for detection of shapes, not suitable for +\note This tool is useful for detection of shapes that can not be used as arguments of Boolean operations and Partition algorithm. For more information about Partition and Boolean Operations Algorithms and their limitations refer to this document. @@ -32,5 +34,28 @@ where: \n See also a \ref tui_check_self_intersections_page "TUI example". +
  2. +
  3. Detect self-intersections of the given shape with 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". + +
  4. +
*/ \ 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..68a2b7f61 100644 --- a/doc/salome/gui/GEOM/input/tui_test_measures.doc +++ b/doc/salome/gui/GEOM/input/tui_test_measures.doc @@ -17,6 +17,9 @@ \until Detect Self-intersections \anchor swig_CheckSelfIntersections +\until Detect Self-intersections fast + +\anchor swig_CheckSelfIntersectionsFast \until Detect Fast intersection \anchor swig_FastIntersection diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index f63819e97..d0f68384f 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4447,6 +4447,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 c67b290fe..a76f0b36c 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -425,7 +425,7 @@ Please, select face, shell or solid and try again GEOM_CHECK_SELF_INTERSECTIONS - Detect Self-intersections + Self-intersection Detection Type GEOM_FAST_CHECK_INTERSECTIONS @@ -7323,6 +7323,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 0ab7e34fc..6dabe3523 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -425,7 +425,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_CHECK_SELF_INTERSECTIONS - Détecter les auto-intersections + Self-intersection Detection Type GEOM_FAST_CHECK_INTERSECTIONS @@ -7256,6 +7256,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 75807fcc7..0b8485afb 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -409,7 +409,7 @@ GEOM_CHECK_SELF_INTERSECTIONS - 自己交差の検出 + Self-intersection Detection Type GEOM_FAST_CHECK_INTERSECTIONS @@ -7141,6 +7141,14 @@ 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/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index d1d23d51c..e91cd66c7 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -1580,6 +1580,61 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections return isGood; } +//============================================================================= +/*! + * CheckSelfIntersectionsFast + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast + (Handle(GEOM_Object) theShape, + float theDeflection, double theTolerance, + Handle(TColStd_HSequenceOfInteger)& theIntersections) +{ + SetErrorCode(KO); + bool isGood = false; + + if (theIntersections.IsNull()) + theIntersections = new TColStd_HSequenceOfInteger; + else + theIntersections->Clear(); + + if (theShape.IsNull()) + return isGood; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return isGood; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return isGood; + + // 0. 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); + // + BRepExtrema_ShapeProximity aBSP; // checker of fast interferences + aBSP.LoadShape1(aScopy); + aBSP.SetTolerance((theTolerance <= 0.) ? 0.0 : theTolerance); + + // 1. Launch the checker + aBSP.Perform(); + + // TODO theIntersections filling + //theIntersections = aBSP.Interferences(); // to be corrected!!! + + isGood = theIntersections->IsEmpty(); + + if (aBSP.IsDone()) + SetErrorCode(OK); + + return isGood; +} + //============================================================================= /*! * FastIntersect 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..99d67cb38 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -58,10 +58,17 @@ def TestMeasureOperations (geompy, math): if geompy.CheckSelfIntersections(Compound_1) == True: raise RuntimeError, "Existing self-intersection is not detected" + ####### Detect Self-intersections fast ####### + + if salome_version.getXVersion() > "0x70700": + cylinder = geompy.MakeCylinderRH(100, 300) + Compound_2 = geompy.MakeCompound([box, cylinder]) + if geompy.CheckSelfIntersectionsFast(Compound_2) == True: + raise RuntimeError, "Existing self-intersection is not detected" + ####### Detect 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" diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index e2bf0b10b..d35e24c2b 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -11250,6 +11250,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..4855db287 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,82 +59,142 @@ //================================================================================= 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()->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_INT_OBJ"), 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); + /***************************************************************/ - myHelpFileName = "check_self_intersections_page.html"; + QVBoxLayout* layout2 = new QVBoxLayout (centralWidget()); + layout2->setMargin(0); layout2->setSpacing(6); + layout2->addWidget(mySimpleGrp); + layout2->addWidget(myFastGrp); /* Initialisation */ Init(); @@ -161,32 +222,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 +291,58 @@ 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: + myHelpFileName = "check_self_intersections_page.html"; + mySimpleGrp->show(); + myFastGrp->hide(); + break; + case 1: + myHelpFileName = "check_self_intersections_fast_page.html"; + 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 +355,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() QString anErrMsg(""); if (!findSelfIntersections(hasSelfInte, anErrMsg)) { - myTextView->setText(anErrMsg); + getTextView()->setText(anErrMsg); return; } @@ -243,12 +375,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 +388,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() anInteList.append(anInteStr); } - myInteList->addItems(anInteList); - myComputeButton->setEnabled(false); + getInteList()->addItems(anInteList); + getComputeButton()->setEnabled(false); } //================================================================================= @@ -291,7 +423,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 +461,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply() if ( !onAccept() ) return false; + clear(); initName(); + + ConstructorsClicked(getConstructorId()); + return true; } @@ -341,7 +493,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation //================================================================================= bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) { - return !myObj->_is_nil(); + return getObj().isNull(); } //================================================================================= @@ -350,37 +502,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() ); - } + GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst ); - if (aSelectedObject->_is_nil()) { - myEditObjName->setText(""); - return; - } - - myObj = aSelectedObject; - myEditObjName->setText(GEOMBase::GetName(myObj)); + (getConstructorId() == 0 ? myObj1 :myObj2) = aSelectedObject; + getEditObjName()->setText(getObj() ? GEOMBase::GetName(getObj().get()) : ""); } //================================================================================= @@ -400,7 +566,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 +579,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(), getTolerance(), getDeflection(), myInters2); + } + nbPairs = getInters()->length()/2; - if (nbPairs*2 != myInters->length()) { + if (nbPairs*2 != getInters()->length()) { isOK = false; } } @@ -426,7 +596,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 +617,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 +650,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 +662,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 +670,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 +696,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 +717,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 +732,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 +761,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 : myShapeList1 ); +} + +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 -- 2.39.2