From: ana Date: Tue, 16 Dec 2014 16:27:28 +0000 (+0300) Subject: 0022762: [EDF] Fast detection of face/face face/solid solid/solid interference X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d81fa3fcfb4940f92882677ce238bb3960959e7e;p=modules%2Fgeom.git 0022762: [EDF] Fast detection of face/face face/solid solid/solid interference --- diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 76c3883e1..0817e5fb4 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -65,7 +65,8 @@ SET(GOOD_TESTS complex_objs_ex07.py complex_objs_ex08.py complex_objs_ex09.py - complex_objs_ex10.py + complex_objs_ex10.py + fast_intersection.py free_boundaries.py free_faces.py GEOM_box.py diff --git a/doc/salome/examples/fast_intersection.py b/doc/salome/examples/fast_intersection.py new file mode 100644 index 000000000..4854a579f --- /dev/null +++ b/doc/salome/examples/fast_intersection.py @@ -0,0 +1,34 @@ +# Fast intersection + +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) + +isOk, res1, res2 = geompy.FastIntersect(box, cylinder) +if isOk == 0: + raise RuntimeError, "No intersection!" +else: + print "\nTwo lists of indexes of sub-shapes localize the intersection:" + print res1, res2 + +# create two boxes with gap +Ver1 = geompy.MakeVertex(0, 0, 0) +Ver2 = geompy.MakeVertex(100, 100, 100) +Ver3 = geompy.MakeVertex(100.1, 0, 0) +Ver4 = geompy.MakeVertex(200, 200, 200) +box1 = geompy.MakeBoxTwoPnt(Ver1, Ver2) +box2 = geompy.MakeBoxTwoPnt(Ver3, Ver4) + +isOk1, aRes1, aRes2 = geompy.FastIntersect(box1, box2, 1.) +if isOk1 == 0: + raise RuntimeError, "No gaps!" +else: + print "\nTwo lists of indexes of sub-shapes localize the gap:" + print aRes1, aRes2 diff --git a/doc/salome/gui/GEOM/images/measures12.png b/doc/salome/gui/GEOM/images/measures12.png new file mode 100644 index 000000000..0dba5423c Binary files /dev/null and b/doc/salome/gui/GEOM/images/measures12.png differ diff --git a/doc/salome/gui/GEOM/input/fast_intersection.doc b/doc/salome/gui/GEOM/input/fast_intersection.doc new file mode 100644 index 000000000..10e4d6c70 --- /dev/null +++ b/doc/salome/gui/GEOM/input/fast_intersection.doc @@ -0,0 +1,59 @@ +/*! +\page fast_intersection_page Fast intersection + +This operation checks whether or not two selected shape are overlapped. + +\n This tool is useful for fast detection of intersections and gaps. +In contrast to Boolean Operations, Partition and Detect Self-intersection +algorithms that compute topological intersections, this algoritm computes +intersections by generating tessellation (triangulation) of the source +shapes and detecting overlapping of resulting meshes. High performance is +achieved through the use of existing triangulation of faces. + +\note For more information about Partition and Boolean Operations Algorithms +and their limitations refer to this document. + +\image html measures12.png + +In this dialog: + +- \b Object 1 - the checked object. \b Selection button allows picking it in the viewer or in the object browser. +- \b Object 2 - the checked object. \b Selection button allows picking it in the viewer or in the object browser. + +\note This dialog supports navigation through the selectable objects (in OCC 3D viewer only): +- Scroll mouse wheel with pressed \em Ctrl key or press \em "S", \em "P" keys when input focus is +in the viewer to navigate between selectable objects. +- Press left mouse button to select an appropriate object to the dialog box. +. +For more details, please refer to the \em "Functionality common for OCC and VTK viewers" chapter +of the GUI module's documentation. + +- Deflection coefficient desires the quality of tessellation. +\note Quality of the result depends on the quality of triangulation. +In some cases changing this coefficient can strongly affect the result. +- Detect gaps - the check box that allows detecting small gaps with between shapes. +- Tolerance distance between shapes used for detecting gaps. +- Compute intersections button computes interferences. +- Sub-shapes of Object 1 - list of sub-shapes from first shape being checked that localize the intersection. +- Sub-shapes of Object 2 - list of sub-shapes from second shape being checked that localize the intersection. +- \b Apply and Apply and Close buttons are used to store selected intersected shapes in the study for further analysis. + +\note Result of this operation cannot be represented as a topological shape. Tool returns as +the result a list of sub-shapes from each shape being checked that localize the intersection. +The intersection will be published as a compound containing intersected sub-shapes from both source objects. +This result might be helpful to the user for further analysis of the initial shapes. + +\n Result: Boolean, two lists of IDs of sub-shapes from shapes being checked that localize the intersection. +\n TUI Command: geompy.FastIntersect(theShape1, theShape1, theTolerance = 0.0, theDeflection = 0.001), \n +where: \n +\em theShape1 First shape. \n +\em theShape2 Second shape. \n +\em theTolerance If negative or zero value, it will be possible to detect intersections + If non-zero positive value, it will be possible to detect gaps. \n +\em theDeflection Linear deflection for shapes. + If deflection <= 0, than use default deflection 0.001 \n + +See also a \ref tui_fast_intersection_page "TUI example". + + +*/ \ No newline at end of file diff --git a/doc/salome/gui/GEOM/input/tui_fast_intersection.doc b/doc/salome/gui/GEOM/input/tui_fast_intersection.doc new file mode 100644 index 000000000..05708da41 --- /dev/null +++ b/doc/salome/gui/GEOM/input/tui_fast_intersection.doc @@ -0,0 +1,6 @@ +/*! + +\page tui_fast_intersection_page Fast intersection +\tui_script{fast_intersection.py} + +*/ diff --git a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc index 583f3de0f..6e83325c3 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_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 90dafb538..2220f9a3a 100644 --- a/doc/salome/gui/GEOM/input/tui_test_measures.doc +++ b/doc/salome/gui/GEOM/input/tui_test_measures.doc @@ -16,6 +16,9 @@ \anchor swig_CheckShape \until MakeCompound +\anchor swig_FastIntersection +\until swig_CheckSelfIntersections + \anchor swig_CheckSelfIntersections \until WhatIs diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc index 40e38c664..2672156cd 100644 --- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc @@ -29,6 +29,7 @@
  • \subpage check_compound_of_blocks_page "Check compound of blocks"
  • \subpage get_non_blocks_page "Get non blocks"
  • \subpage check_self_intersections_page "Detect Self-intersections"
  • +
  • \subpage fast_intersection_page "Fast intersection"
  • \n Our TUI Scripts show how to use diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 83faa46bb..319c49cd7 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4251,6 +4251,23 @@ module GEOM in long theCheckLevel, out ListOfLong theIntersections); + /*! + * \brief Check intersections of the given shapes by algorithm based on mesh intersections. + * \param theShape1,theShape2 Shapes to find angle between. + * \param theTolerance If negative value, it will be possible to detect intersections + * If non-zero positive value, it will be possible to detect gaps. + * \param theDeflection Linear deflection for shapes. + * If deflection <= 0, than use default deflection 0.001 + * \param theIntersections1 Output. List of overlapped sub-shapes IDs of 1st shape. + * \param theIntersections2 Output. List of overlapped sub-shapes IDs of 2nd shape. + * \return TRUE, if the are some intersections. + */ + boolean FastIntersect (in GEOM_Object theShape1, in GEOM_Object theShape2, + in double theTolerance, + in float theDeflection, + out ListOfLong theIntersections1, + out ListOfLong theIntersections2); + /*! * \brief Check if the given shape can be an argument for MakeSolid operation * \param theShape Shape to be described. diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 49a7e5362..cb7e9af4c 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -257,6 +257,7 @@ SET( _res_files check_blocks_compound.png get_non_blocks.png check_self_intersections.png + fast_intersect.png free_faces.png propagate.png redo.png diff --git a/resources/fast_intersect.png b/resources/fast_intersect.png new file mode 100644 index 000000000..736adde33 Binary files /dev/null and b/resources/fast_intersect.png differ diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 14cf841bc..11f7300b1 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -251,6 +251,10 @@ ICON_DLG_CHECK_SELF_INTERSECTIONS check_self_intersections.png + + ICON_DLG_FAST_CHECK_INTERSECTIONS + fast_intersect.png + ICON_DLG_CIRCLE_PNTS circle3points.png @@ -879,6 +883,10 @@ ICO_CHECK_SELF_INTERSECTIONS check_self_intersections.png + + ICO_FAST_CHECK_INTERSECTIONS + fast_intersect.png + ICO_CHECK_FREE_BNDS free_bound.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 1630caf5a..54e765c67 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -423,6 +423,10 @@ Please, select face, shell or solid and try again GEOM_CHECK_SELF_INTERSECTIONS Detect Self-intersections + + GEOM_FAST_CHECK_INTERSECTIONS + Fast intersection + GEOM_CIRCLE Circle @@ -2488,6 +2492,10 @@ Please, select face, shell or solid and try again MEN_CHECK_SELF_INTERSECTIONS Detect Self-intersections + + MEN_FAST_CHECK_INTERSECTIONS + Fast intersection + MEN_CHECK_FREE_BNDS Check Free Boundaries @@ -3493,6 +3501,10 @@ Please, select face, shell or solid and try again Detect Self-intersections + STB_FAST_CHECK_INTERSECTIONS + Fast intersection + + STB_CHECK_FREE_BNDS Check free boundaries @@ -4104,6 +4116,10 @@ Please, select face, shell or solid and try again TOP_CHECK_SELF_INTERSECTIONS Detect Self-intersections + + TOP_FAST_CHECK_INTERSECTIONS + Fast intersection + TOP_CHECK_FREE_BNDS Check free boundaries @@ -7090,6 +7106,37 @@ Do you want to create new material? All interferences + + MeasureGUI_FastCheckIntersectionsDlg + + GEOM_FAST_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_FAST_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + + + GEOM_FAST_CHECK_INT_SUBSHAPES + Sub-shapes of Object %1: + + + GEOM_FAST_CHECK_INT_COMPUTE + Compute intersections + + + GEOM_FAST_INTERSECTION_NAME + Fast_intersection + + + GEOM_FAST_INTERSECTION_FAILS + No intersections + + + GEOM_FAST_CHECK_OBJ + Objects And Results + + TransformationGUI_ExtensionDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index be77999a9..977d84cc3 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -637,6 +637,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpGetNonBlocks: // MENU MEASURE - Get NON BLOCKS case GEOMOp::OpPointCoordinates: // MENU MEASURE - POINT COORDINATES case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS + case GEOMOp::OpFastCheckInters: // MENU MEASURE - FAST CHECK INTERSECTIONS case GEOMOp::OpManageDimensions: // MENU MEASURE - MANAGE DIMENSIONS case GEOMOp::OpShowAllDimensions: // POPUP MENU - SHOW ALL DIMENSIONS case GEOMOp::OpHideAllDimensions: // POPUP MENU - HIDE ALL DIMENSIONS @@ -1014,6 +1015,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpCheckCompound, "CHECK_COMPOUND" ); createGeomAction( GEOMOp::OpGetNonBlocks, "GET_NON_BLOCKS" ); createGeomAction( GEOMOp::OpCheckSelfInters, "CHECK_SELF_INTERSECTIONS" ); + createGeomAction( GEOMOp::OpFastCheckInters, "FAST_CHECK_INTERSECTIONS" ); #ifdef _DEBUG_ // PAL16821 createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" ); @@ -1270,6 +1272,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpCheckCompound, measurId, -1 ); createMenu( GEOMOp::OpGetNonBlocks, measurId, -1 ); createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 ); + createMenu( GEOMOp::OpFastCheckInters, measurId, -1 ); int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 ); #if defined(_DEBUG_) || defined(_DEBUG) // PAL16821 @@ -1416,6 +1419,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createTool( GEOMOp::OpCheckCompound, measureTbId ); createTool( GEOMOp::OpGetNonBlocks, measureTbId ); createTool( GEOMOp::OpCheckSelfInters, measureTbId ); + createTool( GEOMOp::OpFastCheckInters, measureTbId ); int picturesTbId = createTool( tr( "TOOL_PICTURES" ), QString( "GEOMPictures" ) ); createTool( GEOMOp::OpPictureImport, picturesTbId ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 9a1e4fd40..3d473393c 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -193,6 +193,7 @@ namespace GEOMOp { OpManageDimensions = 5014, // MENU MEASURES - MANAGE DIMENSIONS OpShowAllDimensions = 5015, // POPUP MENU - SHOW ALL DIMENSIONS OpHideAllDimensions = 5016, // POPUP MENU - HIDE ALL DIMENSIONS + OpFastCheckInters = 5017, // MENU MEASURES - FAST CHECK INTERSECTIONS // GroupGUI --------------------//-------------------------------- OpGroupCreate = 6000, // MENU GROUP - CREATE OpGroupEdit = 6001, // MENU GROUP - EDIT diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 3822d2912..12fbd66e6 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -30,6 +30,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/BlockFix ${PROJECT_SOURCE_DIR}/src/GEOMAlgo ${PROJECT_SOURCE_DIR}/src/GEOMUtils + ${PROJECT_SOURCE_DIR}/src/OCC2VTK ${PROJECT_SOURCE_DIR}/src/SKETCHER ${PROJECT_SOURCE_DIR}/src/ARCHIMEDE ${PROJECT_SOURCE_DIR}/src/XAO @@ -47,7 +48,7 @@ SET(_link_LIBRARIES ${CAS_TKFeat} ${CAS_TKFillet} ${PYTHON_LIBRARIES} - ShHealOper GEOMbasic BlockFix GEOMAlgo GEOMUtils GEOMSketcher GEOMArchimede XAO + ShHealOper GEOMbasic BlockFix GEOMAlgo GEOMUtils GEOMSketcher GEOMArchimede XAO OCC2VTK ${KERNEL_SALOMELocalTrace} ) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index fb2320ea5..51579f5d2 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1575,6 +1577,89 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections return isGood; } +//============================================================================= +/*! + * FastIntersect + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, + double theTolerance, float theDeflection, + Handle(TColStd_HSequenceOfInteger)& theIntersections1, + Handle(TColStd_HSequenceOfInteger)& theIntersections2) +{ + SetErrorCode(KO); + bool isGood = false; + + if (theIntersections1.IsNull()) + theIntersections1 = new TColStd_HSequenceOfInteger; + else + theIntersections1->Clear(); + + if (theIntersections2.IsNull()) + theIntersections2 = new TColStd_HSequenceOfInteger; + else + theIntersections2->Clear(); + + if (theShape1.IsNull() || theShape2.IsNull()) { + SetErrorCode("Objects have NULL Shape"); + return isGood; + } + + if (theShape1 == theShape2) { + SetErrorCode("Objects are equal"); + return isGood; + } + Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction(); + Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction(); + if (aRefShape1.IsNull() || aRefShape2.IsNull()) return isGood; + + TopoDS_Shape aShape1 = aRefShape1->GetValue(); + TopoDS_Shape aShape2 = aRefShape2->GetValue(); + if (aShape1.IsNull() || aShape2.IsNull()) return isGood; + + // 0. Prepare data + TopoDS_Shape aScopy1, aScopy2; + GEOMAlgo_AlgoTools::CopyShape(aShape1, aScopy1); + GEOMAlgo_AlgoTools::CopyShape(aShape2, aScopy2); + + float aDeflection = (theDeflection <= 0.) ? 0.001 : theDeflection; + GEOM::MeshShape( aScopy1, aDeflection); + GEOM::MeshShape( aScopy2, aDeflection); + // + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices1, anIndices2; + TopExp::MapShapes(aScopy1, anIndices1); + TopExp::MapShapes(aScopy2, anIndices2); + + BOPCol_ListOfShape aLCS1, aLCS2; + aLCS1.Append(aScopy1); aLCS2.Append(aScopy2); + // + BRepExtrema_ShapeProximity aBSP; // checker of fast interferences + aBSP.LoadShape1(aScopy1); aBSP.LoadShape2(aScopy2); + aBSP.SetTolerance((theTolerance <= 0.) ? 0.0 : theTolerance); + + // 1. Launch the checker + aBSP.Perform(); + + isGood = true; + + // 2. Get sets of IDs of overlapped faces + for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { + const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key()); + theIntersections1->Append(anIndices1.FindIndex(aS1)); + } + + for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { + const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key()); + theIntersections2->Append(anIndices2.FindIndex(aS2)); + } + if (theIntersections1->IsEmpty() || theIntersections1->IsEmpty()) + isGood = false; + + if (aBSP.IsDone()) + SetErrorCode(OK); + return isGood; +} //============================================================================= /*! * IsGoodForSolid diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 3b8ae3d42..e73655cbf 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -157,6 +157,11 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_EXPORT bool CheckSelfIntersections (Handle(GEOM_Object) theShape, const SICheckLevel theCheckLevel, Handle(TColStd_HSequenceOfInteger)& theIntersections); + + Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, + double tolerance, float deflection, + Handle(TColStd_HSequenceOfInteger)& theIntersections1, + Handle(TColStd_HSequenceOfInteger)& theIntersections2); Standard_EXPORT TCollection_AsciiString IsGoodForSolid (Handle(GEOM_Object) theShape); diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index 0d4a89eff..f4e2eaea2 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -765,6 +765,59 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Obj return isGood; } +//============================================================================= +/*! + * FastIntersect + */ +//============================================================================= +CORBA::Boolean GEOM_IMeasureOperations_i::FastIntersect (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + CORBA::Double theTolerance, + CORBA::Float theDeflection, + GEOM::ListOfLong_out theIntersections1, + GEOM::ListOfLong_out theIntersections2) +{ + // Set a not done flag + GetOperations()->SetNotDone(); + + bool isGood = false; + + // Allocate the CORBA arrays + GEOM::ListOfLong_var anIntegersArray1 = new GEOM::ListOfLong(); + GEOM::ListOfLong_var anIntegersArray2 = new GEOM::ListOfLong(); + + // Get the reference shape + Handle(GEOM_Object) aShape1 = GetObjectImpl(theShape1); + Handle(GEOM_Object) aShape2 = GetObjectImpl(theShape2); + + if (!aShape1.IsNull() && !aShape2.IsNull()) { + Handle(TColStd_HSequenceOfInteger) anIntegers1 = new TColStd_HSequenceOfInteger; + Handle(TColStd_HSequenceOfInteger) anIntegers2 = new TColStd_HSequenceOfInteger; + + // Detect intersections + isGood = GetOperations()->FastIntersect + (aShape1, aShape2, theTolerance, theDeflection, anIntegers1, anIntegers2); + + int nbInts1 = anIntegers1->Length(); + int nbInts2 = anIntegers2->Length(); + + anIntegersArray1->length(nbInts1); + anIntegersArray2->length(nbInts2); + + for (int ii = 0; ii < nbInts1; ii++) { + anIntegersArray1[ii] = anIntegers1->Value(ii + 1); + } + for (int ii = 0; ii < nbInts2; ii++) { + anIntegersArray2[ii] = anIntegers2->Value(ii + 1); + } + } + + // Initialize out-parameters with local arrays + theIntersections1 = anIntegersArray1._retn(); + theIntersections2 = anIntegersArray2._retn(); + return isGood; +} + //============================================================================= /*! * IsGoodForSolid diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index 391de3f48..27bf86b5f 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -100,6 +100,13 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Long theCheckLevel, GEOM::ListOfLong_out theIntersections); + CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + CORBA::Double theTolerance, + CORBA::Float theDeflection, + GEOM::ListOfLong_out theIntersections1, + GEOM::ListOfLong_out theIntersections2); + char* IsGoodForSolid (GEOM::GEOM_Object_ptr theShape); char* WhatIs (GEOM::GEOM_Object_ptr theShape); diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index 2aed6d6a5..22657306d 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -56,6 +56,12 @@ def TestMeasureOperations (geompy, math): if geompy.CheckSelfIntersections(Compound_1) == True: raise RuntimeError, "Existing self-intersection is not detected" + ####### Detect Fast intersection ####### + + cylinder = geompy.MakeCylinderRH(100, 300) + if geompy.FastIntersect(box, cylinder) == False: + raise RuntimeError, "Existing intersection is not detected" + ####### WhatIs ####### Descr = geompy.WhatIs(box) diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 83c2e34b0..78f715f79 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -10832,6 +10832,41 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("CheckSelfIntersections", self.MeasuOp) return IsValid + ## Check intersections of the given shapes by algorithm based on mesh intersections. + # @param theShape1 First shape. + # @param theShape2 Second shape. + # @param theTolerance If negative or zero value, it will be possible to detect intersections + # If non-zero positive value, it will be possible to detect gaps. + # @param theDeflection Linear deflection for shapes. + # If deflection <= 0, than use default deflection 0.001 + # @return TRUE, if some intersections have been detected. + # @return List of IDs of sub-shapes from first shape being checked that localize the intersection. + # @return List of IDs of sub-shapes from second shape being checked that localize the intersection. + # + # @ref tui_measurement_tools_page "Example" + @ManageTransactions("MeasuOp") + def FastIntersect(self, theShape1, theShape2, theTolerance = 0.0, theDeflection = 0.001): + """ + Check intersections of the given shapes by algorithm based on mesh intersections. + + Parameters: + theShape1 First shape. + theShape2 Second shape. + theTolerance If negative or zero value, it will be possible to detect intersections + If non-zero positive value, it will be possible to detect gaps. + theDeflection Linear deflection for shapes. + If deflection <= 0, than use default deflection 0.001 + + Returns: + TRUE, if some intersections have been detected. + List of IDs of sub-shapes from first shape being checked that localize the intersection. + List of IDs of sub-shapes from second shape being checked that localize the intersection. + """ + # Example: see GEOM_TestMeasures.py + IsOk, Res1, Res2 = self.MeasuOp.FastIntersect(theShape1, theShape2, theTolerance, theDeflection) + RaiseIfFailed("FastIntersect", self.MeasuOp) + return IsOk, Res1, Res2 + ## Get position (LCS) of theShape. # # Origin of the LCS is situated at the shape's center of mass. diff --git a/src/MeasureGUI/CMakeLists.txt b/src/MeasureGUI/CMakeLists.txt index 8f57e40ad..fe15eedc0 100755 --- a/src/MeasureGUI/CMakeLists.txt +++ b/src/MeasureGUI/CMakeLists.txt @@ -97,6 +97,7 @@ SET(MeasureGUI_HEADERS MeasureGUI_CheckCompoundOfBlocksDlg.h MeasureGUI_GetNonBlocksDlg.h MeasureGUI_CheckSelfIntersectionsDlg.h + MeasureGUI_FastCheckIntersectionsDlg.h MeasureGUI_PointDlg.h MeasureGUI_ManageDimensionsDlg.h MeasureGUI_CreateDimensionDlg.h @@ -123,6 +124,7 @@ SET(_moc_HEADERS MeasureGUI_CheckCompoundOfBlocksDlg.h MeasureGUI_GetNonBlocksDlg.h MeasureGUI_CheckSelfIntersectionsDlg.h + MeasureGUI_FastCheckIntersectionsDlg.h MeasureGUI_PointDlg.h MeasureGUI_ManageDimensionsDlg.h MeasureGUI_CreateDimensionDlg.h @@ -154,6 +156,7 @@ SET(MeasureGUI_SOURCES MeasureGUI_CheckCompoundOfBlocksDlg.cxx MeasureGUI_GetNonBlocksDlg.cxx MeasureGUI_CheckSelfIntersectionsDlg.cxx + MeasureGUI_FastCheckIntersectionsDlg.cxx MeasureGUI_PointDlg.cxx MeasureGUI_ManageDimensionsDlg.cxx MeasureGUI_CreateDimensionDlg.cxx diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx index 3f5358745..1c5d61b95 100644 --- a/src/MeasureGUI/MeasureGUI.cxx +++ b/src/MeasureGUI/MeasureGUI.cxx @@ -50,6 +50,7 @@ #include "MeasureGUI_CheckCompoundOfBlocksDlg.h" // Method CHECKCOMPOUND #include "MeasureGUI_GetNonBlocksDlg.h" // Method GET NON BLOCKS #include "MeasureGUI_CheckSelfIntersectionsDlg.h" // Method CHECK SELF INTERSCTIONS +#include "MeasureGUI_FastCheckIntersectionsDlg.h" // Method FAST CHECK INTERSCTIONS #include "MeasureGUI_PointDlg.h" // Method POINTCOORDINATES #include "MeasureGUI_ManageDimensionsDlg.h" // Method MANAGEDIMENSIONS @@ -125,6 +126,9 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpCheckSelfInters: dlg = new MeasureGUI_CheckSelfIntersectionsDlg( getGeometryGUI(), parent ); break; // CHECK SELF INTERSCTIONS + case GEOMOp::OpFastCheckInters: + dlg = new MeasureGUI_FastCheckIntersectionsDlg( getGeometryGUI(), parent ); + break; // FAST CHECK INTERSCTIONS case GEOMOp::OpPointCoordinates: dlg = new MeasureGUI_PointDlg( getGeometryGUI(), parent ); break; // POINT COORDINATES diff --git a/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx new file mode 100644 index 000000000..a9ba9622f --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx @@ -0,0 +1,696 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GEOM GEOMGUI : GUI for Geometry component +// File : MeasureGUI_FastCheckIntersectionsDlg.cxx + +#include "MeasureGUI_FastCheckIntersectionsDlg.h" +#include "MeasureGUI.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define TEXTEDIT_FONT_FAMILY "Courier" +#define TEXTEDIT_FONT_SIZE 11 +//================================================================================= +// class : MeasureGUI_FastCheckIntersectionsDlg() +// purpose : Constructs a MeasureGUI_FastCheckIntersectionsDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// true to construct a modal dialog. +//================================================================================= +MeasureGUI_FastCheckIntersectionsDlg::MeasureGUI_FastCheckIntersectionsDlg (GeometryGUI* GUI, QWidget* parent) + : GEOMBase_Skeleton (GUI, parent, false), + mySelButton1 (0), + mySelButton2 (0), + myEditObjName1 (0), + myEditObjName2 (0), + myDetGaps (0), + myTolerance (0), + myDeflection (0), + myComputeButton (0), + myShapeList1 (0), + myShapeList2 (0) +{ + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FAST_CHECK_INTERSECTIONS"))); + QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_FAST_CHECK_INTERSECTIONS")); + + /***************************************************************/ + mainFrame()->GroupConstructors->setTitle(tr("GEOM_FAST_CHECK_INTERSECTIONS")); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); + mainFrame()->RadioButton3->close(); + + QGroupBox *aGrp = new QGroupBox(tr("GEOM_FAST_CHECK_OBJ")); + QLabel *anObjLbl1 = new QLabel(tr("GEOM_OBJECT_I").arg("1")); + QLabel *anObjLbl2 = new QLabel(tr("GEOM_OBJECT_I").arg("2")); + QLabel *aShapeLbl1 = new QLabel(tr("GEOM_FAST_CHECK_INT_SUBSHAPES").arg("1")); + QLabel *aShapeLbl2 = new QLabel(tr("GEOM_FAST_CHECK_INT_SUBSHAPES").arg("2")); + QLabel *aDeflectLbl = new QLabel(tr("GEOM_FAST_CHECK_INT_DEFLECT")); + QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE); + + aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias); + + mySelButton1 = new QPushButton; + mySelButton1->setIcon(image1); + mySelButton1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mySelButton2 = new QPushButton; + mySelButton2->setIcon(image1); + mySelButton2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + myEditObjName1 = new QLineEdit; + myEditObjName1->setReadOnly(true); + myEditObjName2 = new QLineEdit; + myEditObjName2->setReadOnly(true); + + myDetGaps = new QCheckBox( tr( "GEOM_FAST_CHECK_INT_DETECT_GAPS" )); + myTolerance = new SalomeApp_DoubleSpinBox; + myDeflection = new SalomeApp_DoubleSpinBox; + myShapeList1 = new QListWidget; + myShapeList2 = new QListWidget; + myShapeList1->setSelectionMode(QAbstractItemView::ExtendedSelection); + myShapeList2->setSelectionMode(QAbstractItemView::ExtendedSelection); + + myComputeButton = new QPushButton(tr("GEOM_FAST_CHECK_INT_COMPUTE")); + + QGridLayout *aGrpLayout = new QGridLayout(aGrp); + aGrpLayout->setMargin(9); + aGrpLayout->setSpacing(6); + aGrpLayout->addWidget(anObjLbl1, 0, 0); + aGrpLayout->addWidget(mySelButton1, 0, 1); + aGrpLayout->addWidget(myEditObjName1, 0, 2); + aGrpLayout->addWidget(anObjLbl2, 1, 0); + aGrpLayout->addWidget(mySelButton2, 1, 1); + aGrpLayout->addWidget(myEditObjName2, 1, 2); + aGrpLayout->addWidget(aDeflectLbl, 2, 0); + aGrpLayout->addWidget(myDeflection, 2, 1, 1, 2); + aGrpLayout->addWidget(myDetGaps, 3, 0); + aGrpLayout->addWidget(myTolerance, 3, 1, 1, 2); + aGrpLayout->addWidget(myComputeButton, 4, 0, 1, 3); + + QGridLayout *aGrpLayout2 = new QGridLayout(); + aGrpLayout->addLayout(aGrpLayout2, 5, 0, 1, 3); + aGrpLayout2->addWidget(aShapeLbl1, 0, 0); + aGrpLayout2->addWidget(aShapeLbl2, 0, 1); + aGrpLayout2->addWidget(myShapeList1, 1, 0); + aGrpLayout2->addWidget(myShapeList2, 1, 1); + + QVBoxLayout* layout = new QVBoxLayout (centralWidget()); + layout->setMargin(0); layout->setSpacing(6); + layout->addWidget(aGrp); + + /***************************************************************/ + + myHelpFileName = "fast_intersection_page.html"; + + // Initialisation + Init(); +} + +//================================================================================= +// function : ~MeasureGUI_FastCheckIntersectionsDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +MeasureGUI_FastCheckIntersectionsDlg::~MeasureGUI_FastCheckIntersectionsDlg() +{ +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::Init() +{ + myObj1.nullify(); + myObj2.nullify(); + myEditObjName1->setText(""); + myEditObjName2->setText(""); + myEditObjName1->setEnabled(true); + myEditObjName2->setEnabled(false); + + myDetGaps->setChecked(false); + double SpecificStep = 0.001; + double prec = Precision::Confusion(); + initSpinBox(myTolerance, prec, MAX_NUMBER, SpecificStep); + myTolerance->setValue(SpecificStep); + myTolerance->setEnabled(false); + + // Obtain deflection from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + const char* quantity = "deflection_coeff"; + double aDeflection = resMgr->doubleValue("Geometry", quantity, 0.00001); + initSpinBox(myDeflection, prec, 1.0, aDeflection); + myDeflection->setValue(aDeflection); + + myEditCurrentArgument = myEditObjName1; + + 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(mySelButton1, SIGNAL(clicked()), + this, SLOT(SetEditCurrentArgument())); + 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(myShapeList1, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect(myShapeList2, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect(myComputeButton, SIGNAL(clicked()), this, SLOT(onCompute())); + + LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); + + connect(aSel, SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + initName(tr("GEOM_FAST_INTERSECTION_NAME")); + buttonOk()->setEnabled(false); + buttonApply()->setEnabled(false); + myComputeButton->setEnabled(false); + activateSelection(); + + mySelButton1->click(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : clear +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::clear() +{ + disconnect(myShapeList1, SIGNAL(itemSelectionChanged()), this, 0); + disconnect(myShapeList2, SIGNAL(itemSelectionChanged()), this, 0); + myShapeList1->clear(); + myShapeList2->clear(); + connect(myShapeList1, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect(myShapeList2, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + erasePreview(); + buttonOk()->setEnabled(false); + buttonApply()->setEnabled(false); + myComputeButton->setEnabled(true); +} + +//================================================================================= +// function : onCompute +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::onCompute() +{ + myShapeList1->clear(); + myShapeList2->clear(); + + if (!findIntersections()) { + myShapeList1->addItem(tr("GEOM_FAST_INTERSECTION_FAILS")); + myShapeList1->setEnabled(false); + myShapeList2->addItem(tr("GEOM_FAST_INTERSECTION_FAILS")); + myShapeList2->setEnabled(false); + return; + } + + myShapeList1->setEnabled(true); + myShapeList2->setEnabled(true); + QStringList aSubShapeList1, aSubShapeList2; + TopoDS_Shape aSelShape1, aSelShape2; + if (myObj1 && GEOMBase::GetShape(myObj1.get(), aSelShape1) && myObj2 + && GEOMBase::GetShape(myObj2.get(), aSelShape2)) { + TopTools_IndexedMapOfShape anIndices1, anIndices2; + TopExp::MapShapes(aSelShape1, anIndices1); + TopExp::MapShapes(aSelShape2, anIndices2); + + //Sub-shapes of 1st Object + for (int i = 0; i < myInters1->length(); i++) { + TopoDS_Shape aSubShape = anIndices1.FindKey(myInters1[i]); + QString aType = GEOMBase::GetShapeTypeString(aSubShape); + if (!aType.isEmpty()) + aSubShapeList1.append(QString("%1_%2").arg(aType).arg(myInters1[i])); + } + myShapeList1->addItems(aSubShapeList1); + myShapeList1->selectAll(); + + //Sub-shapes of second Object + for (int i = 0; i < myInters2->length(); i++) { + TopoDS_Shape aSubShape = anIndices2.FindKey(myInters2[i]); + QString aType = GEOMBase::GetShapeTypeString(aSubShape); + if (!aType.isEmpty()) + aSubShapeList2.append(QString("%1_%2").arg(aType).arg(myInters2[i])); + } + myShapeList2->addItems(aSubShapeList2); + myShapeList2->selectAll(); + } + + buttonOk()->setEnabled(true); + buttonApply()->setEnabled(true); + myComputeButton->setEnabled(false); +} + +//================================================================================= +// function : ActivateThisDialog +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + + LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); + if ( aSel ) + connect( aSel, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + + activateSelection(); + DISPLAY_PREVIEW_MACRO +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : public slot to deactivate if active +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::DeactivateActiveDialog() +{ + GEOMBase_Skeleton::DeactivateActiveDialog(); +} + +//================================================================================= +// function : activateSelection +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::activateSelection() +{ + 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 ); + +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::ClickOnOk() +{ + if ( ClickOnApply() ) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool MeasureGUI_FastCheckIntersectionsDlg::ClickOnApply() +{ + if ( !onAccept() ) + return false; + + clear(); + initName(); + return true; +} + +//================================================================================= +// function : extractPrefix +// purpose : +//================================================================================= +bool MeasureGUI_FastCheckIntersectionsDlg::extractPrefix() const +{ + return true; +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr MeasureGUI_FastCheckIntersectionsDlg::createOperation() +{ + return getGeomEngine()->GetIMeasureOperations( getStudyId() ); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool MeasureGUI_FastCheckIntersectionsDlg::isValid( QString& ) +{ + return myObj1 && myObj2; +} + +//================================================================================= +// function : SetEditCurrentArgument +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + if (send == mySelButton1) { + myEditCurrentArgument = myEditObjName1; + + mySelButton2->setDown(false); + myEditObjName2->setEnabled(false); + myObj1.nullify(); + } + else { + myEditCurrentArgument = myEditObjName2; + + mySelButton1->setDown(false); + myEditObjName1->setEnabled(false); + myObj2.nullify(); + } + + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + activateSelection(); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + // enable line edit + myEditCurrentArgument->setEnabled(true); + myEditCurrentArgument->setFocus(); + // after setFocus(), because it will be setDown(false) when loses focus + send->setDown(true); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : OnGaps() +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::OnGaps(bool cheked) +{ + clear(); + myTolerance->setEnabled(cheked); +} +//================================================================================= +// function : SelectionIntoArgument +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::SelectionIntoArgument() +{ + myEditCurrentArgument->setText(""); + // Clear the dialog. + clear(); + + QList typesLst; + typesLst << TopAbs_FACE << TopAbs_SHELL << TopAbs_SOLID << TopAbs_COMPOUND; + GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst ); + + // clear selection + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + myGeomGUI->getApp()->selectionMgr()->clearSelected(); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + if (myEditCurrentArgument == myEditObjName1) { + myObj1 = aSelectedObject; + if (myObj1 && !myObj2) + mySelButton2->click(); + } + else { + myObj2 = aSelectedObject; + if (myObj2 && !myObj1) + mySelButton1->click(); + } + myEditObjName1->setText(myObj1 ? GEOMBase::GetName(myObj1.get()) : ""); + myEditObjName2->setText(myObj2 ? GEOMBase::GetName(myObj2.get()) : ""); +} + +//================================================================================= +// function : enterEvent +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::enterEvent(QEvent *) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : findIntersections +// purpose : +//================================================================================= +bool MeasureGUI_FastCheckIntersectionsDlg::findIntersections() +{ + if (!myObj1 || !myObj2) + return false; + + GEOM::GEOM_IMeasureOperations_var anOper = + GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); + bool isOK = true; + + bool HasInte; + try { + HasInte = anOper->FastIntersect(myObj1.get(), myObj2.get(), getTolerance(), getDeflection(), myInters1, myInters2); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + isOK = false; + } + + bool isDone = anOper->IsDone(); + if (!isDone) { + CORBA::String_var aMsg = anOper->GetErrorCode(); + SUIT_MessageBox::warning(this, + QObject::tr("WRN_WARNING"), + QObject::tr(aMsg.in())); + } + + if ( !HasInte || myInters1->length() == 0 || myInters2->length() == 0) + isOK = false; + + return isOK; +} + +//================================================================================= +// function : onSubShapesListSelectionChanged +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::onSubShapesListSelectionChanged() +{ + erasePreview(); + previewSubShapesListSelection(myShapeList1); + previewSubShapesListSelection(myShapeList2); +} + +//================================================================================= +// function : previewSubShapesListSelection +// purpose : +//================================================================================= +void MeasureGUI_FastCheckIntersectionsDlg::previewSubShapesListSelection(QListWidget* theWidget) +{ + GEOM::ListOfLong_var anInters; + GEOM::GeomObjPtr anObj; + + if (theWidget == myShapeList1) { // Sub-Shapes of Object 1 + anObj = myObj1; + anInters = myInters1; + } + else { + if (theWidget == myShapeList2) { // Sub-Shapes of Object 2 + anObj = myObj2; + anInters = myInters2; + } + else return; + } + // Selected IDs + QList aIds; + for (int i = 0, n = theWidget->count(); i < n; i++) { + if (theWidget->item(i)->isSelected()) + aIds.append(i); + } + if (aIds.count() < 1) + return; + + TopoDS_Shape aSelShape; + TopoDS_Shape aSubShape; + TopTools_IndexedMapOfShape anIndices; + if (anObj && GEOMBase::GetShape(anObj.get(), aSelShape)) { + SALOME_Prs* aPrs = 0; + TopExp::MapShapes(aSelShape, anIndices); + QList::iterator it; + for (it = aIds.begin(); it != aIds.end(); ++it) { + aSubShape = anIndices.FindKey(anInters[(*it)]); + try { + getDisplayer()->SetColor(Quantity_NOC_RED); + getDisplayer()->SetWidth(3); + getDisplayer()->SetToActivate(false); + aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; + if (aPrs) + displayPreview(aPrs, true); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + } + } + } +} + +//================================================================================= +// function : getLstObjFromListSelection +// purpose : +//================================================================================= +GEOM::ListOfGO_var MeasureGUI_FastCheckIntersectionsDlg::getLstObjFromListSelection(QListWidget* theWidget) +{ + GEOM::ListOfLong_var anInters; + GEOM::GeomObjPtr anObj; + GEOM::ListOfGO_var anObjLst = new GEOM::ListOfGO(); + + if (theWidget == myShapeList1) { // Sub-Shapes of Object 1 + anObj = myObj1; + anInters = myInters1; + } + else { + if (theWidget == myShapeList2) { // Sub-Shapes of Object 2 + anObj = myObj2; + anInters = myInters2; + } + else + return anObjLst; + } + //Add in study myObj if local selection + GEOMBase::PublishSubObject( anObj.get() ); + // Collect the map of indices and already publised objects + TColStd_IndexedMapOfInteger aMapIndex; + ObjectList aObjLstExist; + for (int i = 0, n = theWidget->count(); i < n; i++) { + if (theWidget->item(i)->isSelected()) { + GEOM::GEOM_Object_var aTmpObj = GEOMBase_Helper::findObjectInFather(anObj.get(), anInters[i]); + if (aTmpObj->_is_nil()) + aMapIndex.Add(anInters[i]); + else + aObjLstExist.push_back( GEOM::GEOM_Object::_duplicate(aTmpObj)); + } + } + + if (aMapIndex.IsEmpty() && aObjLstExist.empty()) + return anObjLst; + + // Create objects. + GEOM::ListOfLong_var anArray = new GEOM::ListOfLong; + const int aNbShapes = aMapIndex.Extent(); + anArray->length(aNbShapes); + for (int i = 1; i <= aNbShapes; i++) { + anArray[i - 1] = aMapIndex.FindKey(i); + } + + if (myShapesOper->_is_nil()) + myShapesOper = getGeomEngine()->GetIShapesOperations(getStudyId()); + + GEOM::ListOfGO_var aObjLstCreate = myShapesOper->MakeSubShapes(anObj.get(), anArray); + + //Collect all objects in list + anObjLst->length(aObjLstCreate->length() + aObjLstExist.size()); + + ObjectList::iterator anIter; + int i; + for (i=0, anIter = aObjLstExist.begin(); anIter != aObjLstExist.end(); i++, ++anIter) { + anObjLst[i] = *anIter; + } + for (int j = 0; j < aObjLstCreate->length(); j++) { + anObjLst[aObjLstExist.size()+j]=aObjLstCreate[j]; + } + return anObjLst._retn(); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool MeasureGUI_FastCheckIntersectionsDlg::execute(ObjectList& objects) +{ + GEOM::ListOfGO_var aList1 = getLstObjFromListSelection(myShapeList1); + GEOM::ListOfGO_var aList2 = getLstObjFromListSelection(myShapeList2); + GEOM::ListOfGO_var aCompList = new GEOM::ListOfGO(); + const int nbObj = aList1->length() + aList2->length(); + if (nbObj <= 0) + return true; + + //Collect general intersection list + aCompList->length(nbObj); + int i; + for (i = 0; i < aList1->length(); i++) { + GEOMBase::PublishSubObject( aList1[i] ); + aCompList[i]=aList1[i]; + } + for (int j = 0; j < aList2->length(); j++) { + GEOMBase::PublishSubObject( aList2[j] ); + aCompList[i+j]=aList2[j]; + } + + // make compound + objects.push_back(myShapesOper->MakeCompound(aCompList)); + return true; +} + +//================================================================================= +// function : getDeflection +// purpose : +//================================================================================= +float MeasureGUI_FastCheckIntersectionsDlg::getDeflection() +{ + return (float)myDeflection->value(); +} + +//================================================================================= +// function : getTolerance +// purpose : +//================================================================================= +double MeasureGUI_FastCheckIntersectionsDlg::getTolerance() +{ + double aVal = myTolerance->value(); + if (!myDetGaps->isChecked() || aVal < 0.0) + return 0.0; + return aVal; +} diff --git a/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.h b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.h new file mode 100644 index 000000000..745911a8a --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.h @@ -0,0 +1,98 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GEOM GEOMGUI : GUI for Geometry component +// File : MeasureGUI_FastCheckIntersectionsDlg.h + +#ifndef MEASUREGUI_FASTCHECKINTERDLG_H +#define MEASUREGUI_FASTCHECKINTERDLG_H + +#include + +class QListWidget; + +//================================================================================= +// class : MeasureGUI_FastCheckIntersectionsDlg +// purpose : +//================================================================================= + +class MeasureGUI_FastCheckIntersectionsDlg : public GEOMBase_Skeleton +{ + Q_OBJECT + +public: + + MeasureGUI_FastCheckIntersectionsDlg(GeometryGUI*, QWidget*); + ~MeasureGUI_FastCheckIntersectionsDlg(); + +protected: + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid(QString &); + virtual bool execute(ObjectList &); + virtual bool extractPrefix() const; + +private slots: + + void onSubShapesListSelectionChanged(); + void clear(); + void onCompute(); + void ClickOnOk(); + bool ClickOnApply(); + void ActivateThisDialog(); + void DeactivateActiveDialog(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); + void OnGaps(bool); + +private: + + void Init(); + void activateSelection(); + void enterEvent(QEvent *); + bool findIntersections(); + float getDeflection(); + double getTolerance(); + void previewSubShapesListSelection(QListWidget*); + GEOM::ListOfGO_var getLstObjFromListSelection(QListWidget*); + +private: + + QPushButton *mySelButton1; + QPushButton *mySelButton2; + QLineEdit *myEditObjName1; + QLineEdit *myEditObjName2; + QLineEdit *myEditCurrentArgument; + QCheckBox *myDetGaps; + SalomeApp_DoubleSpinBox *myTolerance; + SalomeApp_DoubleSpinBox *myDeflection; + QPushButton *myComputeButton; + QListWidget *myShapeList1; + QListWidget *myShapeList2; + GEOM::GeomObjPtr myObj1; + GEOM::GeomObjPtr myObj2; + GEOM::ListOfLong_var myInters1; + GEOM::ListOfLong_var myInters2; + GEOM::GEOM_IShapesOperations_var myShapesOper; +}; + +#endif // MEASUREGUI_FASTCHECKINTERDLG_H