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-Tag: V7_6_0a1~60^2~14 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ed5673f40bde611ab306086e0eacf64ebb764f6c;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/check_shape.py b/doc/salome/examples/check_shape.py index a0e728967..f10f31c8a 100644 --- a/doc/salome/examples/check_shape.py +++ b/doc/salome/examples/check_shape.py @@ -10,7 +10,7 @@ geompy = geomBuilder.New(salome.myStudy) box = geompy.MakeBoxDXDYDZ(100,30,100) (IsValid, err) = geompy.CheckShape(box, 0, 2) if IsValid == 0: - geompy.PrintShapeError(box, err) + geompy.PrintShapeErrors(box, err) raise RuntimeError, "Invalid box created" else: print "\nBox is valid" 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..4de27fc29 --- /dev/null +++ b/doc/salome/gui/GEOM/input/fast_intersection.doc @@ -0,0 +1,61 @@ +/*! +\page fast_intersection_page Fast intersection + +This operation checks whether or not two selected shapes are overlapped. + +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. +Due to this fact, the tool is not suitable for computing exact intersection +of shapes; however, it can be used to quickly find zones where +intersections can present, and then use these results in further analysis. + +\note For more information about Partition and Boolean Operations Algorithms +and their limitations refer to this document. + +\image html measures12.png + +\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. + +In this dialog: + +- \b Object 1 - first checked object. \b Selection button allows picking it in the viewer or in the object browser. +- \b Object 2 - second checked object. \b Selection button allows picking it in the viewer or in the object browser. +- Deflection coefficient specifies the quality of shapes tessellation. +- Detect gaps - when switched on, allows detecting gaps between shapes. +- Tolerance - specifies a distance between shapes used for detecting gaps. +- Compute intersections - press this button to compute interferences. +- Sub-shapes of Object 1 - list of sub-shapes from the first source shape that localize the intersection. +- Sub-shapes of Object 2 - list of sub-shapes from the second source shape that localize the intersection. +- \b Apply and Apply and Close buttons are used to store selected intersected shapes in the study for +further analysis (see below). + +\note Quality of the result depends on the quality of triangulation. Changing a value of the deflection coefficient +parameter can strongly affect the result. On the other hand, small values of deflection coefficient might lead to +some performance loss of the algorithm, as number of triangles of the tesselation mesh depends on this parameter. + +It is possible to store sub-shapes selected by the user in the study, for the further analysis. +The selection will be published as a compound containing intersected sub-shapes from both source objects. + +TUI Command: geompy.FastIntersect(theShape1, theShape2, theTolerance = 0.0, theDeflection = 0.001), \n +where: +- \em theShape1 First shape. +- \em theShape2 Second shape. +- \em theTolerance When it is negative or equal to zero, the function detects intersections; + when it is positive, the function detects gaps. +- \em theDeflection Linear deflection for shapes; if deflection <= 0, default deflection 0.001 is used + +Result: Boolean + two lists of IDs of sub-shapes (from input shapes) that localize the intersection. + +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..b954b7f60 100644 --- a/doc/salome/gui/GEOM/input/tui_test_measures.doc +++ b/doc/salome/gui/GEOM/input/tui_test_measures.doc @@ -14,9 +14,12 @@ \until CheckShape \anchor swig_CheckShape -\until MakeCompound +\until Detect Self-intersections \anchor swig_CheckSelfIntersections +\until Detect Fast intersection + +\anchor swig_FastIntersection \until WhatIs \anchor swig_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 78e9bfca2..6a38a71db 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4330,6 +4330,26 @@ module GEOM in long theCheckLevel, out ListOfLong theIntersections); + /*! + * \brief Detect intersections of the given shapes with algorithm based on mesh intersections. + * \param theShape1 First source object + * \param theShape2 Second source object + * \param theTolerance Specifies a distance between shapes used for detecting gaps: + * - if \a theTolerance <= 0, algorithm detects intersections + * - if \a theTolerance > 0, algorithm detects gaps + * \param theDeflection Linear deflection coefficient that specifies quality of tesselation: + * - if \a theDeflection <= 0, default deflection 0.001 is used + * \param theIntersections1 Output: contains list of sub-shapes IDs from 1st shape that localize intersection + * \param theIntersections2 Output: contains list of sub-shapes IDs from 2nd shape that localize intersection + * \return TRUE, if the are intersections (gaps) between source shapes + */ + 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 60ea6bd8a..c555dbd48 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -259,6 +259,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 43fa10a06..6877d9c7c 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -255,6 +255,10 @@ ICON_DLG_CHECK_SELF_INTERSECTIONS check_self_intersections.png + + ICON_DLG_FAST_CHECK_INTERSECTIONS + fast_intersect.png + ICON_DLG_CIRCLE_PNTS circle3points.png @@ -883,6 +887,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 45b178e5e..86e1622a7 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 @@ -2500,6 +2504,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 @@ -3505,6 +3513,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 @@ -4116,6 +4128,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 @@ -7138,6 +7154,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/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 0d42a5b67..62edf1628 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -431,6 +431,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_CHECK_SELF_INTERSECTIONS Détecter les auto-intersections + + GEOM_FAST_CHECK_INTERSECTIONS + Fast intersection + GEOM_CHECK_SELF_INTERSECTIONS_FAILED La détection d'auto-intersections a échoué @@ -2464,6 +2468,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_CHECK_SELF_INTERSECTIONS Détections des auto-intersections + + MEN_FAST_CHECK_INTERSECTIONS + Fast intersection + MEN_CHECK_FREE_BNDS Contrôler les contours libres @@ -3452,6 +3460,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_CHECK_SELF_INTERSECTIONS Détecte les auto-intersections + + STB_FAST_CHECK_INTERSECTIONS + Fast intersection + STB_CHECK_FREE_BNDS Vérifier les contours libres @@ -4060,6 +4072,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau TOP_CHECK_SELF_INTERSECTIONS Détection des auto-intersections + + TOP_FAST_CHECK_INTERSECTIONS + Fast intersection + TOP_CHECK_FREE_BNDS Valider les contours libres @@ -6999,4 +7015,160 @@ Voulez-vous en créer un nouveau ? V-Isoligne + + MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTE_INTERSECTIONS + Self-intersections + + + GEOM_CHECK_INTE_SUBSHAPES + Sub-shapes + + + GEOM_CHECK_INTE_CHECK_LEVEL + Level of check + + + GEOM_CHECK_INTE_SUMMARY + Summary + + + GEOM_CHECK_INTE_COMPUTE + Compute self-intersections + + + GEOM_SELF_INTERSECTION_NAME + Self_intersection + + + GEOM_NO_SELF_INTERSECTIONS + There are no self-intersections in the shape + + + GEOM_SELF_INTERSECTIONS_FOUND + Some self-intersections detected + + + GEOM_CHECK_SELF_INTERSECTIONS_FAILED + Detection of self-intersections failed + + + GEOM_CHECK_SELF_INTERSECTIONS_ERRORS + Warning: there were errors during the operation, so the list may be incomplete. + + + GEOM_CHECK_INTE_V_V + Vertex to Vertex + + + GEOM_CHECK_INTE_V_E + Vertex to Edge + all above + + + GEOM_CHECK_INTE_E_E + Edge to Edge + all above + + + GEOM_CHECK_INTE_V_F + Vertex to Face + all above + + + GEOM_CHECK_INTE_E_F + Edge to Face + all above + + + GEOM_CHECK_INTE_ALL + 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 + + GEOM_EXTENSION_TITLE + Extension of Edge or Face + + + GEOM_EXTENSION + Extension + + + GEOM_EXTENSION_MIN + First Parameter + + + GEOM_EXTENSION_MAX + Last Parameter + + + GEOM_EXTENSION_MIN_U + First U-Parameter + + + GEOM_EXTENSION_MAX_U + Last U-Parameter + + + GEOM_EXTENSION_MIN_V + First V-Parameter + + + GEOM_EXTENSION_MAX_V + Last V-Parameter + + + GEOM_EXTENSION_EDGE_NAME + ExtendedEdge + + + GEOM_EXTENSION_FACE_NAME + ExtendedFace + + + + EntityGUI_SurfFromFaceDlg + + GEOM_SURF_FROM_FACE_TITLE + Surface From Face Construction + + + GEOM_SURF_FROM_FACE + Surface From Face + + + GEOM_SURF_FROM_FACE_NAME + SurfaceFromFace + + diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index d7d25aab4..8ef05204b 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -411,6 +411,10 @@ GEOM_CHECK_SELF_INTERSECTIONS 自己交差の検出 + + GEOM_FAST_CHECK_INTERSECTIONS + Fast intersection + GEOM_CHECK_SELF_INTERSECTIONS_FAILED 自己交差の検出に失敗しました @@ -2447,6 +2451,10 @@ MEN_CHECK_SELF_INTERSECTIONS 自己交差の確認 + + MEN_FAST_CHECK_INTERSECTIONS + Fast intersection + MEN_CHECK_FREE_BNDS 自由境界の確認 @@ -3439,6 +3447,10 @@ STB_CHECK_SELF_INTERSECTIONS 自己交差の確認 + + STB_FAST_CHECK_INTERSECTIONS + Fast intersection + STB_CHECK_FREE_BNDS 自由境界をチェック @@ -4047,6 +4059,10 @@ TOP_CHECK_SELF_INTERSECTIONS 自己交差の確認 + + TOP_FAST_CHECK_INTERSECTIONS + Fast intersection + TOP_CHECK_FREE_BNDS 自由境界を確認 @@ -6976,4 +6992,160 @@ V-Isoline + + MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTE_INTERSECTIONS + Self-intersections + + + GEOM_CHECK_INTE_SUBSHAPES + Sub-shapes + + + GEOM_CHECK_INTE_CHECK_LEVEL + Level of check + + + GEOM_CHECK_INTE_SUMMARY + Summary + + + GEOM_CHECK_INTE_COMPUTE + Compute self-intersections + + + GEOM_SELF_INTERSECTION_NAME + Self_intersection + + + GEOM_NO_SELF_INTERSECTIONS + There are no self-intersections in the shape + + + GEOM_SELF_INTERSECTIONS_FOUND + Some self-intersections detected + + + GEOM_CHECK_SELF_INTERSECTIONS_FAILED + Detection of self-intersections failed + + + GEOM_CHECK_SELF_INTERSECTIONS_ERRORS + Warning: there were errors during the operation, so the list may be incomplete. + + + GEOM_CHECK_INTE_V_V + Vertex to Vertex + + + GEOM_CHECK_INTE_V_E + Vertex to Edge + all above + + + GEOM_CHECK_INTE_E_E + Edge to Edge + all above + + + GEOM_CHECK_INTE_V_F + Vertex to Face + all above + + + GEOM_CHECK_INTE_E_F + Edge to Face + all above + + + GEOM_CHECK_INTE_ALL + 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 + + GEOM_EXTENSION_TITLE + Extension of Edge or Face + + + GEOM_EXTENSION + Extension + + + GEOM_EXTENSION_MIN + First Parameter + + + GEOM_EXTENSION_MAX + Last Parameter + + + GEOM_EXTENSION_MIN_U + First U-Parameter + + + GEOM_EXTENSION_MAX_U + Last U-Parameter + + + GEOM_EXTENSION_MIN_V + First V-Parameter + + + GEOM_EXTENSION_MAX_V + Last V-Parameter + + + GEOM_EXTENSION_EDGE_NAME + ExtendedEdge + + + GEOM_EXTENSION_FACE_NAME + ExtendedFace + + + + EntityGUI_SurfFromFaceDlg + + GEOM_SURF_FROM_FACE_TITLE + Surface From Face Construction + + + GEOM_SURF_FROM_FACE + Surface From Face + + + GEOM_SURF_FROM_FACE_NAME + SurfaceFromFace + + diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index a8e6f6bca..883347659 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -638,6 +638,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 @@ -1016,6 +1017,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" ); @@ -1273,6 +1275,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 @@ -1420,6 +1423,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 7243340f4..8b01f7a0f 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -194,6 +194,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 29436dabc..2a8896281 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 @@ -48,7 +49,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..3d7601a76 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,88 @@ 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(); + + // 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)); + } + + isGood = !theIntersections1->IsEmpty() && !theIntersections1->IsEmpty(); + + if (aBSP.IsDone()) + SetErrorCode(OK); + + return isGood; +} //============================================================================= /*! * IsGoodForSolid diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 3b8ae3d42..9712e33c2 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..e8a8272a8 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..6f595d521 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 b5e1ca808..fd3cecc0e 100755 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4869,7 +4869,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @param theShape Shape to find free faces in. # @return List of IDs of all free faces, contained in theShape. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_free_faces_page "Example" @ManageTransactions("ShapesOp") def GetFreeFacesIDs(self,theShape): """ @@ -7000,7 +7000,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # \n \a theClosedWires: Closed wires on the free boundary of the given shape. # \n \a theOpenWires: Open wires on the free boundary of the given shape. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_free_boundaries_page "Example" @ManageTransactions("HealOp") def GetFreeBoundary(self, theObject, theName=None): """ @@ -10008,7 +10008,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): ## Get point coordinates # @return [x, y, z] # - # @ref tui_measurement_tools_page "Example" + # @ref tui_point_coordinates_page "Example" @ManageTransactions("MeasuOp") def PointCoordinates(self,Point): """ @@ -10084,7 +10084,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # theSurfArea: Area of surface of the given shape.\n # theVolume: Volume of the given shape. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_basic_properties_page "Example" @ManageTransactions("MeasuOp") def BasicProperties(self,theShape): """ @@ -10113,7 +10113,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # Ymin,Ymax: Limits of shape along OY axis. # Zmin,Zmax: Limits of shape along OZ axis. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_bounding_box_page "Example" @ManageTransactions("MeasuOp") def BoundingBox (self, theShape, precise=False): """ @@ -10143,7 +10143,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @return New GEOM.GEOM_Object, containing the created box. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_bounding_box_page "Example" @ManageTransactions("MeasuOp") def MakeBoundingBox (self, theShape, precise=False, theName=None): """ @@ -10171,7 +10171,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # I(1-3)(1-3): Components of the inertia matrix of the given shape. # Ix,Iy,Iz: Moments of inertia of the given shape. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_inertia_page "Example" @ManageTransactions("MeasuOp") def Inertia(self,theShape): """ @@ -10214,7 +10214,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @param theShape1,theShape2 Shapes to find minimal distance between. # @return Value of the minimal distance between the given shapes. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_min_distance_page "Example" @ManageTransactions("MeasuOp") def MinDistance(self, theShape1, theShape2): """ @@ -10236,7 +10236,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @return Value of the minimal distance between the given shapes, in form of list # [Distance, DX, DY, DZ]. # - # @ref swig_all_measure "Example" + # @ref tui_min_distance_page "Example" @ManageTransactions("MeasuOp") def MinDistanceComponents(self, theShape1, theShape2): """ @@ -10260,7 +10260,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @return The number of found solutions (-1 in case of infinite number of # solutions) and a list of (X, Y, Z) coordinates for all couples of points. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_min_distance_page "Example" @ManageTransactions("MeasuOp") def ClosestPoints (self, theShape1, theShape2): """ @@ -10284,7 +10284,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # with their orientations, otherwise the minimum angle is computed. # @return Value of the angle between the given shapes in degrees. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_angle_page "Example" @ManageTransactions("MeasuOp") def GetAngle(self, theShape1, theShape2): """ @@ -10311,7 +10311,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # with their orientations, otherwise the minimum angle is computed. # @return Value of the angle between the given shapes in radians. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_angle_page "Example" @ManageTransactions("MeasuOp") def GetAngleRadians(self, theShape1, theShape2): """ @@ -10339,7 +10339,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # if False, the opposite vector to the normal vector is used. # @return Value of the angle between the given vectors in degrees. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_angle_page "Example" @ManageTransactions("MeasuOp") def GetAngleVectors(self, theShape1, theShape2, theFlag = True): """ @@ -10532,7 +10532,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # EdgeMin,EdgeMax: Min and max tolerances of the edges.\n # VertMin,VertMax: Min and max tolerances of the vertices. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_tolerance_page "Example" @ManageTransactions("MeasuOp") def Tolerance(self,theShape): """ @@ -10556,7 +10556,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @param theShape Shape to be described. # @return Description of the given shape. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_whatis_page "Example" @ManageTransactions("MeasuOp") def WhatIs(self,theShape): """ @@ -10643,7 +10643,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @return New GEOM.GEOM_Object, containing the created point. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_center_of_mass_page "Example" @ManageTransactions("MeasuOp") def MakeCDG(self, theShape, theName=None): """ @@ -10789,7 +10789,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @return If theReturnStatus is equal to 1 the description is returned. # Otherwise doesn't return anything. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_check_shape_page "Example" @ManageTransactions("MeasuOp") def PrintShapeErrors(self, theShape, theShapeErrors, theReturnStatus = 0): """ @@ -10829,7 +10829,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # If theReturnStatus is equal to 2 the list of error data is # returned along with IsValid flag. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_check_shape_page "Example" @ManageTransactions("MeasuOp") def CheckShape(self,theShape, theIsCheckGeom = 0, theReturnStatus = 0): """ @@ -10884,7 +10884,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # - GEOM.SI_ALL(5) - all interferences. # @return TRUE, if the shape contains no self-intersections. # - # @ref tui_measurement_tools_page "Example" + # @ref tui_check_self_intersections_page "Example" @ManageTransactions("MeasuOp") def CheckSelfIntersections(self, theShape, theCheckLevel = GEOM.SI_ALL): """ @@ -10909,6 +10909,43 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("CheckSelfIntersections", 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 + # @param theTolerance Specifies a distance between shapes used for detecting gaps: + # - if \a theTolerance <= 0, algorithm detects intersections (default behavior) + # - if \a theTolerance > 0, algorithm detects gaps + # @param theDeflection Linear deflection coefficient that specifies quality of tesselation: + # - if \a theDeflection <= 0, default deflection 0.001 is used + # @return TRUE, if there are intersections (gaps) between source shapes + # @return List of sub-shapes IDs from 1st shape that localize intersection. + # @return List of sub-shapes IDs from 2nd shape that localize intersection. + # + # @ref tui_fast_intersection_page "Example" + @ManageTransactions("MeasuOp") + def FastIntersect(self, theShape1, theShape2, theTolerance = 0.0, theDeflection = 0.001): + """ + Detect intersections of the given shapes with algorithm based on mesh intersections. + + Parameters: + theShape1 First source object + theShape2 Second source object + theTolerance Specifies a distance between shapes used for detecting gaps: + - if theTolerance <= 0, algorithm detects intersections (default behavior) + - if theTolerance > 0, algorithm detects gaps + theDeflection Linear deflection coefficient that specifies quality of tesselation: + - if theDeflection <= 0, default deflection 0.001 is used + + Returns: + TRUE, if there are intersections (gaps) between source shapes + List of sub-shapes IDs from 1st shape that localize intersection. + List of sub-shapes IDs from 2nd shape that localize 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. @@ -11710,7 +11747,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @return TRUE, if the given shape is a compound of blocks. # If theCompound is not valid, prints all discovered errors. # - # @ref tui_measurement_tools_page "Example 1" + # @ref tui_check_compound_of_blocks_page "Example 1" # \n @ref swig_CheckCompoundOfBlocks "Example 2" @ManageTransactions("BlocksOp") def CheckCompoundOfBlocks(self,theCompound): @@ -11749,7 +11786,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # presence of non-quadrangular faces). The second object is a # group of all non quadrangular faces. # - # @ref tui_measurement_tools_page "Example 1" + # @ref tui_get_non_blocks_page "Example 1" # \n @ref swig_GetNonBlocks "Example 2" @ManageTransactions("BlocksOp") def GetNonBlocks (self, theShape, theName=None): 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