From f751596e462c483e8172d2cd339acef9298bcfc6 Mon Sep 17 00:00:00 2001 From: vpa Date: Mon, 6 Apr 2015 12:31:00 +0300 Subject: [PATCH] 0024623: Visualization - improve selection mechanism Redesign of selection mechanism: - implemented 3-level BVH tree for selection; - selection now calculates in 3D space; - intersection tests were moved to SelectMgr_BaseFrustum descendants; - removed .cdl files in Select3D and .cdl related to selection in MeshVS; - SelectMgr_ViewerSelectors are now shared between local and global contexts; - transformations of sensitive entities are now stored in SelectMgr_SelectableObject only. Sensitive entities are independent from transformations, it is applied to SelectMgr_SelectingVolumeManager instance only; - connected and multiple connected interactive objects are now represented by their child objects only for SelectMgr_SelectionManager; - if interactive object has child objects, they will be stored as separate objects in SelectMgr_SelectionManager now. - test cases bugs/vis/bug24623_1, bug24623_2, bug24623_3, bug24623_4 to test performance and memory issues. --- .../mfc/standard/01_Geometry/CMakeLists.txt | 6 +- .../01_Geometry/adm/win/vc10/Geometry.vcxproj | 19 - .../adm/win/vc10/Geometry.vcxproj.filters | 6 - .../ISession2D/ISession2D_SensitiveCurve.cpp | 138 -- .../ISession2D/ISession2D_SensitiveCurve.h | 86 -- samples/mfc/standard/01_Geometry/src/StdAfx.h | 1 - samples/mfc/standard/03_Viewer2d/src/StdAfx.h | 2 - .../standard/04_Viewer3d/src/Viewer3dView.cpp | 8 +- .../mfc/standard/05_ImportExport/src/StdAfx.h | 2 - samples/mfc/standard/06_Ocaf/src/StdAfx.h | 2 - samples/mfc/standard/08_HLR/src/StdAfx.h | 2 - .../09_Animation/src/AnimationView3D.cpp | 8 +- .../mfc/standard/09_Animation/src/StdAfx.h | 2 - .../10_Convert/src/WNT/OCCDemoView.cpp | 8 +- samples/mfc/standard/Common/OCC_2dView.cpp | 8 +- samples/mfc/standard/Common/OCC_3dView.cpp | 8 +- samples/mfc/standard/Common/StdAfx.h | 1 - src/AIS/AIS_Axis.cxx | 1 + src/AIS/AIS_Chamf2dDimension.cxx | 1 + src/AIS/AIS_Chamf3dDimension.cxx | 1 + src/AIS/AIS_Circle.cxx | 1 + src/AIS/AIS_ConcentricRelation.cxx | 1 + src/AIS/AIS_ConnectedInteractive.cxx | 33 +- src/AIS/AIS_Dimension.cxx | 2 - src/AIS/AIS_Dimension.hxx | 1 - src/AIS/AIS_EqualRadiusRelation.cxx | 1 + src/AIS/AIS_FixRelation.cxx | 1 + src/AIS/AIS_IdenticRelation.cxx | 1 + src/AIS/AIS_InteractiveContext.cdl | 59 +- src/AIS/AIS_InteractiveContext.cxx | 96 +- src/AIS/AIS_InteractiveContext_1.cxx | 5 +- src/AIS/AIS_InteractiveContext_2.cxx | 87 +- src/AIS/AIS_InteractiveObject.cdl | 6 + src/AIS/AIS_InteractiveObject.cxx | 61 + src/AIS/AIS_Line.cxx | 1 + src/AIS/AIS_LocalContext.cdl | 57 +- src/AIS/AIS_LocalContext.cxx | 143 +- src/AIS/AIS_LocalContext_1.cxx | 42 +- src/AIS/AIS_MaxRadiusDimension.cxx | 1 + src/AIS/AIS_MidPointRelation.cxx | 1 + src/AIS/AIS_MinRadiusDimension.cxx | 1 + src/AIS/AIS_MultipleConnectedInteractive.cxx | 69 +- src/AIS/AIS_OffsetDimension.cxx | 1 + src/AIS/AIS_ParallelRelation.cxx | 1 + src/AIS/AIS_PerpendicularRelation.cxx | 1 + src/AIS/AIS_Plane.lxx | 2 +- src/AIS/AIS_PlaneTrihedron.cxx | 1 + src/AIS/AIS_SymmetricRelation.cxx | 1 + src/AIS/AIS_TangentRelation.cxx | 1 + src/BVH/BVH_BinnedBuilder.hxx | 7 +- src/BVH/BVH_BinnedBuilder.lxx | 50 +- src/BVH/BVH_SpatialMedianBuilder.hxx | 3 +- src/BVH/BVH_SpatialMedianBuilder.lxx | 6 +- src/IVtk/IVtk_IShapePickerAlgo.hxx | 1 - src/IVtk/IVtk_IView.hxx | 16 + src/IVtkOCC/IVtkOCC_SelectableObject.cxx | 10 + src/IVtkOCC/IVtkOCC_SelectableObject.hxx | 3 + src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx | 21 +- src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx | 6 - src/IVtkOCC/IVtkOCC_ViewerSelector.cxx | 296 ++-- src/IVtkOCC/IVtkOCC_ViewerSelector.hxx | 24 +- src/IVtkVTK/IVtkVTK_View.cxx | 54 + src/IVtkVTK/IVtkVTK_View.hxx | 14 + src/MeshVS/FILES | 10 + src/MeshVS/MeshVS.cdl | 11 +- src/MeshVS/MeshVS_DummySensitiveEntity.cdl | 55 - src/MeshVS/MeshVS_DummySensitiveEntity.cxx | 73 +- src/MeshVS/MeshVS_DummySensitiveEntity.hxx | 56 + src/MeshVS/MeshVS_Mesh.cdl | 6 +- src/MeshVS/MeshVS_SensitiveFace.cdl | 54 - src/MeshVS/MeshVS_SensitiveFace.cxx | 72 +- src/MeshVS/MeshVS_SensitiveFace.hxx | 49 + src/MeshVS/MeshVS_SensitiveMesh.cdl | 69 - src/MeshVS/MeshVS_SensitiveMesh.cxx | 194 +-- src/MeshVS/MeshVS_SensitiveMesh.hxx | 63 + src/MeshVS/MeshVS_SensitivePolyhedron.cdl | 78 - src/MeshVS/MeshVS_SensitivePolyhedron.cxx | 341 ++--- src/MeshVS/MeshVS_SensitivePolyhedron.hxx | 85 ++ src/MeshVS/MeshVS_SensitiveSegment.cdl | 53 - src/MeshVS/MeshVS_SensitiveSegment.cxx | 69 +- src/MeshVS/MeshVS_SensitiveSegment.hxx | 44 + src/PrsMgr/PrsMgr_PresentableObject.cdl | 5 + src/PrsMgr/PrsMgr_PresentableObject.cxx | 1 + src/PrsMgr/PrsMgr_PresentableObject.lxx | 5 + src/QABugs/QABugs_11.cxx | 2 +- src/QABugs/QABugs_9.cxx | 2 +- src/QABugs/QABugs_MyText.cdl | 6 +- src/QABugs/QABugs_MyText.cxx | 7 - src/Select3D/FILES | 44 +- src/Select3D/Select3D.cdl | 70 +- src/Select3D/Select3D_BVHPrimitiveContent.cxx | 80 + src/Select3D/Select3D_BVHPrimitiveContent.hxx | 57 + ...SensitiveBox.lxx => Select3D_BndBox3d.hxx} | 23 +- .../Select3D_BoundarySensitivePointSet.cxx | 95 ++ .../Select3D_BoundarySensitivePointSet.hxx | 67 + src/Select3D/Select3D_Box2d.hxx | 95 -- src/Select3D/Select3D_EntitySequence.hxx | 11 + src/Select3D/Select3D_ISensitivePointSet.hxx | 70 + .../Select3D_InteriorSensitivePointSet.cxx | 418 +++++ .../Select3D_InteriorSensitivePointSet.hxx | 109 ++ src/Select3D/Select3D_Pnt2d.hxx | 46 - src/Select3D/Select3D_PointData.hxx | 36 +- src/Select3D/Select3D_Projector.cdl | 257 ---- src/Select3D/Select3D_Projector.cxx | 492 ------ src/Select3D/Select3D_Projector.lxx | 145 -- src/Select3D/Select3D_SensitiveBox.cdl | 121 -- src/Select3D/Select3D_SensitiveBox.cxx | 224 +-- src/Select3D/Select3D_SensitiveBox.hxx | 88 ++ src/Select3D/Select3D_SensitiveCircle.cdl | 155 -- src/Select3D/Select3D_SensitiveCircle.cxx | 571 +++---- src/Select3D/Select3D_SensitiveCircle.hxx | 124 ++ src/Select3D/Select3D_SensitiveCurve.cdl | 139 -- src/Select3D/Select3D_SensitiveCurve.cxx | 286 +--- src/Select3D/Select3D_SensitiveCurve.hxx | 91 ++ src/Select3D/Select3D_SensitiveCurve.lxx | 15 - src/Select3D/Select3D_SensitiveEntity.cdl | 135 -- src/Select3D/Select3D_SensitiveEntity.cxx | 161 +- src/Select3D/Select3D_SensitiveEntity.hxx | 92 ++ src/Select3D/Select3D_SensitiveFace.cdl | 118 -- src/Select3D/Select3D_SensitiveFace.cxx | 293 +--- src/Select3D/Select3D_SensitiveFace.hxx | 108 ++ src/Select3D/Select3D_SensitiveGroup.cdl | 150 -- src/Select3D/Select3D_SensitiveGroup.cxx | 471 +++--- src/Select3D/Select3D_SensitiveGroup.hxx | 149 ++ src/Select3D/Select3D_SensitiveGroup.lxx | 33 +- src/Select3D/Select3D_SensitivePoint.cdl | 104 -- src/Select3D/Select3D_SensitivePoint.cxx | 168 +-- src/Select3D/Select3D_SensitivePoint.hxx | 74 + src/Select3D/Select3D_SensitivePoly.cdl | 86 -- src/Select3D/Select3D_SensitivePoly.cxx | 313 +++- src/Select3D/Select3D_SensitivePoly.hxx | 125 ++ src/Select3D/Select3D_SensitivePoly.lxx | 25 +- src/Select3D/Select3D_SensitiveSegment.cdl | 162 -- src/Select3D/Select3D_SensitiveSegment.cxx | 270 +--- src/Select3D/Select3D_SensitiveSegment.hxx | 91 ++ src/Select3D/Select3D_SensitiveSegment.lxx | 48 +- src/Select3D/Select3D_SensitiveSet.cxx | 178 +++ src/Select3D/Select3D_SensitiveSet.hxx | 114 ++ src/Select3D/Select3D_SensitiveTriangle.cdl | 118 -- src/Select3D/Select3D_SensitiveTriangle.cxx | 420 +----- src/Select3D/Select3D_SensitiveTriangle.hxx | 86 ++ .../Select3D_SensitiveTriangulation.cdl | 201 --- .../Select3D_SensitiveTriangulation.cxx | 911 ++++------- .../Select3D_SensitiveTriangulation.hxx | 154 ++ .../Select3D_SensitiveTriangulation.lxx | 36 +- src/Select3D/Select3D_SensitiveWire.cdl | 124 -- src/Select3D/Select3D_SensitiveWire.cxx | 342 ++--- src/Select3D/Select3D_SensitiveWire.hxx | 105 ++ src/Select3D/Select3D_TypeOfSensitivity.hxx | 15 + src/SelectBasics/FILES | 3 +- src/SelectBasics/SelectBasics.cdl | 34 +- src/SelectBasics/SelectBasics_BasicTool.cdl | 59 - src/SelectBasics/SelectBasics_BasicTool.cxx | 151 -- src/SelectBasics/SelectBasics_EntityOwner.cxx | 5 - src/SelectBasics/SelectBasics_PickArgs.hxx | 75 - src/SelectBasics/SelectBasics_PickResult.hxx | 55 + .../SelectBasics_SelectingVolumeManager.hxx | 89 ++ .../SelectBasics_SensitiveEntity.cdl | 151 +- .../SelectBasics_SensitiveEntity.cxx | 42 +- .../SelectBasics_SensitiveEntity.lxx | 22 +- src/SelectBasics/SelectBasics_SortAlgo.cdl | 89 -- src/SelectBasics/SelectBasics_SortAlgo.cxx | 116 -- src/SelectMgr/FILES | 28 + src/SelectMgr/SelectMgr.cdl | 47 +- src/SelectMgr/SelectMgr_BaseFrustum.cxx | 191 +++ src/SelectMgr/SelectMgr_BaseFrustum.hxx | 143 ++ src/SelectMgr/SelectMgr_EntityOwner.cxx | 7 +- src/SelectMgr/SelectMgr_Frustum.hxx | 114 ++ src/SelectMgr/SelectMgr_Frustum.lxx | 501 ++++++ src/SelectMgr/SelectMgr_FrustumBuilder.cxx | 221 +++ src/SelectMgr/SelectMgr_FrustumBuilder.hxx | 92 ++ .../SelectMgr_RectangularFrustum.cxx | 792 ++++++++++ .../SelectMgr_RectangularFrustum.hxx | 114 ++ src/SelectMgr/SelectMgr_SelectableObject.cdl | 99 +- src/SelectMgr/SelectMgr_SelectableObject.cxx | 214 ++- .../SelectMgr_SelectableObjectSet.cxx | 141 ++ .../SelectMgr_SelectableObjectSet.hxx | 72 + .../SelectMgr_SelectingVolumeManager.cxx | 312 ++++ .../SelectMgr_SelectingVolumeManager.hxx | 133 ++ src/SelectMgr/SelectMgr_Selection.cdl | 151 -- src/SelectMgr/SelectMgr_Selection.cxx | 102 +- src/SelectMgr/SelectMgr_Selection.hxx | 161 ++ src/SelectMgr/SelectMgr_Selection.lxx | 83 +- src/SelectMgr/SelectMgr_SelectionManager.cdl | 370 ++--- src/SelectMgr/SelectMgr_SelectionManager.cxx | 1336 ++++++++-------- src/SelectMgr/SelectMgr_SensitiveEntity.cxx | 74 + src/SelectMgr/SelectMgr_SensitiveEntity.hxx | 55 + .../SelectMgr_SensitiveEntitySet.cxx | 181 +++ .../SelectMgr_SensitiveEntitySet.hxx | 78 + .../SelectMgr_SequenceOfSelection.hxx} | 16 +- src/SelectMgr/SelectMgr_TriangularFrustum.cxx | 341 +++++ src/SelectMgr/SelectMgr_TriangularFrustum.hxx | 85 ++ .../SelectMgr_TriangularFrustumSet.cxx | 222 +++ .../SelectMgr_TriangularFrustumSet.hxx | 81 + src/SelectMgr/SelectMgr_VectorTypes.hxx | 33 + src/SelectMgr/SelectMgr_ViewerSelector.cdl | 445 ------ src/SelectMgr/SelectMgr_ViewerSelector.cxx | 1338 +++++++---------- src/SelectMgr/SelectMgr_ViewerSelector.hxx | 292 ++++ src/SelectMgr/SelectMgr_ViewerSelector.lxx | 18 +- src/StdSelect/FILES | 3 + src/StdSelect/StdSelect.cdl | 22 +- src/StdSelect/StdSelect.cxx | 25 +- src/StdSelect/StdSelect_BRepSelectionTool.cdl | 32 +- src/StdSelect/StdSelect_BRepSelectionTool.cxx | 49 +- src/StdSelect/StdSelect_ViewerSelector3d.cdl | 199 --- src/StdSelect/StdSelect_ViewerSelector3d.cxx | 733 ++------- src/StdSelect/StdSelect_ViewerSelector3d.hxx | 112 ++ src/StdSelect/StdSelect_ViewerSelector3d.lxx | 14 +- src/ViewerTest/ViewerTest.cxx | 264 ++-- src/ViewerTest/ViewerTest_ObjectCommands.cxx | 23 +- .../ViewerTest_RelationCommands.cxx | 3 - src/Voxel/Voxel_Prs.cdl | 2 +- tests/bugs/modalg_2/bug22781_2 | 4 +- tests/bugs/modalg_2/bug22781_4 | 2 +- tests/bugs/vis/bug23012 | 3 +- tests/bugs/vis/bug23539_2 | 4 +- tests/bugs/vis/bug23649_3 | 6 +- tests/bugs/vis/bug23649_4 | 6 +- tests/bugs/vis/bug24389 | 2 +- tests/bugs/vis/bug24564 | 2 +- tests/bugs/vis/bug24569 | 1 + tests/bugs/vis/bug24623_1 | 95 ++ tests/bugs/vis/bug24623_2 | 74 + tests/bugs/vis/bug24623_3 | 51 + tests/bugs/vis/bug24623_4 | 43 + tests/bugs/vis/bug25098 | 65 +- tests/bugs/vis/bug25532 | 1 + tests/bugs/vis/bug25552 | 2 +- tests/bugs/vis/bug25723 | 2 +- tests/bugs/vis/bug25935 | 1 - tests/v3d/edge_face/E2 | 2 +- tests/v3d/edge_face/E9 | 4 +- tests/v3d/edge_face/J4 | 2 +- tests/v3d/edge_face/K2 | 4 +- tests/v3d/edge_face/O6 | 2 +- tests/v3d/edge_face/P4 | 4 +- tests/v3d/edge_solid/E2 | 2 +- tests/v3d/edge_solid/E9 | 4 +- tests/v3d/edge_solid/J4 | 2 +- tests/v3d/edge_solid/K2 | 4 +- tests/v3d/edge_solid/O6 | 2 +- tests/v3d/edge_solid/P4 | 4 +- tests/v3d/vertex_edge/E7 | 2 +- tests/v3d/vertex_edge/F1 | 4 +- tests/v3d/vertex_edge/J9 | 2 +- tests/v3d/vertex_edge/K1 | 2 +- tests/v3d/vertex_edge/K3 | 4 +- tests/v3d/vertex_face/E7 | 2 +- tests/v3d/vertex_face/F1 | 2 +- tests/v3d/vertex_face/J9 | 2 +- tests/v3d/vertex_face/K1 | 2 +- tests/v3d/vertex_face/K3 | 4 +- tests/v3d/vertex_solid/E7 | 2 +- tests/v3d/vertex_solid/F1 | 4 +- tests/v3d/vertex_solid/J9 | 2 +- tests/v3d/vertex_solid/K3 | 4 +- tests/v3d/vertex_wire/E7 | 2 +- tests/v3d/vertex_wire/F1 | 2 +- tests/v3d/vertex_wire/J9 | 2 +- tests/v3d/vertex_wire/K3 | 4 +- tests/v3d/wire/E9 | 2 +- tests/v3d/wire/F1 | 2 +- tests/v3d/wire/F2 | 2 +- tests/v3d/wire_solid/E2 | 2 +- tests/v3d/wire_solid/E7 | 4 +- tests/v3d/wire_solid/F1 | 6 +- tests/v3d/wire_solid/J4 | 2 +- tests/v3d/wire_solid/J9 | 4 +- tests/v3d/wire_solid/K3 | 4 +- 269 files changed, 12626 insertions(+), 11723 deletions(-) delete mode 100755 samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.cpp delete mode 100755 samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.h delete mode 100644 src/MeshVS/MeshVS_DummySensitiveEntity.cdl create mode 100644 src/MeshVS/MeshVS_DummySensitiveEntity.hxx delete mode 100644 src/MeshVS/MeshVS_SensitiveFace.cdl create mode 100644 src/MeshVS/MeshVS_SensitiveFace.hxx delete mode 100644 src/MeshVS/MeshVS_SensitiveMesh.cdl create mode 100644 src/MeshVS/MeshVS_SensitiveMesh.hxx delete mode 100644 src/MeshVS/MeshVS_SensitivePolyhedron.cdl create mode 100644 src/MeshVS/MeshVS_SensitivePolyhedron.hxx delete mode 100644 src/MeshVS/MeshVS_SensitiveSegment.cdl create mode 100644 src/MeshVS/MeshVS_SensitiveSegment.hxx create mode 100644 src/Select3D/Select3D_BVHPrimitiveContent.cxx create mode 100644 src/Select3D/Select3D_BVHPrimitiveContent.hxx rename src/Select3D/{Select3D_SensitiveBox.lxx => Select3D_BndBox3d.hxx} (58%) create mode 100644 src/Select3D/Select3D_BoundarySensitivePointSet.cxx create mode 100644 src/Select3D/Select3D_BoundarySensitivePointSet.hxx delete mode 100644 src/Select3D/Select3D_Box2d.hxx create mode 100644 src/Select3D/Select3D_EntitySequence.hxx create mode 100644 src/Select3D/Select3D_ISensitivePointSet.hxx create mode 100644 src/Select3D/Select3D_InteriorSensitivePointSet.cxx create mode 100644 src/Select3D/Select3D_InteriorSensitivePointSet.hxx delete mode 100644 src/Select3D/Select3D_Pnt2d.hxx delete mode 100644 src/Select3D/Select3D_Projector.cdl delete mode 100644 src/Select3D/Select3D_Projector.cxx delete mode 100644 src/Select3D/Select3D_Projector.lxx delete mode 100644 src/Select3D/Select3D_SensitiveBox.cdl create mode 100644 src/Select3D/Select3D_SensitiveBox.hxx delete mode 100644 src/Select3D/Select3D_SensitiveCircle.cdl create mode 100644 src/Select3D/Select3D_SensitiveCircle.hxx delete mode 100644 src/Select3D/Select3D_SensitiveCurve.cdl create mode 100644 src/Select3D/Select3D_SensitiveCurve.hxx delete mode 100644 src/Select3D/Select3D_SensitiveCurve.lxx delete mode 100644 src/Select3D/Select3D_SensitiveEntity.cdl create mode 100644 src/Select3D/Select3D_SensitiveEntity.hxx delete mode 100644 src/Select3D/Select3D_SensitiveFace.cdl create mode 100644 src/Select3D/Select3D_SensitiveFace.hxx delete mode 100644 src/Select3D/Select3D_SensitiveGroup.cdl create mode 100644 src/Select3D/Select3D_SensitiveGroup.hxx delete mode 100644 src/Select3D/Select3D_SensitivePoint.cdl create mode 100644 src/Select3D/Select3D_SensitivePoint.hxx delete mode 100644 src/Select3D/Select3D_SensitivePoly.cdl create mode 100644 src/Select3D/Select3D_SensitivePoly.hxx delete mode 100644 src/Select3D/Select3D_SensitiveSegment.cdl create mode 100644 src/Select3D/Select3D_SensitiveSegment.hxx create mode 100644 src/Select3D/Select3D_SensitiveSet.cxx create mode 100644 src/Select3D/Select3D_SensitiveSet.hxx delete mode 100644 src/Select3D/Select3D_SensitiveTriangle.cdl create mode 100644 src/Select3D/Select3D_SensitiveTriangle.hxx delete mode 100644 src/Select3D/Select3D_SensitiveTriangulation.cdl create mode 100644 src/Select3D/Select3D_SensitiveTriangulation.hxx delete mode 100644 src/Select3D/Select3D_SensitiveWire.cdl create mode 100644 src/Select3D/Select3D_SensitiveWire.hxx create mode 100644 src/Select3D/Select3D_TypeOfSensitivity.hxx delete mode 100644 src/SelectBasics/SelectBasics_BasicTool.cdl delete mode 100644 src/SelectBasics/SelectBasics_BasicTool.cxx delete mode 100755 src/SelectBasics/SelectBasics_PickArgs.hxx create mode 100644 src/SelectBasics/SelectBasics_PickResult.hxx create mode 100644 src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx delete mode 100644 src/SelectBasics/SelectBasics_SortAlgo.cdl delete mode 100644 src/SelectBasics/SelectBasics_SortAlgo.cxx create mode 100644 src/SelectMgr/SelectMgr_BaseFrustum.cxx create mode 100644 src/SelectMgr/SelectMgr_BaseFrustum.hxx create mode 100644 src/SelectMgr/SelectMgr_Frustum.hxx create mode 100644 src/SelectMgr/SelectMgr_Frustum.lxx create mode 100644 src/SelectMgr/SelectMgr_FrustumBuilder.cxx create mode 100644 src/SelectMgr/SelectMgr_FrustumBuilder.hxx create mode 100644 src/SelectMgr/SelectMgr_RectangularFrustum.cxx create mode 100644 src/SelectMgr/SelectMgr_RectangularFrustum.hxx create mode 100644 src/SelectMgr/SelectMgr_SelectableObjectSet.cxx create mode 100644 src/SelectMgr/SelectMgr_SelectableObjectSet.hxx create mode 100644 src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx create mode 100644 src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx delete mode 100644 src/SelectMgr/SelectMgr_Selection.cdl create mode 100644 src/SelectMgr/SelectMgr_Selection.hxx create mode 100644 src/SelectMgr/SelectMgr_SensitiveEntity.cxx create mode 100644 src/SelectMgr/SelectMgr_SensitiveEntity.hxx create mode 100644 src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx create mode 100644 src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx rename src/{Select3D/Select3D_SensitiveEntity.lxx => SelectMgr/SelectMgr_SequenceOfSelection.hxx} (58%) create mode 100644 src/SelectMgr/SelectMgr_TriangularFrustum.cxx create mode 100644 src/SelectMgr/SelectMgr_TriangularFrustum.hxx create mode 100644 src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx create mode 100644 src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx create mode 100644 src/SelectMgr/SelectMgr_VectorTypes.hxx delete mode 100644 src/SelectMgr/SelectMgr_ViewerSelector.cdl create mode 100644 src/SelectMgr/SelectMgr_ViewerSelector.hxx create mode 100644 src/StdSelect/FILES delete mode 100644 src/StdSelect/StdSelect_ViewerSelector3d.cdl create mode 100644 src/StdSelect/StdSelect_ViewerSelector3d.hxx create mode 100644 tests/bugs/vis/bug24623_1 create mode 100644 tests/bugs/vis/bug24623_2 create mode 100644 tests/bugs/vis/bug24623_3 create mode 100644 tests/bugs/vis/bug24623_4 diff --git a/samples/mfc/standard/01_Geometry/CMakeLists.txt b/samples/mfc/standard/01_Geometry/CMakeLists.txt index fbe3267a41..051970a4c5 100644 --- a/samples/mfc/standard/01_Geometry/CMakeLists.txt +++ b/samples/mfc/standard/01_Geometry/CMakeLists.txt @@ -33,15 +33,13 @@ set (Geometry_ISESSION2D_HEADER_FILES ${Geometry_ISESSION2D_DIR}/ISession_Curve. ${Geometry_ISESSION2D_DIR}/ISession_Point.h ${Geometry_ISESSION2D_DIR}/ISession_Surface.h ${Geometry_ISESSION2D_DIR}/ISession_Text.h - ${Geometry_ISESSION2D_DIR}/ISession2D_Curve.h - ${Geometry_ISESSION2D_DIR}/ISession2D_SensitiveCurve.h) + ${Geometry_ISESSION2D_DIR}/ISession2D_Curve.h) set (Geometry_ISESSION2D_SOURCE_FILES ${Geometry_ISESSION2D_DIR}/ISession_Curve.cpp ${Geometry_ISESSION2D_DIR}/ISession_Direction.cpp ${Geometry_ISESSION2D_DIR}/ISession_Point.cpp ${Geometry_ISESSION2D_DIR}/ISession_Surface.cpp ${Geometry_ISESSION2D_DIR}/ISession_Text.cpp - ${Geometry_ISESSION2D_DIR}/ISession2D_Curve.cpp - ${Geometry_ISESSION2D_DIR}/ISession2D_SensitiveCurve.cpp) + ${Geometry_ISESSION2D_DIR}/ISession2D_Curve.cpp) set (Geometry_RESOURCE_DIR ${MFC_STANDARD_SAMPLES_DIR}/01_Geometry/res) set (Geometry_RESOURCE_HEADER ${Geometry_RESOURCE_DIR}/resource.h) diff --git a/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj b/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj index 7788b35a2d..512ec89b7d 100644 --- a/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj +++ b/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj @@ -457,24 +457,6 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - true - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - true - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - Disabled %(AdditionalIncludeDirectories) @@ -588,7 +570,6 @@ - diff --git a/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj.filters b/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj.filters index 812b3b1160..185f27ebaa 100644 --- a/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj.filters +++ b/samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj.filters @@ -54,9 +54,6 @@ Source Files\ISession2d - - Source Files\ISession2d - Source Files\ISession2d @@ -106,9 +103,6 @@ Header Files - - Header Files - Header Files diff --git a/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.cpp b/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.cpp deleted file mode 100755 index 01a5c843ae..0000000000 --- a/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright: Matra-Datavision 1995 - -#include "stdafx.h" - -#include -#include -#include - -IMPLEMENT_STANDARD_HANDLE(ISession2D_SensitiveCurve,Select3D_SensitiveEntity) -IMPLEMENT_STANDARD_RTTIEXT(ISession2D_SensitiveCurve,Select3D_SensitiveEntity) - -//===================================================== -// Function : Create -// Purpose :Constructor -//===================================================== - - -ISession2D_SensitiveCurve:: -ISession2D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Geom2d_Curve)& C, - const Standard_Real CDeflect, - const Standard_Integer MaxRect): -Select3D_SensitiveEntity(OwnerId), -myMaxRect(MaxRect), -myCurve(C), -myCDeflect(CDeflect) -{ - Compute(); -} - -void ISession2D_SensitiveCurve::Compute() -{ - Geom2dAdaptor_Curve Curve (myCurve); - Standard_Real ADeflect = 180; //Angular deflection - - GCPnts_TangentialDeflection PointsOnCurve; - PointsOnCurve.Initialize (Curve, ADeflect, myCDeflect,myMaxRect,1.0e-9); - - - myPolyP2d = new TColgp_HArray1OfPnt2d(1,PointsOnCurve.NbPoints()); - - gp_Pnt P; - for (Standard_Integer i=1; i<=PointsOnCurve.NbPoints();i++) { - P = PointsOnCurve.Value (i); - myPolyP2d->SetValue(i,gp_Pnt2d(P.X(),P.Y())); - } - -} - - -//===================================================== -// Function : Areas -// Purpose : return the bounding boxes -//===================================================== -void ISession2D_SensitiveCurve::Areas(SelectBasics_ListOfBox2d& boxes) -{ - // calcul des Areas --> le nombre voulu est myMaxRect - // mais il y a myPolyP2d->Length() segments - - Standard_Integer NbSeg = myPolyP2d->Length()-1; - Standard_Integer nbPerBoxes= NbSeg/myMaxRect; - - Standard_Integer CurrentPoint =1; - for (Standard_Integer i=1;i<=myMaxRect-1;i++) - { - Bnd_Box2d abox; - abox.Set(myPolyP2d->Value(CurrentPoint)); - for(Standard_Integer j=1;j<=nbPerBoxes;j++) - { - CurrentPoint++; - abox.Add(myPolyP2d->Value(CurrentPoint)); - } - boxes.Append(abox); - } - Bnd_Box2d abox; - abox.Set(myPolyP2d->Value(CurrentPoint)); - for(Standard_Integer j=CurrentPoint;j<=myPolyP2d->Length()-1;j++) - { - CurrentPoint++; - abox.Add(myPolyP2d->Value(CurrentPoint)); - } - boxes.Append(abox); - -} - -//======================================================= -// Function : Matches -// Purpose : test : segments in the bounding boxe -//======================================================= -Standard_Boolean ISession2D_SensitiveCurve:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - - Bnd_Box2d BoundBox; - BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol); - - for(Standard_Integer j=1;j<=myPolyP2d->Length()-1;j++) - { - if(BoundBox.IsOut(myPolyP2d->Value(j))) return Standard_False; - } - return Standard_True; - -} - -//==================================================== -// Function : Matches -// Purpose : test the real dist to the segments -//==================================================== -Standard_Boolean ISession2D_SensitiveCurve:: - Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) -{ - // VERY VERY IMPORTANT : set the selector sensibility !!! ( it's aTol !! ) - Standard_Integer Rank=0; // New in 2.0 - if (aTol == 0) {TRACE0("VERY VERY IMPORTANT : set the selector sensibility !!! ( it's aTol !! )");} - - Standard_Boolean Result = SelectBasics_BasicTool::MatchPolyg2d(myPolyP2d->Array1(), - X,Y, - aTol, - DMin, - Rank); // new in 2.0 - return Result; -} - - -Handle(TColgp_HArray1OfPnt2d) ISession2D_SensitiveCurve:: -SensitivePolygon() -{ - return myPolyP2d; -} - - diff --git a/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.h b/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.h deleted file mode 100755 index 6daa3b4501..0000000000 --- a/samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.h +++ /dev/null @@ -1,86 +0,0 @@ -// File generated by CPPExt (Transient) -// -// Copyright (C) 1991,1995 by -// -// MATRA DATAVISION, FRANCE -// -// This software is furnished in accordance with the terms and conditions -// of the contract and with the inclusion of the above copyright notice. -// This software or any other copy thereof may not be provided or otherwise -// be made available to any other person. No title to an ownership of the -// software is hereby transferred. -// -// At the termination of the contract, the software and all copies of this -// software must be deleted. -// -#ifndef _ISession2D_SensitiveCurve_HeaderFile -#define _ISession2D_SensitiveCurve_HeaderFile -#include -#include - - -#include -#include -#include -#include -#include -#include -class SelectBasics_EntityOwner; -class gp_Pnt2d; -#include -#include "TColgp_HArray1OfPnt2d.hxx" -#include - - -DEFINE_STANDARD_HANDLE(ISession2D_SensitiveCurve,Select3D_SensitiveEntity) -class ISession2D_SensitiveCurve : public Select3D_SensitiveEntity { - -public: - - // Methods PUBLIC - // - Standard_EXPORT ISession2D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Geom2d_Curve)& C, - const Standard_Real CDeflect, - const Standard_Integer MaxRect = 3); - inline void SetMaxBoxes(const Standard_Integer MaxRect) ; - inline virtual Standard_Integer MaxBoxes() const; - - inline void SetCurve(const Handle(Geom2d_Curve) aCurve) ; - inline Handle(Geom2d_Curve) GetCurve() ; - - void Compute(); - - Standard_EXPORT void Areas(SelectBasics_ListOfBox2d& aSeq) ; - Standard_EXPORT Standard_Boolean Matches(const Standard_Real XMin,const Standard_Real YMin,const Standard_Real XMax,const Standard_Real YMax,const Standard_Real aTol) ; - Standard_EXPORT Standard_Boolean Matches(const Standard_Real X,const Standard_Real Y,const Standard_Real aTol,Standard_Real& DMin) ; - Handle(TColgp_HArray1OfPnt2d) SensitivePolygon(); - - DEFINE_STANDARD_RTTI(ISession2D_SensitiveCurve) - -private: - // Fields PRIVATE - // -Standard_Real myCDeflect; -Standard_Integer myMaxRect; -Handle(Geom2d_Curve) myCurve; -Handle(TColgp_HArray1OfPnt2d) myPolyP2d; - -}; - -inline Standard_Integer ISession2D_SensitiveCurve:: -MaxBoxes() const {return myMaxRect;} - -inline void ISession2D_SensitiveCurve:: -SetMaxBoxes(const Standard_Integer nbrect) -{myMaxRect = nbrect;} - -inline void ISession2D_SensitiveCurve:: -SetCurve(const Handle(Geom2d_Curve) aCurve) -{myCurve = aCurve;} - -inline Handle(Geom2d_Curve) ISession2D_SensitiveCurve:: -GetCurve() -{return myCurve;} - -#endif diff --git a/samples/mfc/standard/01_Geometry/src/StdAfx.h b/samples/mfc/standard/01_Geometry/src/StdAfx.h index 0a91b8fd85..50c8ddd55f 100755 --- a/samples/mfc/standard/01_Geometry/src/StdAfx.h +++ b/samples/mfc/standard/01_Geometry/src/StdAfx.h @@ -229,7 +229,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/mfc/standard/03_Viewer2d/src/StdAfx.h b/samples/mfc/standard/03_Viewer2d/src/StdAfx.h index 257f72db8c..25e3a10bd3 100755 --- a/samples/mfc/standard/03_Viewer2d/src/StdAfx.h +++ b/samples/mfc/standard/03_Viewer2d/src/StdAfx.h @@ -127,8 +127,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp b/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp index 1a019cf29f..785de91a18 100755 --- a/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp +++ b/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp @@ -846,10 +846,10 @@ void CViewer3dView::DrawRectangle(const Standard_Integer MinX , m_IsVisible = false; } - StoredMinX = min ( MinX, MaxX ); - StoredMinY = min ( MinY, MaxY ); - StoredMaxX = max ( MinX, MaxX ); - StoredMaxY = max ( MinY, MaxY); + StoredMinX = Min ( MinX, MaxX ); + StoredMinY = Min ( MinY, MaxY ); + StoredMaxX = Max ( MinX, MaxX ); + StoredMaxY = Max ( MinY, MaxY); if (Draw) // move : draw { diff --git a/samples/mfc/standard/05_ImportExport/src/StdAfx.h b/samples/mfc/standard/05_ImportExport/src/StdAfx.h index debe0e2210..7eee7acf55 100755 --- a/samples/mfc/standard/05_ImportExport/src/StdAfx.h +++ b/samples/mfc/standard/05_ImportExport/src/StdAfx.h @@ -99,8 +99,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/samples/mfc/standard/06_Ocaf/src/StdAfx.h b/samples/mfc/standard/06_Ocaf/src/StdAfx.h index 89edb6e681..6b2e5a3792 100755 --- a/samples/mfc/standard/06_Ocaf/src/StdAfx.h +++ b/samples/mfc/standard/06_Ocaf/src/StdAfx.h @@ -96,8 +96,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/samples/mfc/standard/08_HLR/src/StdAfx.h b/samples/mfc/standard/08_HLR/src/StdAfx.h index 540aa5a53c..32c76a5af4 100755 --- a/samples/mfc/standard/08_HLR/src/StdAfx.h +++ b/samples/mfc/standard/08_HLR/src/StdAfx.h @@ -153,8 +153,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/samples/mfc/standard/09_Animation/src/AnimationView3D.cpp b/samples/mfc/standard/09_Animation/src/AnimationView3D.cpp index 09f8aec6c6..ec6d921628 100755 --- a/samples/mfc/standard/09_Animation/src/AnimationView3D.cpp +++ b/samples/mfc/standard/09_Animation/src/AnimationView3D.cpp @@ -680,10 +680,10 @@ void CAnimationView3D::DrawRectangle(const Standard_Integer MinX , m_IsVisible = false; } - StoredMinX = min ( MinX, MaxX ); - StoredMinY = min ( MinY, MaxY ); - StoredMaxX = max ( MinX, MaxX ); - StoredMaxY = max ( MinY, MaxY); + StoredMinX = Min ( MinX, MaxX ); + StoredMinY = Min ( MinY, MaxY ); + StoredMaxX = Max ( MinX, MaxX ); + StoredMaxY = Max ( MinY, MaxY); if (Draw) // move : draw { diff --git a/samples/mfc/standard/09_Animation/src/StdAfx.h b/samples/mfc/standard/09_Animation/src/StdAfx.h index 4e70e4c70f..a2a7663e4b 100755 --- a/samples/mfc/standard/09_Animation/src/StdAfx.h +++ b/samples/mfc/standard/09_Animation/src/StdAfx.h @@ -164,8 +164,6 @@ enum CurrentAction3d { #include #include #include -#include -#include #include #include #include diff --git a/samples/mfc/standard/10_Convert/src/WNT/OCCDemoView.cpp b/samples/mfc/standard/10_Convert/src/WNT/OCCDemoView.cpp index 3cd62d5915..cd2c43c792 100755 --- a/samples/mfc/standard/10_Convert/src/WNT/OCCDemoView.cpp +++ b/samples/mfc/standard/10_Convert/src/WNT/OCCDemoView.cpp @@ -450,10 +450,10 @@ void COCCDemoView::DrawRectangle(const Standard_Integer MinX, m_IsVisible = false; } - StoredMinX = min ( MinX, MaxX ); - StoredMinY = min ( MinY, MaxY ); - StoredMaxX = max ( MinX, MaxX ); - StoredMaxY = max ( MinY, MaxY); + StoredMinX = Min ( MinX, MaxX ); + StoredMinY = Min ( MinY, MaxY ); + StoredMaxX = Max ( MinX, MaxX ); + StoredMaxY = Max ( MinY, MaxY); if (Draw) // move : draw { diff --git a/samples/mfc/standard/Common/OCC_2dView.cpp b/samples/mfc/standard/Common/OCC_2dView.cpp index 439c7e08b9..8209ab828d 100755 --- a/samples/mfc/standard/Common/OCC_2dView.cpp +++ b/samples/mfc/standard/Common/OCC_2dView.cpp @@ -594,10 +594,10 @@ void OCC_2dView::DrawRectangle2D(const Standard_Integer MinX, m_IsVisible = false; } - StoredMinX = min ( MinX, MaxX ); - StoredMinY = min ( MinY, MaxY ); - StoredMaxX = max ( MinX, MaxX ); - StoredMaxY = max ( MinY, MaxY); + StoredMinX = Min ( MinX, MaxX ); + StoredMinY = Min ( MinY, MaxY ); + StoredMaxX = Max ( MinX, MaxX ); + StoredMaxY = Max ( MinY, MaxY); if (Draw) // move : draw { diff --git a/samples/mfc/standard/Common/OCC_3dView.cpp b/samples/mfc/standard/Common/OCC_3dView.cpp index a8e1093bfc..3f4a8821b8 100755 --- a/samples/mfc/standard/Common/OCC_3dView.cpp +++ b/samples/mfc/standard/Common/OCC_3dView.cpp @@ -542,10 +542,10 @@ void OCC_3dView::DrawRectangle(const Standard_Integer MinX , m_IsVisible = false; } - StoredMinX = min ( MinX, MaxX ); - StoredMinY = min ( MinY, MaxY ); - StoredMaxX = max ( MinX, MaxX ); - StoredMaxY = max ( MinY, MaxY); + StoredMinX = Min ( MinX, MaxX ); + StoredMinY = Min ( MinY, MaxY ); + StoredMaxX = Max ( MinX, MaxX ); + StoredMaxY = Max ( MinY, MaxY); if (Draw) // move : draw { diff --git a/samples/mfc/standard/Common/StdAfx.h b/samples/mfc/standard/Common/StdAfx.h index 2415a82ceb..122108e25e 100755 --- a/samples/mfc/standard/Common/StdAfx.h +++ b/samples/mfc/standard/Common/StdAfx.h @@ -83,7 +83,6 @@ #include #include -#include #include #include #include diff --git a/src/AIS/AIS_Axis.cxx b/src/AIS/AIS_Axis.cxx index 9202253743..f7ad1d1149 100644 --- a/src/AIS/AIS_Axis.cxx +++ b/src/AIS/AIS_Axis.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AIS/AIS_Chamf2dDimension.cxx b/src/AIS/AIS_Chamf2dDimension.cxx index 4a36258f11..878843a471 100644 --- a/src/AIS/AIS_Chamf2dDimension.cxx +++ b/src/AIS/AIS_Chamf2dDimension.cxx @@ -25,6 +25,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_Chamf3dDimension.cxx b/src/AIS/AIS_Chamf3dDimension.cxx index 0405edcdf5..3d7d183d19 100644 --- a/src/AIS/AIS_Chamf3dDimension.cxx +++ b/src/AIS/AIS_Chamf3dDimension.cxx @@ -25,6 +25,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_Circle.cxx b/src/AIS/AIS_Circle.cxx index f7c4ac3ca4..e2dae1d21b 100644 --- a/src/AIS/AIS_Circle.cxx +++ b/src/AIS/AIS_Circle.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AIS/AIS_ConcentricRelation.cxx b/src/AIS/AIS_ConcentricRelation.cxx index 9fb1036b24..f209345691 100644 --- a/src/AIS/AIS_ConcentricRelation.cxx +++ b/src/AIS/AIS_ConcentricRelation.cxx @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_ConnectedInteractive.cxx b/src/AIS/AIS_ConnectedInteractive.cxx index 9a4fef784f..79e1228970 100644 --- a/src/AIS/AIS_ConnectedInteractive.cxx +++ b/src/AIS/AIS_ConnectedInteractive.cxx @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -287,31 +288,30 @@ void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selectio if (!myReference->HasSelection (theMode)) { - myReference->UpdateSelection (theMode); + myReference->RecomputePrimitives (theMode); } const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode); Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this); Handle(Select3D_SensitiveEntity) aSensitive, aNewSensitive; - + + TopLoc_Location aLocation (Transformation()); + anOwner->SetLocation (aLocation); + if (TheRefSel->IsEmpty()) { - myReference->UpdateSelection (theMode); + myReference->RecomputePrimitives (theMode); } for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next()) { - aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive()); + aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive()->BaseSensitive()); if (!aSensitive.IsNull()) { - TopLoc_Location aLocation (Transformation()); // Get the copy of SE3D - aNewSensitive = aSensitive->GetConnected (aLocation); + aNewSensitive = aSensitive->GetConnected(); aNewSensitive->Set(anOwner); - // In case if SE3D caches some location-dependent data - // that must be updated after setting OWN - aNewSensitive->SetLocation (aLocation); theSelection->Add (aNewSensitive); } @@ -330,13 +330,13 @@ void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_ Shapes2EntitiesMap; if (!myReference->HasSelection (theMode)) - myReference->UpdateSelection (theMode); + myReference->RecomputePrimitives (theMode); const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode); if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full) { - myReference->UpdateSelection (theMode); + myReference->RecomputePrimitives (theMode); } Handle(StdSelect_BRepOwner) anOwner; @@ -352,7 +352,7 @@ void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_ // sensitive entities associated with aMode for (aRefSel->Init(); aRefSel->More(); aRefSel->Next()) { - aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()); + aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()->BaseSensitive()); if(!aSE.IsNull()) { anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId()); @@ -376,17 +376,14 @@ void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_ this, aSEList.First()->OwnerId()->Priority(), Standard_True); + anOwner->SetLocation (Transformation()); for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next()) - { + { aSE = aListIt.Value(); - TopLoc_Location aLocation (Transformation()); - aNewSE = aSE->GetConnected (aDummyLoc); + aNewSE = aSE->GetConnected(); aNewSE->Set (anOwner); - // In case if aSE caches some location-dependent data - // that must be updated after setting anOwner - aNewSE->SetLocation (aLocation); theSelection->Add (aNewSE); } diff --git a/src/AIS/AIS_Dimension.cxx b/src/AIS/AIS_Dimension.cxx index 34cf02bbb2..a09e1a1da2 100755 --- a/src/AIS/AIS_Dimension.cxx +++ b/src/AIS/AIS_Dimension.cxx @@ -50,8 +50,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/AIS/AIS_Dimension.hxx b/src/AIS/AIS_Dimension.hxx index 03ad7d01b1..6992339ff9 100755 --- a/src/AIS/AIS_Dimension.hxx +++ b/src/AIS/AIS_Dimension.hxx @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/src/AIS/AIS_EqualRadiusRelation.cxx b/src/AIS/AIS_EqualRadiusRelation.cxx index ff6e431237..553cd05929 100644 --- a/src/AIS/AIS_EqualRadiusRelation.cxx +++ b/src/AIS/AIS_EqualRadiusRelation.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AIS/AIS_FixRelation.cxx b/src/AIS/AIS_FixRelation.cxx index 57d1236dec..f9ae72a042 100644 --- a/src/AIS/AIS_FixRelation.cxx +++ b/src/AIS/AIS_FixRelation.cxx @@ -23,6 +23,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_IdenticRelation.cxx b/src/AIS/AIS_IdenticRelation.cxx index 9947d35c4c..6031f37205 100644 --- a/src/AIS/AIS_IdenticRelation.cxx +++ b/src/AIS/AIS_IdenticRelation.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include diff --git a/src/AIS/AIS_InteractiveContext.cdl b/src/AIS/AIS_InteractiveContext.cdl index 6398d8cb1f..2270226d10 100644 --- a/src/AIS/AIS_InteractiveContext.cdl +++ b/src/AIS/AIS_InteractiveContext.cdl @@ -427,43 +427,16 @@ is ---Purpose: -- Removes selection mode from Interactive Objects. -- aMode provides the selection mode index of the entity aniobj. - - SetSensitivityMode(me : mutable; - aMode : SensitivityMode from StdSelect) is static; - ---Level: Public - ---Purpose: Sets the selection sensitivity mode. SM_WINDOW mode - -- uses the specified pixel tolerance to compute the sensitivity - -- value, SM_VIEW mode allows to define the sensitivity manually. - - SensitivityMode(me) returns SensitivityMode from StdSelect; - ---Level: Public - ---Purpose: Returns the selection sensitivity mode. - - SetSensitivity(me:mutable; - aPrecision: Real from Standard); - ---Level: Public - ---Purpose: Sets the sensitivity aPrecision --- according to the view size for the current context or local --- context if any is activated. --- Sets the sensitivity aPrecision in pixels for the current context --- or local context if any is activated. By default, this --- sensitivity is equal to 4 pixels. --- When a local context is open, the defined sensitivity applies to --- this local context instead of the main context. - - Sensitivity (me) returns Real from Standard; - ---Level: Public - ---Purpose: Returns the selection sensitivity value. SetPixelTolerance(me:mutable; - aPrecision: Integer from Standard = 4); + aPrecision: Real from Standard = 4.0); ---Level: Public ---Purpose: Define the current selection pixel sensitivity -- for this context or local context if any one is activated. -- Warning: When a local context is open the sensitivity is apply on it -- instead on the main context. - PixelTolerance(me) returns Integer from Standard; + PixelTolerance(me) returns Real from Standard; ---Level: Public ---Purpose: Returns the pixel tolerance. @@ -1668,9 +1641,10 @@ is ZDetection(me) returns Boolean; ---Purpose: Retrieves the Z detection state. - Activate(me : mutable; - anIobj : InteractiveObject from AIS; - aMode : Integer from Standard = 0); + Activate(me : mutable; + anIobj : InteractiveObject from AIS; + aMode : Integer from Standard = 0; + theIsForce : Boolean from Standard = Standard_False); ---Purpose: Activates the selection mode aMode whose index is -- given, for the given interactive entity anIobj. @@ -1947,10 +1921,10 @@ is ---C++: inline ---C++: return const & - MainSelector(me) returns any ViewerSelector3d from StdSelect; + MainSelector(me) returns ViewerSelector3d from StdSelect; ---C++: inline ---C++: return const & - LocalSelector(me) returns any ViewerSelector3d from StdSelect; + LocalSelector(me) returns ViewerSelector3d from StdSelect; PurgeDisplay(me:mutable) returns Integer from Standard; @@ -1962,12 +1936,6 @@ is HighestIndex(me) returns Integer from Standard; - - DisplayActiveAreas(me:mutable;aView:View from V3d) ; - - ClearActiveAreas (me :mutable; - aView: View from V3d) is static; - ---Level: Internal DisplayActiveSensitive(me:mutable;aView : View from V3d) is static; @@ -1978,9 +1946,6 @@ is DisplayActiveSensitive(me:mutable; anObject: InteractiveObject from AIS; aView : View from V3d) is static; - DisplayActiveAreas(me:mutable; - anObject: InteractiveObject from AIS; - aView : View from V3d) is static; GetDefModes(me; anIobj : InteractiveObject from AIS; @@ -2010,6 +1975,8 @@ is ---Purpose: returns if possible, -- the first local context where the object is seen + RebuildSelectionStructs (me : mutable); + ---Purpose: Rebuilds 1st level of BVH selection forcibly SetViewAffinity (me : mutable; theIObj : InteractiveObject from AIS; theView : View from V3d; @@ -2017,6 +1984,12 @@ is ---Purpose: setup object visibility in specified view, -- has no effect if object is not disaplyed in this context. + Disconnect (me : mutable; + theAssembly : InteractiveObject from AIS; + theObjToDisconnect : InteractiveObject from AIS = NULL) + is static; + ---Purpose: Disconnects theObjToDisconnect from theAssembly and removes dependent selection structures + ObjectsForView (me; theListOfIO : in out ListOfInteractive from AIS; theView : View from V3d; diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index ffe89cfd72..3c3d400254 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -2364,6 +2365,9 @@ void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& t if (theIObj.IsNull() || !myObjects.IsBound (theIObj)) { + // for cases when reference shape of connected interactives was not displayed + // but its selection primitives were calculated + mgrSelector->Remove (theIObj); return; } @@ -2584,65 +2588,11 @@ void AIS_InteractiveContext::UnsetSelectionMode (const Handle(AIS_InteractiveObj // } -//======================================================================= -//function : SetSensitivityMode -//purpose : -//======================================================================= -void AIS_InteractiveContext::SetSensitivityMode (const StdSelect_SensitivityMode theMode) -{ - if (HasOpenedContext()) - { - myLocalContexts (myCurLocalIndex)->SetSensitivityMode (theMode); - } - else - { - myMainSel->SetSensitivityMode (theMode); - } -} - -//======================================================================= -//function : SensitivityMode -//purpose : -//======================================================================= -StdSelect_SensitivityMode AIS_InteractiveContext::SensitivityMode() const -{ - return HasOpenedContext() - ? myLocalContexts (myCurLocalIndex)->SensitivityMode() - : myMainSel->SensitivityMode(); -} - -//======================================================================= -//function : SetSensitivity -//purpose : -//======================================================================= -void AIS_InteractiveContext::SetSensitivity (const Standard_Real thePrecision) -{ - if (HasOpenedContext()) - { - myLocalContexts(myCurLocalIndex)->SetSensitivity (thePrecision); - } - else - { - myMainSel->SetSensitivity (thePrecision); - } -} - -//======================================================================= -//function : Sensitivity -//purpose : -//======================================================================= -Standard_Real AIS_InteractiveContext::Sensitivity() const -{ - return HasOpenedContext() - ? myLocalContexts(myCurLocalIndex)->Sensitivity() - : myMainSel->Sensitivity(); -} - //======================================================================= //function : SetPixelTolerance //purpose : //======================================================================= -void AIS_InteractiveContext::SetPixelTolerance (const Standard_Integer thePrecision) +void AIS_InteractiveContext::SetPixelTolerance (const Standard_Real thePrecision) { if (HasOpenedContext()) { @@ -2658,7 +2608,7 @@ void AIS_InteractiveContext::SetPixelTolerance (const Standard_Integer thePrecis //function : PixelTolerance //purpose : //======================================================================= -Standard_Integer AIS_InteractiveContext::PixelTolerance() const +Standard_Real AIS_InteractiveContext::PixelTolerance() const { return HasOpenedContext() ? myLocalContexts (myCurLocalIndex)->PixelTolerance() @@ -2836,3 +2786,37 @@ Standard_Integer AIS_InteractiveContext::GetZLayer (const Handle(AIS_Interactive ? theIObj->ZLayer() : Graphic3d_ZLayerId_UNKNOWN; } + +//======================================================================= +//function : RebuildSelectionStructs +//purpose : Rebuilds 1st level of BVH selection forcibly +//======================================================================= +void AIS_InteractiveContext::RebuildSelectionStructs() +{ + myMainSel->RebuildObjectsTree (Standard_True); +} + +//======================================================================= +//function : Disconnect +//purpose : Disconnects selectable object from an assembly and updates selection structures +//======================================================================= +void AIS_InteractiveContext::Disconnect (const Handle(AIS_InteractiveObject)& theAssembly, + const Handle(AIS_InteractiveObject)& theObjToDisconnect) +{ + if (theAssembly->IsInstance ("AIS_MultipleConnectedInteractive")) + { + const Handle(AIS_MultipleConnectedInteractive)& theObj = + Handle(AIS_MultipleConnectedInteractive)::DownCast (theAssembly); + theObj->Disconnect (theObjToDisconnect); + mgrSelector->Remove (theObjToDisconnect); + } + else if (theAssembly->IsInstance ("AIS_ConnectedInteractive") && theObjToDisconnect == NULL) + { + const Handle(AIS_ConnectedInteractive)& theObj = + Handle(AIS_ConnectedInteractive)::DownCast (theAssembly); + theObj->Disconnect(); + mgrSelector->Remove (theObj); + } + else + return; +} diff --git a/src/AIS/AIS_InteractiveContext_1.cxx b/src/AIS/AIS_InteractiveContext_1.cxx index b8423a9acd..d82f767c21 100644 --- a/src/AIS/AIS_InteractiveContext_1.cxx +++ b/src/AIS/AIS_InteractiveContext_1.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -1098,11 +1099,11 @@ void AIS_InteractiveContext::EntityOwners(SelectMgr_IndexedMapOfOwner& theOwners if ( !theIObj->HasSelection( aMode ) ) continue; - Handle(SelectMgr_Selection) aSel = theIObj->Selection( aMode ); + Handle(SelectMgr_Selection) aSel = theIObj->Selection(aMode); for ( aSel->Init(); aSel->More(); aSel->Next() ) { - Handle(SelectBasics_SensitiveEntity) aEntity = aSel->Sensitive(); + Handle(SelectBasics_SensitiveEntity) aEntity = aSel->Sensitive()->BaseSensitive(); if ( aEntity.IsNull() ) continue; diff --git a/src/AIS/AIS_InteractiveContext_2.cxx b/src/AIS/AIS_InteractiveContext_2.cxx index 10c9c5ff62..0fef9640fa 100644 --- a/src/AIS/AIS_InteractiveContext_2.cxx +++ b/src/AIS/AIS_InteractiveContext_2.cxx @@ -29,6 +29,8 @@ #include #include +#include + //======================================================================= //function : OpenLocalContext //purpose : @@ -59,10 +61,6 @@ OpenLocalContext(const Standard_Boolean UseDisplayedObjects, myLastPicked.Nullify(); myWasLastMain = Standard_True; - - - Standard_Integer untilnow = myCurLocalIndex; - myCurLocalIndex = HighestIndex() + 1; Handle(AIS_LocalContext) NewLocal= new AIS_LocalContext(this,myCurLocalIndex, @@ -72,12 +70,6 @@ OpenLocalContext(const Standard_Boolean UseDisplayedObjects, // the AIS_LocalContext bind itself to myLocalContexts // because procedures performed in AIS_LocalContext constructor // already may access myLocalContexts(myCurLocalIndex) (like methods AIS_LocalContext::IsSelected()). - //myLocalContexts.Bind (myCurLocalIndex, NewLocal); - NewLocal->MainSelector()->Set ((myLocalContexts.Extent() > 1) - ? myLocalContexts (untilnow)->MainSelector()->Projector() - : myMainSel->Projector()); - - NewLocal->MainSelector()->UpdateConversion(); #ifdef OCCT_DEBUG cout<<"\tOpen Local Context No "<HasSameProjector(myMainSel->Projector())); myLocalContexts(myCurLocalIndex)->Terminate( updateviewer ); myLocalContexts.UnBind(myCurLocalIndex); myCurLocalIndex = 0; ResetOriginalState(Standard_False); - if(updateproj) - myMainSel->UpdateConversion(); - else{ - myMainSel->UpdateSort(); - } if(debugmode) cout<<"No More Opened Local Context "<HasSameProjector (VS->Projector())) - { - LocCtx->MainSelector()->UpdateConversion(); - } } else if(debugmode) cout<<"a No Current Local Context WasClosed"<UpdateSort(); if(updateviewer) myMainVwr->Update(); } @@ -226,12 +206,13 @@ Standard_Integer AIS_InteractiveContext::HighestIndex() const void AIS_InteractiveContext:: Activate(const Handle(AIS_InteractiveObject)& anIObj, - const Standard_Integer aMode) + const Standard_Integer aMode, + const Standard_Boolean theIsForce) { if(!HasOpenedContext()){ if(!myObjects.IsBound(anIObj)) return; const Handle(AIS_GlobalStatus)& STAT = myObjects(anIObj); - if(STAT->GraphicStatus()==AIS_DS_Displayed) + if(STAT->GraphicStatus()==AIS_DS_Displayed || theIsForce) mgrSelector->Activate(anIObj,aMode,myMainSel); STAT ->AddSelectionMode(aMode); } @@ -570,31 +551,6 @@ const SelectMgr_ListOfFilter& AIS_InteractiveContext::Filters() const return myFilters->StoredFilters(); } -//======================================================================= -//function : DisplayActiveAreas -//purpose : -//======================================================================= -void AIS_InteractiveContext::DisplayActiveAreas(const Handle(V3d_View)& aviou) -{ - if(HasOpenedContext()) - myLocalContexts(myCurLocalIndex)->DisplayAreas(aviou); - else - myMainSel->DisplayAreas(aviou); - -} - -//======================================================================= -//function : ClearActiveAreas -//purpose : -//======================================================================= -void AIS_InteractiveContext::ClearActiveAreas(const Handle(V3d_View)& aviou) -{ - if(HasOpenedContext()) - myLocalContexts(myCurLocalIndex)->ClearAreas(aviou); - else - myMainSel->ClearAreas(aviou); -} - //======================================================================= //function : DisplayActiveSensitive //purpose : @@ -631,41 +587,11 @@ void AIS_InteractiveContext::DisplayActiveSensitive(const Handle(AIS_Interactive for(;It.More();It.Next()){ const Handle(SelectMgr_Selection)& Sel = anIObj->Selection(It.Value()); - VS->DisplaySensitive(Sel,aviou,Standard_False); + VS->DisplaySensitive(Sel,anIObj->Transformation(), aviou,Standard_False); } } -//======================================================================= -//function : DisplayActiveAreas -//purpose : -//======================================================================= - -void AIS_InteractiveContext::DisplayActiveAreas(const Handle(AIS_InteractiveObject)& anIObj, - const Handle(V3d_View)& aviou) -{ - TColStd_ListIteratorOfListOfInteger It; - Handle(StdSelect_ViewerSelector3d) VS; - if(HasOpenedContext()){ - const Handle(AIS_LocalContext)& LC = myLocalContexts(myCurLocalIndex); - if(!LC->IsIn(anIObj)) return; - It.Initialize(LC->SelectionModes(anIObj)); - VS = LC->MainSelector(); - } - else{ - if(!myObjects.IsBound(anIObj)) return; - It.Initialize(myObjects(anIObj)->SelectionModes()); - VS = myMainSel; - } - - - for(;It.More();It.Next()){ - const Handle(SelectMgr_Selection)& Sel = anIObj->Selection(It.Value()); - VS->DisplayAreas(Sel,aviou,Standard_False); - } - -} - //======================================================================= //function : ClearActiveSensitive //purpose : @@ -848,6 +774,7 @@ void AIS_InteractiveContext::ResetOriginalState(const Standard_Boolean updatevie { Standard_Boolean upd_main(Standard_False); TColStd_ListIteratorOfListOfInteger itl; + myMainSel->ResetSelectionActivationStatus(); for (AIS_DataMapIteratorOfDataMapOfIOStatus it(myObjects);it.More();it.Next()){ const Handle(AIS_InteractiveObject)& iobj = it.Key(); diff --git a/src/AIS/AIS_InteractiveObject.cdl b/src/AIS/AIS_InteractiveObject.cdl index 5134ed6e1a..601a008340 100644 --- a/src/AIS/AIS_InteractiveObject.cdl +++ b/src/AIS/AIS_InteractiveObject.cdl @@ -581,6 +581,12 @@ is ---Purpose: Retrieves current polygon offsets settings from . ---Category: Inquire methods + BoundingBox (me : mutable; + theBndBox : out Box from Bnd) + is redefined; + ---Level: Public + ---Purpose: Returns bounding box of object correspondingly to its current display mode. + fields myCTXPtr : PToContext from AIS; diff --git a/src/AIS/AIS_InteractiveObject.cxx b/src/AIS/AIS_InteractiveObject.cxx index 639c75c434..0256b6ec47 100644 --- a/src/AIS/AIS_InteractiveObject.cxx +++ b/src/AIS/AIS_InteractiveObject.cxx @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -586,3 +588,62 @@ void AIS_InteractiveObject::PolygonOffsets(Standard_Integer& aMode, if( HasPolygonOffsets() ) myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits ); } + +//======================================================================= +//function : BoundingBox +//purpose : Returns bounding box of object correspondingly to its +// current display mode +//======================================================================= +void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox) +{ + if (myDisplayMode == -1) + { + if (!myPresentations.IsEmpty()) + { + const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations.First().Presentation(); + const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation(); + const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox(); + theBndBox.Update (static_cast (aBndBox.CornerMin().x()), + static_cast (aBndBox.CornerMin().y()), + static_cast (aBndBox.CornerMin().z()), + static_cast (aBndBox.CornerMax().x()), + static_cast (aBndBox.CornerMax().y()), + static_cast (aBndBox.CornerMax().z())); + return; + } + else + { + for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (Children()); aPrsIter.More(); aPrsIter.Next()) + { + const Handle(AIS_InteractiveObject)& aChild = Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()); + if (aChild.IsNull()) + { + continue; + } + Bnd_Box aBox; + aChild->BoundingBox (aBox); + theBndBox.Add (aBox); + } + return; + } + } + else + { + for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter) + { + if (myPresentations (aPrsIter).Mode() == myDisplayMode) + { + const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation(); + const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation(); + const Graphic3d_BndBox4f& aBndBox = aStruct->CStructure()->BoundingBox(); + theBndBox.Update (static_cast (aBndBox.CornerMin().x()), + static_cast (aBndBox.CornerMin().y()), + static_cast (aBndBox.CornerMin().z()), + static_cast (aBndBox.CornerMax().x()), + static_cast (aBndBox.CornerMax().y()), + static_cast (aBndBox.CornerMax().z())); + return; + } + } + } +} diff --git a/src/AIS/AIS_Line.cxx b/src/AIS/AIS_Line.cxx index 08e5a03907..8cc19f814c 100644 --- a/src/AIS/AIS_Line.cxx +++ b/src/AIS/AIS_Line.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AIS/AIS_LocalContext.cdl b/src/AIS/AIS_LocalContext.cdl index 2177f65c09..5a9b10424f 100644 --- a/src/AIS/AIS_LocalContext.cdl +++ b/src/AIS/AIS_LocalContext.cdl @@ -51,7 +51,6 @@ uses Shape from TopoDS, View from V3d, PresentationManager3d from PrsMgr, - Projector from Select3D, IndexedMapOfOwner from SelectMgr, EntityOwner from SelectMgr, OrFilter from SelectMgr, @@ -105,14 +104,6 @@ is Terminate(me: mutable; updateviewer : Boolean from Standard = Standard_True); - HasSameProjector(me;aPrj:Projector from Select3D) - returns Boolean from Standard; - ---Purpose: compares the current projector of the localContext - -- with - -- returns True if the projectors are identical. - -- (no need to update projection of selection primitives - -- when closing the local context).... - Reactivate(me:mutable); ---Purpose: to be called when a upper local context was closed... -- useful to put pack the right projector... @@ -445,35 +436,14 @@ is WithColor : out Boolean from Standard; HiCol : out NameOfColor from Quantity) returns Boolean from Standard; - - SetSensitivityMode(me : mutable; - aMode : SensitivityMode from StdSelect) is static; - ---Level: Public - ---Purpose: Sets the selection sensitivity mode. SM_WINDOW mode - -- uses the specified pixel tolerance to compute the sensitivity - -- value, SM_VIEW mode allows to define the sensitivity manually. - - SensitivityMode(me) returns SensitivityMode from StdSelect; - ---Level: Public - ---Purpose: Returns the selection sensitivity mode. - - SetSensitivity(me:mutable; - aPrecision: Real from Standard); - ---Level: Public - ---Purpose: Define the current selection sensitivity for - -- this local context according to the view size. - - Sensitivity (me) returns Real from Standard; - ---Level: Public - ---Purpose: Returns the selection sensitivity value. SetPixelTolerance(me:mutable; - aPrecision: Integer from Standard = 2); + aPrecision: Real from Standard = 2); ---Level: Public ---Purpose: Define the current selection sensitivity for -- this local context according to the view size. - PixelTolerance(me) returns Integer from Standard; + PixelTolerance(me) returns Real from Standard; ---Level: Public ---Purpose: Returns the pixel tolerance. @@ -505,11 +475,6 @@ is ---Category: INTERNAL METHODS; - UpdateConversion(me:mutable); - - UpdateSort(me:mutable); - - Status(me) returns AsciiString from TCollection is private; @@ -524,15 +489,12 @@ is UnloadContextObjects(me:mutable); Process(me : mutable; - anObject : SelectableObject from SelectMgr; - WithProj: Boolean from Standard = Standard_True) is static private; + anObject : SelectableObject from SelectMgr) is static private; - Process(me:mutable; - WithProj: Boolean from Standard = Standard_True) is static private; + Process(me:mutable) is static private; - ActivateStandardModes(me:mutable;anObject: SelectableObject from SelectMgr; - WithProj: Boolean from Standard = Standard_True) is static private; + ActivateStandardModes(me:mutable;anObject: SelectableObject from SelectMgr) is static private; manageDetected (me : mutable; thePickOwner : EntityOwner from SelectMgr; @@ -566,13 +528,6 @@ is ComesFromDecomposition(me; aPickedIndex : Integer from Standard) returns Boolean from Standard is static private; - - DisplayAreas(me:mutable;aviou:View from V3d); - - ClearAreas (me:mutable; - aView: View from V3d) is static; - ---Level: Internal - HasFilters(me;aType:ShapeEnum from TopAbs) returns Boolean from Standard is private; @@ -580,7 +535,7 @@ is ClearSensitive(me:mutable;aView:View from V3d) is static; - MainSelector(me) returns any ViewerSelector3d from StdSelect; + MainSelector(me) returns ViewerSelector3d from StdSelect; ---C++: inline ---C++: return const& diff --git a/src/AIS/AIS_LocalContext.cxx b/src/AIS/AIS_LocalContext.cxx index c62f8467bb..6549e9a388 100644 --- a/src/AIS/AIS_LocalContext.cxx +++ b/src/AIS/AIS_LocalContext.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ myLoadDisplayed(LoadDisplayed), myAcceptStdMode(AcceptStandardModes), myAcceptErase(AcceptEraseOfTemp), mySM(aCtx->SelectionManager()), -myMainVS(new StdSelect_ViewerSelector3d(aCtx->MainSelector()->Projector())), +myMainVS(aCtx->MainSelector()), myFilters(new SelectMgr_OrFilter()), myAutoHilight(Standard_True), mylastindex(0), @@ -84,13 +85,14 @@ myAISCurDetected(0) // created and mapped. aCtx->myLocalContexts.Bind (Index, this); + myMainVS->ResetSelectionActivationStatus(); myMainPM = aCtx->MainPrsMgr(); mySelName = AIS_Local_SelName(this, Index); AIS_Selection::CreateSelection(mySelName.ToCString()); mySM->Add(myMainVS); if(myLoadDisplayed) LoadContextObjects(); - Process(Standard_False); + Process(); } @@ -195,7 +197,24 @@ Load(const Handle(AIS_InteractiveObject)& anInteractive, const Standard_Boolean AllowShapeDecomposition, const Standard_Integer ActivationMode) { - if(myActiveObjects.IsBound(anInteractive)) return Standard_False; + if (myActiveObjects.IsBound (anInteractive)) + { + if (anInteractive->HasSelection (ActivationMode)) + { + const Handle(SelectMgr_Selection)& aSel = anInteractive->Selection (ActivationMode); + if (aSel->GetSelectionState() != SelectMgr_SOS_Activated) + { + if (!myMainVS->Contains (anInteractive)) + { + mySM->Load (anInteractive, myMainVS); + } + mySM->Activate (anInteractive, ActivationMode, myMainVS); + return Standard_True; + } + } + return Standard_False; + } + Handle(AIS_LocalStatus) Att = new AIS_LocalStatus(); if(anInteractive->AcceptShapeDecomposition() && AllowShapeDecomposition) @@ -296,8 +315,6 @@ Erase(const Handle(AIS_InteractiveObject)& anInteractive) } } - UpdateSort(); - ClearOutdatedSelection (anInteractive, Standard_True); return status; @@ -353,7 +370,6 @@ void AIS_LocalContext::Clear(const AIS_ClearMode aType) case AIS_CM_TemporaryShapePrs: ClearDetected(); } - UpdateSort(); } //======================================================================= //function : ActivateMode @@ -370,7 +386,6 @@ void AIS_LocalContext::ActivateMode(const Handle(AIS_InteractiveObject)& aSelect myActiveObjects(aSelectable)->AddSelectionMode(aMode); mySM->Activate(aSelectable,aMode,myMainVS); } - UpdateSort(); } //======================================================================= //function : ActivateMode @@ -386,8 +401,6 @@ void AIS_LocalContext::DeactivateMode(const Handle(AIS_InteractiveObject)& aSele myActiveObjects(aSelectable)->RemoveSelectionMode(aMode); mySM->Deactivate(aSelectable,aMode,myMainVS); - UpdateSort(); - } //======================================================================= //function : ActivateMode @@ -398,9 +411,8 @@ void AIS_LocalContext::Deactivate(const Handle(AIS_InteractiveObject)& aSelectab { if(!myActiveObjects.IsBound(aSelectable)) return; - mySM->Deactivate(aSelectable,myMainVS); + mySM->Deactivate(aSelectable, -1, myMainVS); myActiveObjects(aSelectable)->ClearSelectionModes(); - UpdateSort(); } //======================================================================= @@ -465,7 +477,6 @@ Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& a { mySM->Remove (aSelectable); } - UpdateSort(); ClearOutdatedSelection (aSelectable, Standard_True); // This should be done at the very end because most methods use @@ -538,10 +549,8 @@ void AIS_LocalContext::DeactivateStandardMode(const TopAbs_ShapeEnum aType) myListOfStandardMode.Remove(It); if(myFilters->IsIn(myStdFilters[IMode])) myFilters->Remove(myStdFilters[IMode]); - UpdateSort(); return; } - UpdateSort(); } //======================================================================= @@ -588,31 +597,6 @@ void AIS_LocalContext::RemoveFilter(const Handle(SelectMgr_Filter)& aFilter) } } - - -Standard_Boolean AIS_LocalContext::HasSameProjector(const Handle(Select3D_Projector)& thePrj) const -{ - const Handle(Select3D_Projector)& aCurPrj = myMainVS->Projector(); - if (aCurPrj->Perspective() != thePrj->Perspective()) - return Standard_False; - if (aCurPrj->Perspective() && aCurPrj->Focus() != thePrj->Focus()) - return Standard_False; - const gp_GTrsf& aCurTrsf = aCurPrj->Transformation(); - const gp_GTrsf& aPrjTrsf = thePrj->Transformation(); - - for (Standard_Integer i = 1; i <= 3; ++i) - { - for (Standard_Integer j = 1; j <= 3 ; ++j) - { - if (aCurTrsf.Value (i, j) != aPrjTrsf.Value (i, j)) - return Standard_False; - } - } - - return Standard_True; -} - - //======================================================================= //function : Terminate //purpose : @@ -627,7 +611,6 @@ void AIS_LocalContext::Terminate (const Standard_Boolean theToUpdate) mylastindex=0; // clear the selector... myMainVS->Clear(); - myCTX->SelectionManager()->Remove(myMainVS); AIS_Selection::SetCurrentSelection(mySelName.ToCString()); @@ -650,7 +633,6 @@ void AIS_LocalContext::Terminate (const Standard_Boolean theToUpdate) } Handle(V3d_View) aDummyView; - myMainVS->ClearAreas (aDummyView); myMainVS->ClearSensitive (aDummyView); if (theToUpdate) @@ -893,12 +875,17 @@ void AIS_LocalContext::LoadContextObjects() myCTX->DisplayedObjects(LL,Standard_True); Handle(AIS_LocalStatus) Att; for (It.Initialize(LL);It.More();It.Next()){ + const Handle(AIS_InteractiveObject)& anObj = It.Value(); Att= new AIS_LocalStatus(); - Att->SetDecomposition((It.Value()->AcceptShapeDecomposition() && myAcceptStdMode)); + Att->SetDecomposition((anObj->AcceptShapeDecomposition() && myAcceptStdMode)); Att->SetTemporary(Standard_False); - Att->SetHilightMode(It.Value()->HasHilightMode()? It.Value()->HilightMode(): 0); - - myActiveObjects.Bind(It.Value(),Att); + Att->SetHilightMode(anObj->HasHilightMode()? anObj->HilightMode(): 0); + for (anObj->Init(); anObj->More(); anObj->Next()) + { + const Handle(SelectMgr_Selection)& aSel = anObj->CurrentSelection(); + aSel->SetSelectionState (SelectMgr_SOS_Deactivated); + } + myActiveObjects.Bind(anObj,Att); } } } @@ -922,17 +909,16 @@ void AIS_LocalContext::UnloadContextObjects() //purpose : //======================================================================= -void AIS_LocalContext::Process(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Boolean WithProj) +void AIS_LocalContext::Process(const Handle(SelectMgr_SelectableObject)& anObject) { if(!myActiveObjects.IsBound(anObject)) return; if(myActiveObjects(anObject)->Decomposed()) - ActivateStandardModes(anObject,WithProj); + ActivateStandardModes(anObject); else { TColStd_ListIteratorOfListOfInteger It(myActiveObjects(anObject)->SelectionModes()); for(;It.More();It.Next()) - myCTX->SelectionManager()->Activate(anObject,It.Value(),myMainVS,WithProj); + myCTX->SelectionManager()->Activate(anObject,It.Value(),myMainVS); } } @@ -941,7 +927,7 @@ void AIS_LocalContext::Process(const Handle(SelectMgr_SelectableObject)& anObjec //purpose : //======================================================================= -void AIS_LocalContext::Process(const Standard_Boolean WithProj) +void AIS_LocalContext::Process() { myMainVS->Clear(); @@ -951,11 +937,11 @@ void AIS_LocalContext::Process(const Standard_Boolean WithProj) for(;It.More();It.Next()){ myCTX->SelectionManager()->Load(It.Key(),myMainVS); if(It.Value()->Decomposed()) - ActivateStandardModes(It.Key(),WithProj); + ActivateStandardModes(It.Key()); else if( myCTX->GetAutoActivateSelection() ) { It.Value()->AddSelectionMode(0); - myCTX->SelectionManager()->Activate(It.Key(),0,myMainVS,WithProj); + myCTX->SelectionManager()->Activate(It.Key(),0,myMainVS); } } @@ -966,8 +952,7 @@ void AIS_LocalContext::Process(const Standard_Boolean WithProj) //purpose : //======================================================================= -void AIS_LocalContext::ActivateStandardModes(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Boolean WithProj) +void AIS_LocalContext::ActivateStandardModes(const Handle(SelectMgr_SelectableObject)& anObject) { if(!myActiveObjects.IsBound(anObject)) return; @@ -976,7 +961,7 @@ void AIS_LocalContext::ActivateStandardModes(const Handle(SelectMgr_SelectableOb const Handle(AIS_LocalStatus)& LS = myActiveObjects(anObject); if(LS->Decomposed()){ for(;itl.More();itl.Next()){ - myCTX->SelectionManager()->Activate(anObject,itl.Value(),myMainVS,WithProj); + myCTX->SelectionManager()->Activate(anObject,itl.Value(),myMainVS); LS->AddSelectionMode(itl.Value()); } } @@ -1023,13 +1008,13 @@ void AIS_LocalContext::ClearObjects() myMainPM->Erase(SO,CurAtt->DisplayMode()); } - TColStd_ListIteratorOfListOfInteger ITL(CurAtt->SelectionModes()); - for(;ITL.More();ITL.Next()) - mySM->Deactivate(SO,ITL.Value(),myMainVS); - - if(CurAtt->IsTemporary()) - mySM->Remove(SO,myMainVS); - + TColStd_ListIteratorOfListOfInteger aSelModeIter (CurAtt->SelectionModes()); + for ( ; aSelModeIter.More(); aSelModeIter.Next()) + { + Standard_Integer aSelMode = aSelModeIter.Value(); + mySM->Deactivate (SO, aSelMode, myMainVS); + } + } ClearSelected( Standard_False ); myActiveObjects.Clear(); @@ -1082,16 +1067,6 @@ void AIS_LocalContext::ClearDetected() } } -void AIS_LocalContext::UpdateConversion() -{ - myMainVS->UpdateConversion(); -} - -void AIS_LocalContext::UpdateSort() -{ - myMainVS->UpdateSort(); -} - //======================================================================= //function : BeginImmediateDraw //purpose : @@ -1155,32 +1130,12 @@ Standard_Boolean AIS_LocalContext::IsImmediateModeOn() const return myMainPM->IsImmediateModeOn(); } -void AIS_LocalContext::SetSensitivityMode(const StdSelect_SensitivityMode aMode) { - - myMainVS->SetSensitivityMode(aMode); -} - -StdSelect_SensitivityMode AIS_LocalContext::SensitivityMode() const { - - return myMainVS->SensitivityMode(); -} - -void AIS_LocalContext::SetSensitivity(const Standard_Real aPrecision) { - - myMainVS->SetSensitivity(aPrecision); -} - -Standard_Real AIS_LocalContext::Sensitivity() const { - - return myMainVS->Sensitivity(); -} - -void AIS_LocalContext::SetPixelTolerance(const Standard_Integer aPrecision) { +void AIS_LocalContext::SetPixelTolerance(const Standard_Real aPrecision) { myMainVS->SetPixelTolerance(aPrecision); } -Standard_Integer AIS_LocalContext::PixelTolerance() const { +Standard_Real AIS_LocalContext::PixelTolerance() const { return myMainVS->PixelTolerance(); } diff --git a/src/AIS/AIS_LocalContext_1.cxx b/src/AIS/AIS_LocalContext_1.cxx index cbf86d849e..c5a9217bcf 100644 --- a/src/AIS/AIS_LocalContext_1.cxx +++ b/src/AIS/AIS_LocalContext_1.cxx @@ -31,12 +31,12 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -855,7 +855,7 @@ void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObjec continue; } - if (toClearDeactivated && !mySM->IsActivated (theIO, myMainVS, aMode)) + if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS)) { continue; } @@ -863,7 +863,7 @@ void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObjec Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode); for (aSelection->Init(); aSelection->More(); aSelection->Next()) { - Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive(); + Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive(); if (anEntity.IsNull()) { continue; @@ -1012,7 +1012,7 @@ void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj, const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0); SIOBJ->Init(); if(SIOBJ->More()){ - Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId(); + Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId(); EO = *((Handle(SelectMgr_EntityOwner)*)&BO); } } @@ -1049,10 +1049,9 @@ void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& { const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0); SIOBJ->Init(); - if(SIOBJ->More()) - { - Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId(); - EO = *((Handle(SelectMgr_EntityOwner)*)&BO); + if(SIOBJ->More()){ + Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId(); + EO = *((Handle(SelectMgr_EntityOwner)*)&BO); } } if(EO.IsNull()) @@ -1272,27 +1271,6 @@ Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer return Standard_False; } - -//======================================================================= -//function : DisplayAreas -//purpose : -//======================================================================= - -void AIS_LocalContext::DisplayAreas(const Handle(V3d_View)& aviou) -{ - myMainVS->DisplayAreas(aviou); -} - -//======================================================================= -//function : ClearAreas -//purpose : -//======================================================================= - -void AIS_LocalContext::ClearAreas(const Handle(V3d_View)& aviou) -{ - myMainVS->ClearAreas(aviou); -} - //======================================================================= //function : DisplaySensitive //purpose : @@ -1475,9 +1453,9 @@ Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const Standard_Boolean found(Standard_False); if (!found) { - SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive aSensitiveIt (myMainVS->Primitives()); - for (; aSensitiveIt.More(); aSensitiveIt.Next()) { - EO = Handle(SelectMgr_EntityOwner)::DownCast (aSensitiveIt.Value()->OwnerId()); + NCollection_List::Iterator anOwnersIt (myMainVS->ActiveOwners()); + for (; anOwnersIt.More(); anOwnersIt.Next()) { + EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value()); Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO); if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) { found = Standard_True; diff --git a/src/AIS/AIS_MaxRadiusDimension.cxx b/src/AIS/AIS_MaxRadiusDimension.cxx index 6ef3c3a205..695ec44660 100644 --- a/src/AIS/AIS_MaxRadiusDimension.cxx +++ b/src/AIS/AIS_MaxRadiusDimension.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/src/AIS/AIS_MidPointRelation.cxx b/src/AIS/AIS_MidPointRelation.cxx index 8ec70b4e01..f17c0cfad3 100644 --- a/src/AIS/AIS_MidPointRelation.cxx +++ b/src/AIS/AIS_MidPointRelation.cxx @@ -38,6 +38,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_MinRadiusDimension.cxx b/src/AIS/AIS_MinRadiusDimension.cxx index 39f8426cc3..861f2d0549 100644 --- a/src/AIS/AIS_MinRadiusDimension.cxx +++ b/src/AIS/AIS_MinRadiusDimension.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/src/AIS/AIS_MultipleConnectedInteractive.cxx b/src/AIS/AIS_MultipleConnectedInteractive.cxx index 4cde3df6d6..82ac598c1e 100644 --- a/src/AIS/AIS_MultipleConnectedInteractive.cxx +++ b/src/AIS/AIS_MultipleConnectedInteractive.cxx @@ -159,6 +159,7 @@ AIS_MultipleConnectedInteractive::AIS_MultipleConnectedInteractive() : AIS_InteractiveObject (PrsMgr_TOP_AllView) { myHasOwnPresentations = Standard_False; + myAssemblyOwner = NULL; SetHilightMode (0); } @@ -189,12 +190,16 @@ Handle(AIS_InteractiveObject) AIS_MultipleConnectedInteractive::Connect (const H const Graphic3d_TransModeFlags& theTrsfPersFlag, const gp_Pnt& theTrsfPersPoint) { + if (myAssemblyOwner.IsNull()) + myAssemblyOwner = new SelectMgr_EntityOwner (this); + Handle(AIS_InteractiveObject) anObjectToAdd; Handle(AIS_MultipleConnectedInteractive) aMultiConnected = Handle(AIS_MultipleConnectedInteractive)::DownCast (theAnotherObj); if (!aMultiConnected.IsNull()) { Handle(AIS_MultipleConnectedInteractive) aNewMultiConnected = new AIS_MultipleConnectedInteractive(); + aNewMultiConnected->myAssemblyOwner = myAssemblyOwner; aNewMultiConnected->SetLocalTransformation (aMultiConnected->LocalTransformation()); // Perform deep copy of instance tree @@ -357,7 +362,7 @@ Standard_Boolean AIS_MultipleConnectedInteractive::AcceptShapeDecomposition() co //function : ComputeSelection //purpose : //======================================================================= -void AIS_MultipleConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, +void AIS_MultipleConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& /*theSelection*/, const Standard_Integer theMode) { if (theMode != 0) @@ -370,67 +375,13 @@ void AIS_MultipleConnectedInteractive::ComputeSelection (const Handle(SelectMgr_ continue; } - if (!aChild->HasSelection(theMode)) + if (!aChild->HasSelection (theMode)) { - aChild->UpdateSelection(theMode); + aChild->RecomputePrimitives (theMode); } - aChild->ComputeSelection (theSelection, theMode); - } - - return; - } - - for (PrsMgr_ListOfPresentableObjectsIter anIter (Children()); anIter.More(); anIter.Next()) - { - Handle(AIS_InteractiveObject) aChild = Handle(AIS_InteractiveObject)::DownCast (anIter.Value()); - if (aChild.IsNull()) - { - continue; - } - - if (!aChild->HasSelection (theMode)) - { - aChild->UpdateSelection (theMode); - } - - const Handle(SelectMgr_Selection)& TheRefSel = aChild->Selection (theMode); - - // To redirect selection we must replace owners in sensitives, but we don't want new owner for each SE. - // Only for each existing owner. - NCollection_DataMap anOwnerMap; - - Handle(Select3D_SensitiveEntity) aSensitive, aNewSensitive; - - if (TheRefSel->IsEmpty()) - { - aChild->UpdateSelection(theMode); - } - - for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next()) - { - aSensitive = Handle(Select3D_SensitiveEntity)::DownCast(TheRefSel->Sensitive()); - - if (!aSensitive.IsNull()) - { - TopLoc_Location aLocation (Transformation()); - // Get the copy of aSensitive - aNewSensitive = aSensitive->GetConnected (aLocation); - Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aNewSensitive->OwnerId()); - - if (!anOwnerMap.IsBound (anOwner)) - { - Handle(SelectMgr_EntityOwner) aNewOwner = new SelectMgr_AssemblyEntityOwner (anOwner, this); - anOwnerMap.Bind (anOwner, aNewOwner); - } - - aNewSensitive->Set (anOwnerMap.Find (anOwner)); - // In case if aSensitive caches some location-dependent data - // that must be updated after setting OWN - aNewSensitive->SetLocation (aLocation); - - theSelection->Add (aNewSensitive); - } + Handle(SelectMgr_Selection) aSelection = new SelectMgr_Selection (theMode); + aChild->ComputeSelection (aSelection, theMode); } } } diff --git a/src/AIS/AIS_OffsetDimension.cxx b/src/AIS/AIS_OffsetDimension.cxx index a799327d71..376bf99a93 100644 --- a/src/AIS/AIS_OffsetDimension.cxx +++ b/src/AIS/AIS_OffsetDimension.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/src/AIS/AIS_ParallelRelation.cxx b/src/AIS/AIS_ParallelRelation.cxx index 7b47bb2f51..0a9fbe7fd0 100644 --- a/src/AIS/AIS_ParallelRelation.cxx +++ b/src/AIS/AIS_ParallelRelation.cxx @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_PerpendicularRelation.cxx b/src/AIS/AIS_PerpendicularRelation.cxx index 5ef137afc9..d964b2f147 100644 --- a/src/AIS/AIS_PerpendicularRelation.cxx +++ b/src/AIS/AIS_PerpendicularRelation.cxx @@ -41,6 +41,7 @@ #include #include +#include #include #include diff --git a/src/AIS/AIS_Plane.lxx b/src/AIS/AIS_Plane.lxx index 8d955d4afe..90df73229e 100644 --- a/src/AIS/AIS_Plane.lxx +++ b/src/AIS/AIS_Plane.lxx @@ -50,7 +50,7 @@ inline Select3D_TypeOfSensitivity AIS_Plane::TypeOfSensitivity() const return myTypeOfSensitivity; } -inline void AIS_Plane::SetTypeOfSensitivity (const Select3D_TypeOfSensitivity theTypeOfSensitivity) +inline void AIS_Plane::SetTypeOfSensitivity (const Select3D_TypeOfSensitivity& theTypeOfSensitivity) { myTypeOfSensitivity = theTypeOfSensitivity; } diff --git a/src/AIS/AIS_PlaneTrihedron.cxx b/src/AIS/AIS_PlaneTrihedron.cxx index dfc50e87e3..b9b57955f7 100644 --- a/src/AIS/AIS_PlaneTrihedron.cxx +++ b/src/AIS/AIS_PlaneTrihedron.cxx @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/src/AIS/AIS_SymmetricRelation.cxx b/src/AIS/AIS_SymmetricRelation.cxx index dc822b5e52..0f51dce1bb 100644 --- a/src/AIS/AIS_SymmetricRelation.cxx +++ b/src/AIS/AIS_SymmetricRelation.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/src/AIS/AIS_TangentRelation.cxx b/src/AIS/AIS_TangentRelation.cxx index a86fa6a512..e6565331aa 100644 --- a/src/AIS/AIS_TangentRelation.cxx +++ b/src/AIS/AIS_TangentRelation.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/src/BVH/BVH_BinnedBuilder.hxx b/src/BVH/BVH_BinnedBuilder.hxx index 06a32286f7..ee2c4474e1 100644 --- a/src/BVH/BVH_BinnedBuilder.hxx +++ b/src/BVH/BVH_BinnedBuilder.hxx @@ -45,7 +45,8 @@ public: //! Creates binned SAH BVH builder. BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize = 5, - const Standard_Integer theMaxTreeDepth = 32); + const Standard_Integer theMaxTreeDepth = 32, + const Standard_Boolean theToUseMainAxis = Standard_False); //! Releases resources of binned SAH BVH builder. virtual ~BVH_BinnedBuilder(); @@ -64,6 +65,10 @@ protected: BVH_BinVector& theBins, const Standard_Integer theAxis); +private: + + Standard_Boolean myUseMainAxis; //!< Defines whether to search for the best split or use the widest axis + }; #include diff --git a/src/BVH/BVH_BinnedBuilder.lxx b/src/BVH/BVH_BinnedBuilder.lxx index 7ad8c22e5f..9ab554b509 100644 --- a/src/BVH/BVH_BinnedBuilder.lxx +++ b/src/BVH/BVH_BinnedBuilder.lxx @@ -19,9 +19,11 @@ // ======================================================================= template BVH_BinnedBuilder::BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize, - const Standard_Integer theMaxTreeDepth) + const Standard_Integer theMaxTreeDepth, + const Standard_Boolean theToUseMainAxis) : BVH_QueueBuilder (theLeafNodeSize, - theMaxTreeDepth) + theMaxTreeDepth), + myUseMainAxis (theToUseMainAxis) { // } @@ -129,6 +131,46 @@ namespace BVH #include +namespace BVH +{ + template + struct BVH_AxisSelector + { + typedef typename BVH::VectorType::Type BVH_VecNt; + + // ======================================================================= + // function : MainAxis + // purpose : + // ======================================================================= + static Standard_Integer MainAxis (const BVH_VecNt& theSize) + { + if (theSize.y() > theSize.x()) + { + return theSize.y() > theSize.z() ? 1 : 2; + } + else + { + return theSize.z() > theSize.x() ? 2 : 0; + } + } + }; + + template + struct BVH_AxisSelector + { + typedef typename BVH::VectorType::Type BVH_VecNt; + + // ======================================================================= + // function : MainAxis + // purpose : + // ======================================================================= + static Standard_Integer MainAxis (const BVH_VecNt& theSize) + { + return theSize.x() > theSize.y() ? 0 : 1; + } + }; +} + // ======================================================================= // function : BuildNode // purpose : @@ -162,8 +204,10 @@ void BVH_BinnedBuilder::BuildNode (BVH_Set* theSet, Standard_Real aMinSplitCost = std::numeric_limits::max(); + Standard_Integer aMainAxis = BVH::BVH_AxisSelector::MainAxis (aSize); + // Find best split - for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis) + for (Standard_Integer anAxis = myUseMainAxis ? aMainAxis : 0; anAxis <= (myUseMainAxis ? aMainAxis : Min (N - 1, 2)); ++anAxis) { if (BVH::VecComp::Get (aSize, anAxis) <= BVH::THE_NODE_MIN_SIZE) continue; diff --git a/src/BVH/BVH_SpatialMedianBuilder.hxx b/src/BVH/BVH_SpatialMedianBuilder.hxx index 9b4e148ffc..5c7726ab37 100644 --- a/src/BVH/BVH_SpatialMedianBuilder.hxx +++ b/src/BVH/BVH_SpatialMedianBuilder.hxx @@ -26,7 +26,8 @@ public: //! Creates spatial median split builder. BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize = 5, - const Standard_Integer theMaxTreeDepth = 32); + const Standard_Integer theMaxTreeDepth = 32, + const Standard_Boolean theToUseMainAxis = Standard_False); //! Releases resources of spatial median split builder. virtual ~BVH_SpatialMedianBuilder(); diff --git a/src/BVH/BVH_SpatialMedianBuilder.lxx b/src/BVH/BVH_SpatialMedianBuilder.lxx index 69d26a9383..7be3a73615 100644 --- a/src/BVH/BVH_SpatialMedianBuilder.lxx +++ b/src/BVH/BVH_SpatialMedianBuilder.lxx @@ -21,9 +21,11 @@ // ======================================================================= template BVH_SpatialMedianBuilder::BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize, - const Standard_Integer theMaxTreeDepth) + const Standard_Integer theMaxTreeDepth, + const Standard_Boolean theToUseMainAxis) : BVH_BinnedBuilder (theLeafNodeSize, - theMaxTreeDepth) + theMaxTreeDepth, + theToUseMainAxis) { // } diff --git a/src/IVtk/IVtk_IShapePickerAlgo.hxx b/src/IVtk/IVtk_IShapePickerAlgo.hxx index aa36105b0a..6b9421384e 100644 --- a/src/IVtk/IVtk_IShapePickerAlgo.hxx +++ b/src/IVtk/IVtk_IShapePickerAlgo.hxx @@ -33,7 +33,6 @@ public: DEFINE_STANDARD_RTTI( IVtk_IShapePickerAlgo ) virtual void SetView (const IVtk_IView::Handle& theView) = 0; - virtual void Modified() = 0; virtual int NbPicked() = 0; //! Get activated selection modes for a shape. diff --git a/src/IVtk/IVtk_IView.hxx b/src/IVtk/IVtk_IView.hxx index c974e5ff96..b1230161cc 100644 --- a/src/IVtk/IVtk_IView.hxx +++ b/src/IVtk/IVtk_IView.hxx @@ -19,6 +19,8 @@ #include #include #include +#include +#include DEFINE_STANDARD_HANDLE( IVtk_IView, IVtk_Interface ) @@ -65,12 +67,26 @@ public: //! @return Two doubles containing the display coordinates of the view window center virtual void GetViewCenter (double& theX, double& theY) const = 0; + //! Gets window size in screen coordinates in pixels + virtual void GetWindowSize (int& theX, int& theY) const = 0; + + //! Gets camera projection and orientation matrices + virtual void GetCamera (Graphic3d_Mat4d& theProj, + Graphic3d_Mat4d& theOrient, + Standard_Boolean& theIsOrtho) const = 0; + //! Converts 3D display coordinates into 3D world coordinates. //! @param [in] theDisplayPnt 2d point of display coordinates //! @param [out] theWorldPnt 3d point of world coordinates //! @return true if conversion was successful, false otherwise virtual bool DisplayToWorld (const gp_XY& theDisplayPnt, gp_XYZ& theWorldPnt) const = 0; + //! Gets viewport coordinates + virtual void GetViewport (Standard_Real& theX, + Standard_Real& theY, + Standard_Real& theWidth, + Standard_Real& theHeight) const = 0; + DEFINE_STANDARD_RTTI( IVtk_IView ) }; diff --git a/src/IVtkOCC/IVtkOCC_SelectableObject.cxx b/src/IVtkOCC/IVtkOCC_SelectableObject.cxx index 7fb153e53a..57f27906e3 100644 --- a/src/IVtkOCC/IVtkOCC_SelectableObject.cxx +++ b/src/IVtkOCC/IVtkOCC_SelectableObject.cxx @@ -170,3 +170,13 @@ const Bnd_Box& IVtkOCC_SelectableObject::BoundingBox() return myBndBox; } + +//============================================================================ +// Method: BoundingBox +// Purpose: +//============================================================================ +void IVtkOCC_SelectableObject::BoundingBox (Bnd_Box& theBndBox) +{ + BoundingBox(); + theBndBox = myBndBox; +} diff --git a/src/IVtkOCC/IVtkOCC_SelectableObject.hxx b/src/IVtkOCC/IVtkOCC_SelectableObject.hxx index cfab9deaa3..b344cf4a48 100644 --- a/src/IVtkOCC/IVtkOCC_SelectableObject.hxx +++ b/src/IVtkOCC/IVtkOCC_SelectableObject.hxx @@ -43,6 +43,9 @@ public: const IVtkOCC_Shape::Handle& GetShape() const { return myShape; }; + //! Returns bounding box of object + Standard_EXPORT virtual void BoundingBox (Bnd_Box& theBndBox) Standard_OVERRIDE; + DEFINE_STANDARD_RTTI( IVtkOCC_SelectableObject ) private: diff --git a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx index f3c1f65c41..24255ce4ee 100644 --- a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx +++ b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx @@ -47,16 +47,6 @@ IVtkOCC_ShapePickerAlgo::~IVtkOCC_ShapePickerAlgo() void IVtkOCC_ShapePickerAlgo::SetView (const IVtk_IView::Handle& theView) { myView = theView; - Modified(); -} - -//================================================================ -// Function : Modified -// Purpose : -//================================================================ -void IVtkOCC_ShapePickerAlgo::Modified() -{ - myViewerSelector->Update (myView); } //================================================================ @@ -132,6 +122,7 @@ void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_IShape::Handle& theSh // then create a new selection in the given mode for this object (shape). Handle(SelectMgr_Selection) aNewSelection = new SelectMgr_Selection (theMode); aSelObj->AddSelection (aNewSelection, theMode); + myViewerSelector->AddSelectionToObject (aSelObj, aNewSelection); } // Update the selection for the given mode according to its status. @@ -141,14 +132,16 @@ void IVtkOCC_ShapePickerAlgo::SetSelectionMode (const IVtk_IShape::Handle& theSh { case SelectMgr_TOU_Full: // Recompute the sensitive primitives which correspond to the mode. - aSelObj->UpdateSelection (theMode); + myViewerSelector->RemoveSelectionOfObject (aSelObj, aSelObj->Selection (theMode)); + aSelObj->RecomputePrimitives (theMode); + myViewerSelector->AddSelectionToObject (aSelObj, aSelObj->Selection (theMode)); + myViewerSelector->RebuildObjectsTree(); + myViewerSelector->RebuildSensitivesTree (aSelObj); case SelectMgr_TOU_Partial: { if (aSelObj->HasTransformation()) { - // Updates locations in all sensitive entities from the Selection and - // corresponding entity owners (shapes). - aSelObj->UpdateTransformations (aSel); + myViewerSelector->RebuildObjectsTree(); } break; } diff --git a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx index f25621c8b8..93a79a1ebf 100644 --- a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx +++ b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx @@ -39,12 +39,6 @@ public: //! the 3D view projection. Standard_EXPORT virtual void SetView (const IVtk_IView::Handle& theView); - //! Informs the picker that some parameters of the view - //! has been modified so it is necessary to recompute internal selection data. - //! It makes sense to call this method automatically as soon as - //! the underlying VTK object emits its ModifiedEvent. - Standard_EXPORT virtual void Modified(); - //! Get number of picked entities. Standard_EXPORT virtual int NbPicked(); diff --git a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx index 94b93cecd1..c3fb9e5a22 100644 --- a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx +++ b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx @@ -29,33 +29,7 @@ IMPLEMENT_STANDARD_RTTIEXT( IVtkOCC_ViewerSelector, SelectMgr_ViewerSelector ) IVtkOCC_ViewerSelector::IVtkOCC_ViewerSelector() : SelectMgr_ViewerSelector(), myPixTol(2), -myToUpdateTol(Standard_True) -{ - for (Standard_Integer i=0;i<=13;i++) {myCoeff [i] = 0.;myPrevCoeff[i]=0.0;} - for (Standard_Integer j=0;j<2;j++) {myCenter [j] = 0.;myPrevCenter[j]=0.0;} -} - -//============================================================================ -// Method: Convert -// Purpose: Projects all sensitive entities from the given selection container -// to 2D space -//============================================================================ -void IVtkOCC_ViewerSelector::Convert (const Handle(SelectMgr_Selection)& theSelection) -{ - for (theSelection->Init(); theSelection->More(); theSelection->Next()) - { - if(theSelection->Sensitive()->NeedsConversion()) - { - Handle(Select3D_SensitiveEntity) aSensEntity = - *((Handle(Select3D_SensitiveEntity)*) &(theSelection->Sensitive())); - aSensEntity->Project (myPrj); - if (!tosort) - { - tosort = Standard_True; - } - } - } -} +myToUpdateTol(Standard_True) {} //============================================================================ // Method: Pick @@ -65,14 +39,38 @@ void IVtkOCC_ViewerSelector::Pick (const Standard_Integer theXPix, const Standard_Integer theYPix, const IVtk_IView::Handle& theView) { - myclip.SetVoid(); - Update (theView); - gp_XY aDispPnt (theXPix, theYPix); - gp_XYZ aWorldPnt; - gp_Pnt2d aP2d; - theView->DisplayToWorld (aDispPnt, aWorldPnt); - myPrj->Project (gp_Pnt (aWorldPnt), aP2d); - InitSelect (aP2d.X(), aP2d.Y()); + if (myToUpdateTol) + { + // Compute and set a sensitivity tolerance according to the renderer (viewport). + // TODO: Think if this works well in perspective view...'cause result depends + // on position on the screen, but we always use the point close to the + // screen's origin... + mySelectingVolumeMgr.SetPixelTolerance (myPixTol); + + myToUpdateTol = Standard_False; + } + + Standard_Integer aWidth = 0, aHeight = 0; + Graphic3d_Mat4d aProj, anOrient; + Standard_Boolean isOrthographic = Standard_False; + Standard_Real aX = RealLast(), aY = RealLast(); + Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast(); + + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Point); + theView->GetCamera (aProj, anOrient, isOrthographic); + mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic); + + theView->GetWindowSize (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); + + theView->GetViewport (aX, aY, aVpWidth, aVpHeight); + mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight); + + gp_Pnt2d aMousePos (static_cast (theXPix), + static_cast (theYPix)); + mySelectingVolumeMgr.BuildSelectingVolume (aMousePos); + + TraverseSensitives(); } //============================================================================ @@ -91,33 +89,36 @@ void IVtkOCC_ViewerSelector::Pick (const Standard_Integer theXMin, // TODO: Think if this works well in perspective view...'cause result depends // on position on the screen, but we always use the point close to the // screen's origin... - gp_XYZ aWorldPnt1, aWorldPnt2; - gp_XY aDispPnt1 (0.0, 0.0); - gp_XY aDispPnt2 (myPixTol, 0.0); - theView->DisplayToWorld (aDispPnt1, aWorldPnt1); - theView->DisplayToWorld (aDispPnt2, aWorldPnt2); - gp_Pnt aPnt1 (aWorldPnt1); - gp_Pnt aPnt2 (aWorldPnt2); - SetSensitivity (aPnt2.Distance (aPnt1)); + mySelectingVolumeMgr.SetPixelTolerance (myPixTol); + myToUpdateTol = Standard_False; } - Update (theView); - gp_XY aDispPnt1 (theXMin, theYMin); - gp_XY aDispPnt2 (theXMax, theYMax); - gp_XYZ aWorldPnt1, aWorldPnt2; + Standard_Integer aWidth = 0, aHeight = 0; + Graphic3d_Mat4d aProj, anOrient; + Standard_Boolean isOrthographic = Standard_False; + Standard_Real aX = RealLast(), aY = RealLast(); + Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast(); - gp_Pnt2d aP2d_1, aP2d_2; - theView->DisplayToWorld (aDispPnt1, aWorldPnt1); - theView->DisplayToWorld (aDispPnt2, aWorldPnt2); + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box); + theView->GetCamera (aProj, anOrient, isOrthographic); + mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic); - myPrj->Project (gp_Pnt (aWorldPnt1), aP2d_1); - myPrj->Project (gp_Pnt (aWorldPnt2), aP2d_2); + theView->GetWindowSize (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); - InitSelect (Min (aP2d_1.X(), aP2d_2.X()), - Min (aP2d_1.Y(), aP2d_2.Y()), - Max (aP2d_1.X(), aP2d_2.X()), - Max (aP2d_1.Y(), aP2d_2.Y())); + theView->GetViewport (aX, aY, aVpWidth, aVpHeight); + mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight); + + gp_Pnt2d aMinMousePos (static_cast (theXMin), + static_cast (theYMin)); + gp_Pnt2d aMaxMousePos (static_cast (theXMax), + static_cast (theYMax)); + + mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos, + aMaxMousePos); + + TraverseSensitives(); } //============================================================================ @@ -136,19 +137,11 @@ void IVtkOCC_ViewerSelector::Pick (double** thePoly, // TODO: Think if this works well in perspective view...'cause result depends // on position on the screen, but we always use the point close to the // screen's origin... - gp_XYZ aWorldPnt1, aWorldPnt2; - gp_XY aDispPnt1 (0.0, 0.0); - gp_XY aDispPnt2 (myPixTol, 0.0); - theView->DisplayToWorld (aDispPnt1, aWorldPnt1); - theView->DisplayToWorld (aDispPnt2, aWorldPnt2); - gp_Pnt aPnt1 (aWorldPnt1); - gp_Pnt aPnt2 (aWorldPnt2); - SetSensitivity (aPnt2.Distance (aPnt1)); + mySelectingVolumeMgr.SetPixelTolerance (myPixTol); + myToUpdateTol = Standard_False; } - Update (theView); - // Build TColgp_Array1OfPnt2d from input array of doubles gp_XYZ aWorldPnt; @@ -156,149 +149,46 @@ void IVtkOCC_ViewerSelector::Pick (double** thePoly, { gp_XY aDispPnt = thePoly[anIt][2] != 0 ? gp_XY (thePoly[anIt][0] / thePoly[anIt][2], thePoly[anIt][1] / thePoly[anIt][2]) : gp_XY (thePoly[anIt][0], thePoly[anIt][1]); - gp_Pnt2d aP2d; - theView->DisplayToWorld (aDispPnt, aWorldPnt); - myPrj->Project (gp_Pnt (aWorldPnt), aP2d); - aPolyline.SetValue (anIt + 1, aP2d); + aPolyline.SetValue (anIt + 1, aDispPnt); } - InitSelect (aPolyline); -} + Standard_Integer aWidth = 0, aHeight = 0; + Graphic3d_Mat4d aProj, anOrient; + Standard_Boolean isOrthographic = Standard_False; + Standard_Real aX = RealLast(), aY = RealLast(); + Standard_Real aVpWidth = RealLast(), aVpHeight = RealLast(); -//============================================================================ -// Method: Update -// Purpose: Checks if some projection parameters have changed, -// and updates the 2D projections of all sensitive entities if necessary. -//============================================================================ -Standard_Boolean IVtkOCC_ViewerSelector::Update (const IVtk_IView::Handle& theView) -{ - static Standard_Real aZoom (0.0); + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline); + theView->GetCamera (aProj, anOrient, isOrthographic); + mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic); - // No focal distance by default - myPrevCoeff[9] = 0.0; - // Parallel projection by default - myPrevCoeff[10] = 0.0; + theView->GetWindowSize (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); - // Flag related to perspective or parallel projection - Standard_Boolean isPerspective = theView->IsPerspective(); + theView->GetViewport (aX, aY, aVpWidth, aVpHeight); + mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight); - // For perspective projections only - if (isPerspective) - { - // Flag = 1 if perspective projection - myPrevCoeff[10] = 1.0; - // Focal distance - myPrevCoeff[9] = theView->GetDistance(); - } - // View point - // Use (0,0,0) as a view reference point: + mySelectingVolumeMgr.BuildSelectingVolume (aPolyline); - theView->GetPosition (myPrevCoeff[0], myPrevCoeff[1], myPrevCoeff[2]); - - // Orientation - theView->GetViewUp (myPrevCoeff[3], myPrevCoeff[4], myPrevCoeff[5]); - // Projection direction vector - theView->GetDirectionOfProjection (myPrevCoeff[6], myPrevCoeff[7], myPrevCoeff[8]); - - // 3D Scale - theView->GetScale (myPrevCoeff[11], myPrevCoeff[12], myPrevCoeff[13]); - - // Return the center of this viewport in display coordinates. - theView->GetViewCenter (myPrevCenter[0], myPrevCenter[1]); - - Standard_Integer anIt; - - for (anIt=0; anIt <= 13 && (myPrevCoeff[anIt] == myCoeff[anIt]); anIt++) { } - - if (anIt <= 13 || (myPrevCenter[0] != myCenter[0]) || (myPrevCenter[1] != myCenter[1])) - { - toupdate = Standard_True; - myToUpdateTol = Standard_True; - - for (Standard_Integer anI = anIt; anI <= 13; anI++) - { - myCoeff[anI] = myPrevCoeff[anI]; - } - - for (Standard_Integer aJ = 0; aJ < 2; aJ++) - { - myCenter[aJ] = myPrevCenter[aJ]; - } - - // For orthographic view use only direction of projection and up vector - // Panning, and zooming has no effect on 2D selection sensitives. - Handle (Graphic3d_Camera) aCamera = new Graphic3d_Camera(); - - aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic); - aCamera->SetCenter (gp::Origin()); - aCamera->SetDirection (gp_Dir (-myCoeff[6], -myCoeff[7], -myCoeff[8])); - aCamera->SetUp (gp_Dir (myCoeff[3], myCoeff[4], myCoeff[5])); - aCamera->SetDistance (1.0); - aCamera->SetAxialScale (gp_XYZ (myCoeff[11], myCoeff[12], myCoeff[13])); - - myPrj = new Select3D_Projector (aCamera->OrientationMatrix(), Graphic3d_Mat4d()); - } - - if (isPerspective) - { - if (Abs(theView->GetViewAngle() - aZoom) > 1.e-3) - { - myToUpdateTol = Standard_True; - aZoom = theView->GetViewAngle(); - } - } - else - { - if (Abs (theView->GetParallelScale() - aZoom) > 1.e-3) - { - myToUpdateTol = Standard_True; - aZoom = theView->GetParallelScale(); - } - } - - if(myToUpdateTol) - { - // Compute and set a sensitivity tolerance according to the view - gp_XYZ aWorldPnt1, aWorldPnt2; - gp_XY aDispPnt1 (0.0, 0.0); - gp_XY aDispPnt2 (myPixTol, 0.0); - - theView->DisplayToWorld (aDispPnt1, aWorldPnt1); - theView->DisplayToWorld (aDispPnt2, aWorldPnt2); - gp_Pnt aPnt1 (aWorldPnt1); - gp_Pnt aPnt2 (aWorldPnt2); - SetSensitivity (aPnt2.Distance (aPnt1)); - - myToUpdateTol = Standard_False; - } - - if(toupdate) UpdateConversion(); - if(tosort) UpdateSort(); - - return Standard_True; + TraverseSensitives(); } //============================================================================ // Method: Activate // Purpose: Activates the given selection //============================================================================ -void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection, - const Standard_Boolean theIsAutomaticProj) +void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection) { - tosort = Standard_True; + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + theSelection->Sensitive()->SetActiveForSelection(); + } - if (!myselections.IsBound (theSelection)) - { - myselections.Bind (theSelection, 0); - } - else if (myselections (theSelection) != 0) - { - myselections (theSelection) = 0; - } - if (theIsAutomaticProj) - { - Convert (theSelection); - } + theSelection->SetSelectionState (SelectMgr_SOS_Activated); + + myTolerances.Add (theSelection->Sensitivity()); + mytolerance = myTolerances.Largest(); + myToUpdateTolerance = Standard_True; } //============================================================================ @@ -307,18 +197,14 @@ void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSel //============================================================================ void IVtkOCC_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection) { - if (myselections.IsBound (theSelection)) + for (theSelection->Init(); theSelection->More(); theSelection->Next()) { - myselections (theSelection) = 1; - tosort = Standard_True; + theSelection->Sensitive()->ResetSelectionActiveStatus(); } -} -//============================================================================ -// Method: PickingLine -// Purpose: Deactivate the given selection -//============================================================================ -gp_Lin IVtkOCC_ViewerSelector::PickingLine (const Standard_Real theX,const Standard_Real theY) const -{ - return myPrj->Shoot (theX, theY); + theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); + + myTolerances.Decrement (theSelection->Sensitivity()); + mytolerance = myTolerances.Largest(); + myToUpdateTolerance = Standard_True; } diff --git a/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx b/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx index 4f5485305a..e1b36fd987 100644 --- a/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx +++ b/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx @@ -17,7 +17,6 @@ #define __IVTKOCC_VIEWERSELECTOR_H__ #include -#include #include #include @@ -32,10 +31,6 @@ class IVtkOCC_ViewerSelector : public SelectMgr_ViewerSelector public: IVtkOCC_ViewerSelector(); - //! Projects all sensitive entities from the given selection container to 2D space - //! param [in] theSelection Container with sensitive entities to project - void Convert (const Handle(SelectMgr_Selection)& theSelection); - //! Implements point picking //! @param [in] theXPix, theYPix Display coordinates of the point //! @param [in] theView ICamera interface to update the projection parameters. @@ -56,32 +51,15 @@ public: void Pick (double** thePoly, const int theNbPoints, const IVtk_IView::Handle& theView); //! Activates the given selection - void Activate (const Handle(SelectMgr_Selection)& theSelection, - const Standard_Boolean isAutomaticProj = Standard_True); + void Activate (const Handle(SelectMgr_Selection)& theSelection); //! Deactivate the given selection void Deactivate (const Handle(SelectMgr_Selection)& theSelection); - //! Checks if some projection parameters have changed, - //! and updates the 2D projections of all sensitive entities if necessary. - //! @param [in] theView Interface to VTK renderer to access projection parameters - Standard_Boolean Update (const IVtk_IView::Handle& theView); - - //! Returns picking line. - //! @param theX direction X. - //! @param theX direction Y. - //! @return picking direction. - virtual gp_Lin PickingLine (const Standard_Real theX, const Standard_Real theY) const; - DEFINE_STANDARD_RTTI( IVtkOCC_ViewerSelector ) private: - Standard_Real myCoeff[14]; - Standard_Real myPrevCoeff[14]; - Standard_Real myCenter[2]; - Standard_Real myPrevCenter[2]; Standard_Integer myPixTol; - Handle(Select3D_Projector) myPrj; Standard_Boolean myToUpdateTol; }; diff --git a/src/IVtkVTK/IVtkVTK_View.cxx b/src/IVtkVTK/IVtkVTK_View.cxx index e7db1cfe58..39cff7c908 100644 --- a/src/IVtkVTK/IVtkVTK_View.cxx +++ b/src/IVtkVTK/IVtkVTK_View.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include // Initialization of VTK object factories. @@ -159,3 +160,56 @@ bool IVtkVTK_View::DisplayToWorld (const gp_XY& theDisplayPnt, gp_XYZ& theWorldP return true; } + +//================================================================ +// Function : GetWindowSize +// Purpose : +//================================================================ +void IVtkVTK_View::GetWindowSize (int& theX, int& theY) const +{ + int* aSize = myRenderer->GetRenderWindow()->GetSize(); + theX = aSize[0]; + theY = aSize[1]; +} + +//================================================================ +// Function : GetCamera +// Purpose : +//================================================================ +void IVtkVTK_View::GetCamera (Graphic3d_Mat4d& theProj, + Graphic3d_Mat4d& theOrient, + Standard_Boolean& theIsOrtho) const +{ + theIsOrtho = !IsPerspective(); + + vtkMatrix4x4* aCompositeProj = + myRenderer->GetActiveCamera()->GetCompositeProjectionTransformMatrix (myRenderer->GetTiledAspectRatio(), + 0, + 1); + for (Standard_Integer aRow = 0; aRow < 4; ++aRow) + { + for (Standard_Integer aCol = 0; aCol < 4; ++aCol) + { + theProj.SetValue (aRow, aCol, aCompositeProj->GetElement (aRow, aCol)); + } + } + + theOrient.InitIdentity(); +} + +//================================================================ +// Function : GetViewport +// Purpose : +//================================================================ +void IVtkVTK_View::GetViewport (Standard_Real& theX, + Standard_Real& theY, + Standard_Real& theWidth, + Standard_Real& theHeight) const +{ + Standard_Real aViewport[4]; + myRenderer->GetViewport (aViewport); + theX = aViewport[0]; + theY = aViewport[1]; + theWidth = aViewport[2]; + theHeight = aViewport[3]; +} diff --git a/src/IVtkVTK/IVtkVTK_View.hxx b/src/IVtkVTK/IVtkVTK_View.hxx index b66af7fc98..7f62fe3746 100644 --- a/src/IVtkVTK/IVtkVTK_View.hxx +++ b/src/IVtkVTK/IVtkVTK_View.hxx @@ -68,6 +68,20 @@ public: //! @return Two doubles containing the display coordinates of the view window center Standard_EXPORT virtual void GetViewCenter (double& theX, double& theY) const; + //! Gets window size in screen coordinates in pixels + Standard_EXPORT virtual void GetWindowSize (int& theX, int& theY) const Standard_OVERRIDE; + + //! Gets camera projection and orientation matrices + Standard_EXPORT virtual void GetCamera (Graphic3d_Mat4d& theProj, + Graphic3d_Mat4d& theOrient, + Standard_Boolean& theIsOrtho) const Standard_OVERRIDE; + + //! Gets viewport coordinates + Standard_EXPORT virtual void GetViewport (Standard_Real& theX, + Standard_Real& theY, + Standard_Real& theWidth, + Standard_Real& theHeight) const Standard_OVERRIDE; + //! Converts 3D display coordinates into 3D world coordinates. //! @param [in] theDisplayPnt 2d point of display coordinates //! @param [out] theWorldPnt 3d point of world coordinates diff --git a/src/MeshVS/FILES b/src/MeshVS/FILES index d85be04329..fbc8f8c6a3 100755 --- a/src/MeshVS/FILES +++ b/src/MeshVS/FILES @@ -1,10 +1,20 @@ MeshVS_Buffer.hxx MeshVS_EntityType.hxx MeshVS_DisplayModeFlags.hxx +MeshVS_DummySensitiveEntity.hxx +MeshVS_DummySensitiveEntity.cxx MeshVS_BuilderPriority.hxx MeshVS_MeshPrsBuilder.lxx MeshVS_TwoColors.hxx MeshVS_TwoColors.cxx MeshVS_TwoNodes.hxx MeshVS_SelectionModeFlags.hxx +MeshVS_SensitiveFace.hxx +MeshVS_SensitiveFace.cxx +MeshVS_SensitiveMesh.hxx +MeshVS_SensitiveMesh.cxx +MeshVS_SensitiveSegment.hxx +MeshVS_SensitiveSegment.cxx +MeshVS_SensitivePolyhedron.hxx +MeshVS_SensitivePolyhedron.cxx MeshVS_SymmetricPairHasher.hxx diff --git a/src/MeshVS/MeshVS.cdl b/src/MeshVS/MeshVS.cdl index 1e0d85c432..2835b67b0b 100644 --- a/src/MeshVS/MeshVS.cdl +++ b/src/MeshVS/MeshVS.cdl @@ -141,12 +141,6 @@ is class MeshOwner; class MeshEntityOwner; - class DummySensitiveEntity; - class SensitiveMesh; - class SensitiveFace; - class SensitiveSegment; - class SensitivePolyhedron; - ---Category: miscellaneous types: data maps, enumerations and other imported EntityType; @@ -156,6 +150,11 @@ is imported BuilderPriority; imported TwoNodes; imported Buffer; + imported SensitiveFace; + imported SensitiveMesh; + imported SensitiveSegment; + imported SensitivePolyhedron; + imported DummySensitiveEntity; class Tool; diff --git a/src/MeshVS/MeshVS_DummySensitiveEntity.cdl b/src/MeshVS/MeshVS_DummySensitiveEntity.cdl deleted file mode 100644 index f419867c88..0000000000 --- a/src/MeshVS/MeshVS_DummySensitiveEntity.cdl +++ /dev/null @@ -1,55 +0,0 @@ --- Created on: 2003-09-29 --- Created by: Alexander SOLOVYOV and Sergey LITONIN --- Copyright (c) 2003-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class DummySensitiveEntity from MeshVS inherits SensitiveEntity from SelectBasics - - ---Purpose: This class allows to create owners to all elements or nodes, - -- both hidden and shown, but these owners user cannot select "by hands" - -- in viewer. They means for internal application tasks, for example, receiving - -- all owners, both for hidden and shown entities. -uses - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt2d from TColgp, - - Box2d from Bnd - -is - Create ( OwnerId : EntityOwner from SelectBasics ) returns DummySensitiveEntity from MeshVS; - - Areas ( me: mutable; - aresult: in out ListOfBox2d from SelectBasics ) is redefined; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined; - - Matches ( me: mutable; - XMin, YMin, XMax, YMax, aTol: Real ) returns Boolean is redefined; - - Matches ( me: mutable; - Polyline : Array1OfPnt2d from TColgp; - aBox : Box2d from Bnd; - aTol : Real ) returns Boolean is redefined; - - Is3D ( me ) returns Boolean is redefined; - - NeedsConversion ( me ) returns Boolean is redefined; - - MaxBoxes ( me ) returns Integer is redefined; - -end DummySensitiveEntity; diff --git a/src/MeshVS/MeshVS_DummySensitiveEntity.cxx b/src/MeshVS/MeshVS_DummySensitiveEntity.cxx index 17d08f36e3..16c53eae64 100644 --- a/src/MeshVS/MeshVS_DummySensitiveEntity.cxx +++ b/src/MeshVS/MeshVS_DummySensitiveEntity.cxx @@ -13,84 +13,61 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include + +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity) //================================================================ // Function : Constructor MeshVS_DummySensitiveEntity // Purpose : //================================================================ -MeshVS_DummySensitiveEntity::MeshVS_DummySensitiveEntity - ( const Handle(SelectBasics_EntityOwner)& OwnerId ) -: SelectBasics_SensitiveEntity( OwnerId ) -{ -} +MeshVS_DummySensitiveEntity::MeshVS_DummySensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId) +: SelectBasics_SensitiveEntity (theOwnerId) +{} //================================================================ -// Function : Areas +// Function : NbSubElements // Purpose : //================================================================ -void MeshVS_DummySensitiveEntity::Areas( SelectBasics_ListOfBox2d& ) +Standard_Integer MeshVS_DummySensitiveEntity::NbSubElements() { + return -1; } //================================================================ // Function : Matches // Purpose : //================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const SelectBasics_PickArgs&, - Standard_Real&, - Standard_Real& ) +Standard_Boolean MeshVS_DummySensitiveEntity::Matches (SelectBasics_SelectingVolumeManager& /*theMgr*/, + SelectBasics_PickResult& /*thePickResult*/) { return Standard_False; } //================================================================ -// Function : Matches +// Function : BoundingBox // Purpose : //================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const Standard_Real, - const Standard_Real, - const Standard_Real, - const Standard_Real, - const Standard_Real ) +Select3D_BndBox3d MeshVS_DummySensitiveEntity::BoundingBox() { - return Standard_False; + return Select3D_BndBox3d(); } //================================================================ -// Function : Matches +// Function : ElementsNb // Purpose : //================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const TColgp_Array1OfPnt2d&, - const Bnd_Box2d&, - const Standard_Real ) -{ - return Standard_False; -} +void MeshVS_DummySensitiveEntity::BVH() +{} //================================================================ -// Function : NeedsConversion +// Function : Clear // Purpose : //================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::NeedsConversion() const -{ - return Standard_False; -} - -//================================================================ -// Function : Is3D -// Purpose : -//================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::Is3D() const -{ - return Standard_True; -} - -//================================================================ -// Function : MaxBoxes -// Purpose : -//================================================================ -Standard_Integer MeshVS_DummySensitiveEntity::MaxBoxes() const -{ - return 0; -} +void MeshVS_DummySensitiveEntity::Clear() +{} diff --git a/src/MeshVS/MeshVS_DummySensitiveEntity.hxx b/src/MeshVS/MeshVS_DummySensitiveEntity.hxx new file mode 100644 index 0000000000..6e7402006b --- /dev/null +++ b/src/MeshVS/MeshVS_DummySensitiveEntity.hxx @@ -0,0 +1,56 @@ +// Created on: 2003-09-29 +// Created by: Alexander SOLOVYOV and Sergey LITONIN +// Copyright (c) 2003-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _MeshVS_DummySensitiveEntity_HeaderFile +#define _MeshVS_DummySensitiveEntity_HeaderFile + +#include +#include + +#include +#include +#include +#include + +class SelectBasics_EntityOwner; + + +//! This class allows to create owners to all elements or nodes, +//! both hidden and shown, but these owners user cannot select "by hands" +//! in viewer. They means for internal application tasks, for example, receiving +//! all owners, both for hidden and shown entities. +class MeshVS_DummySensitiveEntity : public SelectBasics_SensitiveEntity +{ +public: + + Standard_EXPORT MeshVS_DummySensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId); + + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + Standard_EXPORT virtual void Clear() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(MeshVS_DummySensitiveEntity) +}; + +DEFINE_STANDARD_HANDLE(MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity) + +#endif // _MeshVS_DummySensitiveEntity_HeaderFile diff --git a/src/MeshVS/MeshVS_Mesh.cdl b/src/MeshVS/MeshVS_Mesh.cdl index 043d884656..63c83be5ee 100644 --- a/src/MeshVS/MeshVS_Mesh.cdl +++ b/src/MeshVS/MeshVS_Mesh.cdl @@ -29,9 +29,9 @@ uses NameOfColor from Quantity, - Selection from SelectMgr, - EntityOwner from SelectMgr, - SequenceOfOwner from SelectMgr, + Selection from SelectMgr, + EntityOwner from SelectMgr, + SequenceOfOwner from SelectMgr, Boolean from Standard, CString from Standard, diff --git a/src/MeshVS/MeshVS_SensitiveFace.cdl b/src/MeshVS/MeshVS_SensitiveFace.cdl deleted file mode 100644 index 554327f5d8..0000000000 --- a/src/MeshVS/MeshVS_SensitiveFace.cdl +++ /dev/null @@ -1,54 +0,0 @@ --- Created on: 2003-09-29 --- Created by: Alexander SOLOVYOV and Sergey LITONIN --- Copyright (c) 2003-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveFace from MeshVS inherits SensitiveFace from Select3D - - ---Purpose: This class provides custom sensitive face, which will be selected if it center is in rectangle. - -uses - EntityOwner from SelectBasics, - - Array1OfPnt from TColgp, - - TypeOfSensitivity from Select3D, - Projector from Select3D, - - Pnt from gp, - Pnt2d from gp, - - Array1OfPnt2d from TColgp, - - Box2d from Bnd - -is - - Create ( theOwner : EntityOwner from SelectBasics; - thePoints : Array1OfPnt from TColgp; - theSensType : TypeOfSensitivity from Select3D = Select3D_TOS_INTERIOR ) - returns SensitiveFace from MeshVS; - - Project( me: mutable; aProjector : Projector from Select3D ) is redefined; - - Matches ( me: mutable; XMin, YMin, XMax, YMax: Real; - aTol: Real ) returns Boolean is redefined; - - Matches ( me: mutable; Polyline: Array1OfPnt2d from TColgp; - aBox:Box2d; aTol: Real ) returns Boolean is redefined; - -fields - myCentre : Pnt from gp is protected; - myProjCentre : Pnt2d from gp is protected; - -end SensitiveFace; diff --git a/src/MeshVS/MeshVS_SensitiveFace.cxx b/src/MeshVS/MeshVS_SensitiveFace.cxx index 872ff539e6..2a26ae7982 100644 --- a/src/MeshVS/MeshVS_SensitiveFace.cxx +++ b/src/MeshVS/MeshVS_SensitiveFace.cxx @@ -13,70 +13,26 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include - +#include +#include #include -#include -#include -#include + +IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveFace, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveFace, Select3D_SensitiveEntity) //======================================================================= // name : MeshVS_SensitiveFace::MeshVS_SensitiveFace // Purpose : //======================================================================= -MeshVS_SensitiveFace::MeshVS_SensitiveFace ( - const Handle(SelectBasics_EntityOwner)& theOwnerId, - const TColgp_Array1OfPnt& thePnts, - const Select3D_TypeOfSensitivity theSensitivity ) -: Select3D_SensitiveFace( theOwnerId, thePnts, theSensitivity ) +MeshVS_SensitiveFace::MeshVS_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePnts, + const Select3D_TypeOfSensitivity theSensitivity) +: Select3D_SensitiveFace (theOwnerId, thePnts, theSensitivity) { - gp_XYZ c( 0, 0, 0 ); - Standard_Integer nbPnts = thePnts.Upper() - thePnts.Lower() + 1; - for ( Standard_Integer i = thePnts.Lower(); i <= thePnts.Upper(); i++ ) - c += thePnts( i ).XYZ(); - myCentre.SetXYZ( c / nbPnts ); -} + gp_XYZ aCenter (0.0, 0.0, 0.0); + Standard_Integer aNbPnts = thePnts.Upper() - thePnts.Lower() + 1; + for (Standard_Integer aPntIdx = thePnts.Lower(); aPntIdx <= thePnts.Upper(); aPntIdx++) + aCenter += thePnts (aPntIdx).XYZ(); -//======================================================================= -// name : MeshVS_SensitiveFace::Project -// Purpose : -//======================================================================= -void MeshVS_SensitiveFace::Project( const Handle(Select3D_Projector)& aProj ) -{ - Select3D_SensitiveFace::Project( aProj ); - if ( HasLocation() ) - aProj->Project( myCentre.Transformed( Location().Transformation() ), myProjCentre ); - else - aProj->Project( myCentre, myProjCentre ); -} - -//======================================================================= -// name : MeshVS_SensitiveFace::Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveFace::Matches( const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol ) -{ - Bnd_Box2d aBox; - aBox.Update( XMin-aTol, YMin-aTol, XMax+aTol, YMax+aTol ); - return !aBox.IsOut( myProjCentre ); -} - -//======================================================================= -// name : MeshVS_SensitiveFace::Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveFace::Matches( const TColgp_Array1OfPnt2d& Polyline, - const Bnd_Box2d& aBox, - const Standard_Real aTol ) -{ - Standard_Real Umin, Vmin, Umax, Vmax; - aBox.Get ( Umin,Vmin,Umax,Vmax ); - CSLib_Class2d aClassifier2d( Polyline, aTol, aTol, Umin, Vmin, Umax, Vmax ); - Standard_Integer aRes = aClassifier2d.SiDans( myProjCentre ); - - return ( aRes == 1) ; + myCenter.SetXYZ (aCenter / aNbPnts); } diff --git a/src/MeshVS/MeshVS_SensitiveFace.hxx b/src/MeshVS/MeshVS_SensitiveFace.hxx new file mode 100644 index 0000000000..d7464e58cf --- /dev/null +++ b/src/MeshVS/MeshVS_SensitiveFace.hxx @@ -0,0 +1,49 @@ +// Created on: 2003-09-29 +// Created by: Alexander SOLOVYOV and Sergey LITONIN +// Copyright (c) 2003-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _MeshVS_SensitiveFace_HeaderFile +#define _MeshVS_SensitiveFace_HeaderFile + +#include +#include + +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; + + +//! This class provides custom sensitive face, which will be selected if it center is in rectangle. +class MeshVS_SensitiveFace : public Select3D_SensitiveFace +{ +public: + + Standard_EXPORT MeshVS_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwner, + const TColgp_Array1OfPnt& thePoints, + const Select3D_TypeOfSensitivity theSensType = Select3D_TOS_INTERIOR); + + DEFINE_STANDARD_RTTI(MeshVS_SensitiveFace) + +protected: + + gp_Pnt myCenter; +}; + +DEFINE_STANDARD_HANDLE(MeshVS_SensitiveFace, Select3D_SensitiveFace) + +#endif // _MeshVS_SensitiveFace_HeaderFile diff --git a/src/MeshVS/MeshVS_SensitiveMesh.cdl b/src/MeshVS/MeshVS_SensitiveMesh.cdl deleted file mode 100644 index f96826a860..0000000000 --- a/src/MeshVS/MeshVS_SensitiveMesh.cdl +++ /dev/null @@ -1,69 +0,0 @@ --- Created on: 2007-01-25 --- Created by: Sergey KOCHETKOV --- Copyright (c) 2007-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveMesh from MeshVS inherits SensitiveEntity from Select3D - - ---Purpose: This class provides custom mesh sensitive entity used in advanced mesh selection. - ---It provides detection of mesh entities accordingly to activated selection mode - -uses - EntityOwner from SelectBasics, - Array1OfPnt2d from TColgp, - Box from Bnd, - Box2d from Bnd, - Location from TopLoc, - Lin from gp, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Projector from Select3D -is - - Create ( theOwner : EntityOwner from SelectBasics; - theMode : Integer = 0 ) - returns SensitiveMesh from MeshVS; - - GetMode( me ) returns Integer from Standard; - - GetConnected( me: mutable; aLocation : Location from TopLoc ) - returns SensitiveEntity from Select3D is redefined; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined; - - Matches ( me: mutable; XMin, YMin, XMax, YMax : Real; - aTol : Real ) returns Boolean - is redefined; - - Matches ( me: mutable; Polyline : Array1OfPnt2d from TColgp; - aBox : Box2d; - aTol : Real ) returns Boolean - is redefined; - - Project ( me:mutable; aProjector : Projector from Select3D ) is redefined static; - - Areas ( me: mutable ; boxes : in out ListOfBox2d from SelectBasics ) is redefined static; - - ProjectOneCorner( me: mutable; aProjector : Projector from Select3D; - X,Y,Z : Real from Standard ) is private; - -fields - - myMode : Integer from Standard; - mybox : Box from Bnd; - mybox2d : Box2d from Bnd; - -end SensitiveMesh; diff --git a/src/MeshVS/MeshVS_SensitiveMesh.cxx b/src/MeshVS/MeshVS_SensitiveMesh.cxx index 193b1b6865..714ffa4282 100644 --- a/src/MeshVS/MeshVS_SensitiveMesh.cxx +++ b/src/MeshVS/MeshVS_SensitiveMesh.cxx @@ -13,15 +13,20 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include #include #include #include -#include +#include +#include #include #include #include +#include + +IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveMesh, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveMesh, Select3D_SensitiveEntity) //======================================================================= // name : MeshVS_SensitiveMesh::MeshVS_SensitiveMesh @@ -29,16 +34,24 @@ //======================================================================= MeshVS_SensitiveMesh::MeshVS_SensitiveMesh (const Handle(SelectBasics_EntityOwner)& theOwnerId, const Standard_Integer theMode) -: Select3D_SensitiveEntity( theOwnerId ) +: Select3D_SensitiveEntity (theOwnerId) { myMode = theMode; - mybox.SetVoid(); - Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); + Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast (OwnerId()); if( !anOwner.IsNull() ) { Handle(MeshVS_DataSource) aDS = anOwner->GetDataSource(); - if( !aDS.IsNull() ) - mybox = aDS->GetBoundingBox(); + if (!aDS.IsNull()) + { + Bnd_Box aBox = aDS->GetBoundingBox(); + Standard_Real aXMin, aYMin, aZMin; + Standard_Real aXMax, aYMax, aZMax; + aBox.Get (aXMin, aYMin, aZMin, + aXMax, aYMax, aZMax); + Select3D_Vec3 aMinPnt (aXMin, aYMin, aZMin); + Select3D_Vec3 aMaxPnt (aXMax, aYMax, aZMax); + myBndBox = Select3D_BndBox3d (aMinPnt, aMaxPnt); + } } } @@ -46,159 +59,54 @@ MeshVS_SensitiveMesh::MeshVS_SensitiveMesh (const Handle(SelectBasics_EntityOwne // Function : GetMode // Purpose : //================================================================ -Standard_Integer MeshVS_SensitiveMesh::GetMode () const +Standard_Integer MeshVS_SensitiveMesh::GetMode() const { return myMode; } -//======================================================================= -// name : Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveMesh::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - theMatchDMin = 0.0; - theMatchDepth = Precision::Infinite(); - - Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); - if( anOwner.IsNull() ) return Standard_False; - Handle(MeshVS_Mesh) aMeshPrs = Handle(MeshVS_Mesh)::DownCast( anOwner->Selectable() ); - if( aMeshPrs.IsNull() ) return Standard_False; - Handle(MeshVS_DataSource) aDS = anOwner->GetDataSource(); - if( aDS.IsNull() ) return Standard_False; - Handle(TColStd_HPackedMapOfInteger) NodesMap; - Handle(TColStd_HPackedMapOfInteger) ElemsMap; - - // Mesh data source should provide the algorithm for computation - // of detected entities from 2D point - Standard_Boolean isDetected = - aDS->GetDetectedEntities (aMeshPrs, thePickArgs.X(), thePickArgs.Y(), - thePickArgs.Tolerance(), NodesMap, - ElemsMap, theMatchDMin); - - // The detected entites will be available from mesh owner - anOwner->SetDetectedEntities( NodesMap, ElemsMap ); - - return isDetected; -} - -//======================================================================= -// name : Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveMesh::Matches(const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); - if( anOwner.IsNull() ) return Standard_False; - Handle(MeshVS_Mesh) aMeshPrs = Handle(MeshVS_Mesh)::DownCast( anOwner->Selectable() ); - if( aMeshPrs.IsNull() ) return Standard_False; - Handle(MeshVS_DataSource) aDS = anOwner->GetDataSource(); - if( aDS.IsNull() ) return Standard_False; - Handle(TColStd_HPackedMapOfInteger) NodesMap; - Handle(TColStd_HPackedMapOfInteger) ElemsMap; - // Mesh data source should provide the algorithm for computation - // of detected entities from 2D box area - Standard_Boolean isDetected = aDS->GetDetectedEntities( aMeshPrs, XMin, YMin, XMax, YMax, aTol, NodesMap, ElemsMap ); - // The detected entites will be available from mesh owner - anOwner->SetDetectedEntities( NodesMap, ElemsMap ); - - return isDetected; -} - -//======================================================================= -// name : Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveMesh::Matches(const TColgp_Array1OfPnt2d& Polyline, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); - if( anOwner.IsNull() ) return Standard_False; - Handle(MeshVS_Mesh) aMeshPrs = Handle(MeshVS_Mesh)::DownCast( anOwner->Selectable() ); - if( aMeshPrs.IsNull() ) return Standard_False; - Handle(MeshVS_DataSource) aDS = anOwner->GetDataSource(); - if( aDS.IsNull() ) return Standard_False; - Handle(TColStd_HPackedMapOfInteger) NodesMap; - Handle(TColStd_HPackedMapOfInteger) ElemsMap; - // Mesh data source should provide the algorithm for computation - // of detected entities from 2D polyline - Standard_Boolean isDetected = aDS->GetDetectedEntities( aMeshPrs, Polyline, aBox, aTol, NodesMap, ElemsMap ); - // The detected entites will be available from mesh owner - anOwner->SetDetectedEntities( NodesMap, ElemsMap ); - - return isDetected; -} - //======================================================================= // name : GetConnected // Purpose : //======================================================================= -Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected( const TopLoc_Location& aLoc ) +Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected() { - Handle(MeshVS_SensitiveMesh) aMeshEnt = new MeshVS_SensitiveMesh( myOwnerId ); - if(HasLocation()) aMeshEnt->SetLocation( Location() ); - aMeshEnt->UpdateLocation( aLoc ); + Handle(MeshVS_SensitiveMesh) aMeshEnt = new MeshVS_SensitiveMesh (myOwnerId); return aMeshEnt; } -//================================================== -// Function: ProjectOneCorner -// Purpose : -//================================================== -void MeshVS_SensitiveMesh::ProjectOneCorner(const Handle(Select3D_Projector)& theProj, - const Standard_Real theX, - const Standard_Real theY, - const Standard_Real theZ) +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of mesh nodes +//======================================================================= +Standard_Integer MeshVS_SensitiveMesh::NbSubElements() { - gp_Pnt aPnt( theX, theY, theZ ); - gp_Pnt2d aProjPnt; - if( HasLocation() ) - theProj->Project( aPnt.Transformed(Location().Transformation()), aProjPnt ); - else - theProj->Project( aPnt, aProjPnt ); - mybox2d.Add( aProjPnt ); + Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast (OwnerId()); + if (anOwner.IsNull()) + return -1; + Handle(MeshVS_DataSource) aDataSource = anOwner->GetDataSource(); + if (aDataSource.IsNull()) + return -1; + return aDataSource->GetAllNodes().Extent(); } -//================================================== -// Function: Project -// Purpose : -//================================================== -void MeshVS_SensitiveMesh::Project(const Handle(Select3D_Projector)& aProj) +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of mesh +//======================================================================= +Select3D_BndBox3d MeshVS_SensitiveMesh::BoundingBox() { - mybox2d.SetVoid(); - if (mybox.IsVoid()) - return; - // Compute the 2D bounding box - projection of mesh bounding box - Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); - if( anOwner.IsNull() ) return; - Handle(MeshVS_DataSource) aDS = anOwner->GetDataSource(); - if( aDS.IsNull() ) return; - - Standard_Real XMin, YMin, ZMin, XMax, YMax, ZMax; - mybox.Get( XMin, YMin, ZMin, XMax, YMax, ZMax ); - - ProjectOneCorner (aProj, XMin, YMin, ZMin); - ProjectOneCorner (aProj, XMin, YMin, ZMax); - ProjectOneCorner (aProj, XMin, YMax, ZMin); - ProjectOneCorner (aProj, XMin, YMax, ZMax); - ProjectOneCorner (aProj, XMax, YMin, ZMin); - ProjectOneCorner (aProj, XMax, YMin, ZMax); - ProjectOneCorner (aProj, XMax, YMax, ZMin); - ProjectOneCorner (aProj, XMax, YMax, ZMax); + return myBndBox; } -//================================================== -// Function: Areas -// Purpose : -//================================================== -void MeshVS_SensitiveMesh::Areas( SelectBasics_ListOfBox2d& aSeq ) +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of mesh +//======================================================================= +gp_Pnt MeshVS_SensitiveMesh::CenterOfGeometry() const { - aSeq.Append(mybox2d); + if (!myBndBox.IsValid()) + return gp_Pnt (0.0, 0.0, 0.0); + + SelectMgr_Vec3 aCenter = (myBndBox.CornerMax() + myBndBox.CornerMin()) * 0.5; + return gp_Pnt (aCenter.x(), aCenter.y(), aCenter.z()); } diff --git a/src/MeshVS/MeshVS_SensitiveMesh.hxx b/src/MeshVS/MeshVS_SensitiveMesh.hxx new file mode 100644 index 0000000000..f8a01f04f4 --- /dev/null +++ b/src/MeshVS/MeshVS_SensitiveMesh.hxx @@ -0,0 +1,63 @@ +// Created on: 2007-01-29 +// Created by: Sergey KOCHETKOV +// Copyright (c) 2007-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _MeshVS_SensitiveMesh_HeaderFile +#define _MeshVS_SensitiveMesh_HeaderFile + +#include +#include + +#include +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class Select3D_SensitiveEntity; + + +//! This class provides custom mesh sensitive entity used in advanced mesh selection. +class MeshVS_SensitiveMesh : public Select3D_SensitiveEntity +{ +public: + + Standard_EXPORT MeshVS_SensitiveMesh (const Handle(SelectBasics_EntityOwner)& theOwner, + const Standard_Integer theMode = 0); + + Standard_EXPORT Standard_Integer GetMode() const; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Returns the amount of mesh nodes + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + //! Returns bounding box of mesh + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of mesh + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(MeshVS_SensitiveMesh) + +private: + + Standard_Integer myMode; + Select3D_BndBox3d myBndBox; +}; + +DEFINE_STANDARD_HANDLE(MeshVS_SensitiveMesh, Select3D_SensitiveEntity) + +#endif // _MeshVS_SensitiveMesh_HeaderFile diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.cdl b/src/MeshVS/MeshVS_SensitivePolyhedron.cdl deleted file mode 100644 index 20325d63b0..0000000000 --- a/src/MeshVS/MeshVS_SensitivePolyhedron.cdl +++ /dev/null @@ -1,78 +0,0 @@ --- Created on: 2005-01-21 --- Created by: Alexander SOLOVYOV --- Copyright (c) 2005-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitivePolyhedron from MeshVS inherits SensitiveEntity from Select3D - -uses - EntityOwner from SelectBasics, - Projector from Select3D, - Location from TopLoc, - Real from Standard, - Boolean from Standard, - Array1OfPnt2d from TColgp, - SequenceOfInteger from TColStd, - Box2d from Bnd, - Lin from gp, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt from TColgp, - HArray1OfPnt from TColgp, - HArray1OfPnt2d from TColgp, - HArray1OfSequenceOfInteger from MeshVS, - XY from gp - -is - Create( Owner : EntityOwner from SelectBasics; - Nodes : Array1OfPnt from TColgp; - Topo : HArray1OfSequenceOfInteger from MeshVS ) returns SensitivePolyhedron from MeshVS; - - Project( me:mutable; aProjector: Projector from Select3D ) is redefined; - - GetConnected( me:mutable; aLocation: Location from TopLoc ) returns SensitiveEntity from Select3D - is redefined; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined; - - Matches( me : mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol : Real from Standard ) returns Boolean from Standard is redefined; - - Matches( me : mutable; - Polyline : Array1OfPnt2d from TColgp; - aBox : Box2d from Bnd; - aTol : Real from Standard ) returns Boolean from Standard is redefined; - - GetBox2d( me; aBox : out Box2d from Bnd ) is protected; - - FindIntersection( me; NodesIndices : SequenceOfInteger from TColStd; - EyeLine : Lin from gp ) returns Real is protected; - - ComputeDepth( me; EyeLine: Lin from gp ) returns Real from Standard is virtual; - --- ComputeSize( me ) returns Real from Standard is redefined; - - Areas( me: mutable; aResult : in out ListOfBox2d from SelectBasics ) is redefined; - -fields - myNodes : HArray1OfPnt from TColgp; - myNodes2d : HArray1OfPnt2d from TColgp; - myTopo : HArray1OfSequenceOfInteger from MeshVS; - myCenter : XY from gp; - -end SensitiveEntity; - diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.cxx b/src/MeshVS/MeshVS_SensitivePolyhedron.cxx index 80c443c15b..b2013e5bb0 100644 --- a/src/MeshVS/MeshVS_SensitivePolyhedron.cxx +++ b/src/MeshVS/MeshVS_SensitivePolyhedron.cxx @@ -13,289 +13,118 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitivePolyhedron, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitivePolyhedron, Select3D_SensitiveEntity) //================================================================ // Function : Constructor MeshVS_SensitivePolyhedron // Purpose : //================================================================ -MeshVS_SensitivePolyhedron:: -MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner, - const TColgp_Array1OfPnt& Nodes, - const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo ) -: Select3D_SensitiveEntity( Owner ), - myTopo( Topo ) +MeshVS_SensitivePolyhedron::MeshVS_SensitivePolyhedron (const Handle(SelectBasics_EntityOwner)& theOwner, + const TColgp_Array1OfPnt& theNodes, + const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo) +: Select3D_SensitiveEntity (theOwner), + myTopo (theTopo) { - Standard_Integer low = Nodes.Lower(), up = Nodes.Upper(), i; + Standard_Integer aPlaneLowIdx = theTopo->Lower(); + Standard_Integer aPlaneUpIdx = theTopo->Upper(); + Standard_Integer aNodesLowerIdx = theNodes.Lower(); + myNodes = new TColgp_HArray1OfPnt (aNodesLowerIdx, theNodes.Upper()); + myCenter = gp_XYZ (0.0, 0.0, 0.0); - myNodes = new TColgp_HArray1OfPnt ( low, up ); - for( i=low; i<=up; i++ ) - myNodes->SetValue( i, Nodes.Value( i ) ); - - myNodes2d = new TColgp_HArray1OfPnt2d( low, up ); -} - -//================================================================ -// Function : Project -// Purpose : -//================================================================ -void MeshVS_SensitivePolyhedron::Project( const Handle(Select3D_Projector)& aProjector ) -{ - if( myNodes.IsNull() || myNodes2d.IsNull() ) - return; - - Standard_Integer low = myNodes->Lower(), - up = myNodes->Upper(); - - gp_Pnt pnt; - gp_Pnt2d proj; - - Standard_Boolean hasLoc = HasLocation(); - - myCenter = gp_XY( 0, 0 ); - - for( Standard_Integer i=low; i<=up; i++ ) + for (Standard_Integer aPlaneIdx = aPlaneLowIdx; aPlaneIdx <= aPlaneUpIdx; ++aPlaneIdx) { - pnt = myNodes->Value( i ); - if( !hasLoc ) - aProjector->Project( pnt, proj ); - else - aProjector->Project( pnt.Transformed( Location().Transformation() ), proj ); + Standard_Integer aVertNb = theTopo->Value (aPlaneIdx).Length(); + Handle(TColgp_HArray1OfPnt) aVertArray = new TColgp_HArray1OfPnt (0, aVertNb - 1); + for (Standard_Integer aVertIdx = 1; aVertIdx <= aVertNb; ++aVertIdx) + { + Standard_Integer aNodeIdx = theTopo->Value (aPlaneIdx).Value (aVertIdx); + const gp_Pnt& aVert = theNodes.Value (aNodeIdx + aNodesLowerIdx); + aVertArray->SetValue (aVertIdx - 1, aVert); + myNodes->SetValue (aNodeIdx + aNodesLowerIdx, aVert); + myBndBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z())); + myCenter += aVert.XYZ(); + } - myNodes2d->SetValue( i, proj.XY() ); - myCenter += proj.XY(); + myTopology.Append (aVertArray); } - myCenter /= ( up-low+1 ); + myCenter.Divide (theNodes.Length()); } //================================================================ // Function : GetConnected // Purpose : //================================================================ -Handle( Select3D_SensitiveEntity ) MeshVS_SensitivePolyhedron::GetConnected - ( const TopLoc_Location& aLocation ) +Handle(Select3D_SensitiveEntity) MeshVS_SensitivePolyhedron::GetConnected() { - Handle( MeshVS_SensitivePolyhedron ) NewEnt = new - MeshVS_SensitivePolyhedron( myOwnerId, myNodes->Array1(), myTopo ); + Handle(MeshVS_SensitivePolyhedron) aNewEnt = new + MeshVS_SensitivePolyhedron (myOwnerId, myNodes->Array1(), myTopo); - if( HasLocation() ) - NewEnt->SetLocation( Location() ); - - NewEnt->UpdateLocation( aLocation ); - - return NewEnt; + return aNewEnt; } -//================================================================ -// Function : sort -// Purpose : -//================================================================ -void sort( Standard_Real& a, Standard_Real& b ) +//======================================================================= +// function : Matches +// purpose : +//======================================================================= +Standard_Boolean MeshVS_SensitivePolyhedron::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - if( a>b ) + Standard_Real aDepthMin = RealLast(); + Standard_Real aDistToCOG = RealLast(); + + for (MeshVS_PolyhedronVertsIter aIter (myTopology); aIter.More(); aIter.Next()) { - Standard_Real temp = a; a = b; b = temp; - } -} - -//================================================================ -// Function : Matches -// Purpose : -//================================================================ -Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const SelectBasics_PickArgs& thePickArgs, - Standard_Real& /*theMatchDMin*/, - Standard_Real& theMatchDepth ) -{ - if( myNodes2d.IsNull() || myTopo.IsNull() ) - return Standard_False; - - Standard_Integer R1 = myTopo->Lower(), - R2 = myTopo->Upper(), - low = myNodes2d->Lower(); - - Standard_Real rTol = thePickArgs.Tolerance() * SensitivityFactor(); - - Standard_Boolean inside = Standard_False; - - // "odd-even" algorithm: with ray parallel axis of absciss and toward positive - for( Standard_Integer i=R1; i<=R2 && !inside; i++ ) - { - Standard_Integer intersect = 0, cur, next, C1 = 1, C2 = myTopo->Value( i ).Length(); - Standard_Real k, b, // y=kx+b -- equation of polygon's edge - x1, y1, x2, y2, xp; // auxiliary points - - for( Standard_Integer j=C1; j<=C2; j++ ) + Standard_Real aDepth = RealLast(); + if (theMgr.Overlaps (aIter.Value(), Select3D_TOS_INTERIOR, aDepth)) { - cur = myTopo->Value( i ).Value( j ); - next = myTopo->Value( i ).Value( jValue( low+cur ).X(), - y1 = myNodes2d->Value( low+cur ).Y(), - x2 = myNodes2d->Value( low+next ).X(), - y2 = myNodes2d->Value( low+next ).Y(); - - if( Abs( x2-x1 )= y1 - rTol && thePickArgs.Y() <= y2 + rTol && x1 > thePickArgs.X() - rTol ) - intersect++; - } - else - { - //inclined edge!!! - - k = ( y2-y1 ) / ( x2-x1 ); - b = y1 - k*x1; - - if( Abs( k )>Precision::Confusion() ) - { - xp = ( thePickArgs.Y() - b ) / k; // absciss of point of intersection - sort( x1, x2 ); - if( xp >= x1 && xp <= x2 && xp > thePickArgs.X() - rTol ) - intersect++; - } - } - } - inside = ( intersect%2 ) == 1; - } - - if( inside ) - { - theMatchDepth = ComputeDepth (thePickArgs.PickLine()); - - return !thePickArgs.IsClipped(theMatchDepth); - } - - return Standard_False; -} - -//================================================================ -// Function : Matches -// Purpose : -//================================================================ -Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol ) -{ - Standard_Real rTol = aTol*SensitivityFactor(); - - return myCenter.X()>=XMin-rTol && myCenter.X()<=XMax+rTol && - myCenter.Y()>=YMin-rTol && myCenter.Y()<=YMax+rTol; -} - -//================================================================ -// Function : Matches -// Purpose : -//================================================================ -Standard_Boolean MeshVS_SensitivePolyhedron::Matches - ( const TColgp_Array1OfPnt2d& Polyline, - const Bnd_Box2d& aBox, - const Standard_Real aTol ) -{ - Standard_Real Umin, Vmin, Umax, Vmax; - aBox.Get( Umin, Vmin, Umax, Vmax ); - - CSLib_Class2d aClassifier2d( Polyline, aTol, aTol, Umin, Vmin, Umax, Vmax ); - - Standard_Integer res = aClassifier2d.SiDans( myCenter ); - return( res==1 ); -} - -//================================================================ -// Function : FindIntersection -// Purpose : -//================================================================ -Standard_Real MeshVS_SensitivePolyhedron::FindIntersection - ( const TColStd_SequenceOfInteger& NodesIndices, - const gp_Lin& EyeLine) const -{ - Standard_Real val( Precision::Infinite() ); - for( Standard_Integer i=1, n=NodesIndices.Length(); i<=n; i++ ) - val = Min( val, ElCLib::Parameter( - EyeLine, myNodes->Value( myNodes->Lower()+NodesIndices.Value( i ) ) ) ); - - return val; -} - -//================================================================ -// Function : ComputeDepth -// Purpose : -//================================================================ -Standard_Real MeshVS_SensitivePolyhedron::ComputeDepth( const gp_Lin& EyeLine ) const -{ - Standard_Real val = Precision::Infinite(); - - if( !myTopo.IsNull() ) - for( Standard_Integer i=myTopo->Lower(), up=myTopo->Upper(); i<=up; i++ ) - val = Min( val, FindIntersection( myTopo->Value( i ), EyeLine ) ); - - return val; -} - -//================================================================ -// Function : ComputeSize -// Purpose : -//================================================================ -/*Standard_Real MeshVS_SensitivePolyhedron::ComputeSize() const -{ - Bnd_Box2d aBox; - GetBox2d( aBox ); - - Standard_Real aXmin, aYmin, aXmax, aYmax; - aBox.Get( aXmin, aYmin, aXmax, aYmax ); - return Abs( ( aXmax-aXmin ) * ( aYmax-aYmin ) ); -} */ - -//================================================================ -// Function : Areas -// Purpose : -//================================================================ -void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult ) -{ - Bnd_Box2d aBox; - GetBox2d( aBox ); - aResult.Append( aBox ); -} - -//================================================================ -// Function : GetBox2d -// Purpose : -//================================================================ -void MeshVS_SensitivePolyhedron::GetBox2d( Bnd_Box2d& aBox ) const -{ - aBox.SetVoid(); - - Standard_Real xmin = 0., ymin = 0., xmax = 0., ymax = 0., x, y; - Standard_Integer low = myNodes2d->Lower(), - up = myNodes2d->Upper(); - - if( !myNodes2d.IsNull() ) - { - xmin = xmax = myNodes2d->Value( low ).X(); - ymin = ymax = myNodes2d->Value( low ).Y(); - for( Standard_Integer i=low+1; i<=up; i++ ) - { - x = myNodes2d->Value( i ).X(); - y = myNodes2d->Value( i ).Y(); - if( x>xmax ) - xmax = x; - else if( xymax ) - ymax = y; - else if( yLength(); +} + +//======================================================================= +// function : BoundingBox +// purpose : +//======================================================================= +Select3D_BndBox3d MeshVS_SensitivePolyhedron::BoundingBox() +{ + return myBndBox; +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : +//======================================================================= +gp_Pnt MeshVS_SensitivePolyhedron::CenterOfGeometry() const +{ + return myCenter; } diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.hxx b/src/MeshVS/MeshVS_SensitivePolyhedron.hxx new file mode 100644 index 0000000000..fff3c4952b --- /dev/null +++ b/src/MeshVS/MeshVS_SensitivePolyhedron.hxx @@ -0,0 +1,85 @@ +// Created on: 2005-01-21 +// Created by: Alexander SOLOVYOV +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _MeshVS_SensitivePolyhedron_HeaderFile +#define _MeshVS_SensitivePolyhedron_HeaderFile + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TColgp_HArray1OfPnt; +class TColgp_HArray1OfPnt2d; +class MeshVS_HArray1OfSequenceOfInteger; +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; +class Select3D_SensitiveEntity; +class TopLoc_Location; +class TColgp_Array1OfPnt2d; +class Bnd_Box2d; +class TColStd_SequenceOfInteger; +class gp_Lin; +class SelectBasics_ListOfBox2d; + +typedef NCollection_List MeshVS_PolyhedronVerts; +typedef NCollection_List::Iterator MeshVS_PolyhedronVertsIter; + +//! This class is used to detect selection of a polyhedron. The main +//! principle of detection algorithm is to search for overlap with +//! each polyhedron's face separately, treating them as planar convex +//! polygons. +class MeshVS_SensitivePolyhedron : public Select3D_SensitiveEntity +{ +public: + + Standard_EXPORT MeshVS_SensitivePolyhedron (const Handle(SelectBasics_EntityOwner)& theOwner, + const TColgp_Array1OfPnt& theNodes, + const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo); + + Standard_EXPORT virtual Handle_Select3D_SensitiveEntity GetConnected() Standard_OVERRIDE; + + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the amount of nodes of polyhedron + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(MeshVS_SensitivePolyhedron) + +private: + + MeshVS_PolyhedronVerts myTopology; + gp_XYZ myCenter; + Select3D_BndBox3d myBndBox; + Handle(TColgp_HArray1OfPnt) myNodes; + Handle(MeshVS_HArray1OfSequenceOfInteger) myTopo; +}; + +DEFINE_STANDARD_HANDLE(MeshVS_SensitivePolyhedron, Select3D_SensitiveEntity) + +#endif // _MeshVS_SensitivePolyhedron_HeaderFile diff --git a/src/MeshVS/MeshVS_SensitiveSegment.cdl b/src/MeshVS/MeshVS_SensitiveSegment.cdl deleted file mode 100644 index 917cf03e9b..0000000000 --- a/src/MeshVS/MeshVS_SensitiveSegment.cdl +++ /dev/null @@ -1,53 +0,0 @@ --- Created on: 2003-09-29 --- Created by: Alexander SOLOVYOV and Sergey LITONIN --- Copyright (c) 2003-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveSegment from MeshVS inherits SensitiveSegment from Select3D - - ---Purpose: This class provides custom sensitive face, which will be selected if it center is in rectangle. - -uses - EntityOwner from SelectBasics, - - Array1OfPnt from TColgp, - - TypeOfSensitivity from Select3D, - Projector from Select3D, - - Pnt from gp, - Pnt2d from gp, - - Array1OfPnt2d from TColgp, - - Box2d from Bnd - -is - - Create ( theOwner : EntityOwner from SelectBasics; - theFirstP, theLastP : Pnt from gp; - theMaxRect : Integer = 1 ) returns SensitiveSegment from MeshVS; - - Project( me: mutable; aProjector : Projector from Select3D ) is redefined; - - Matches ( me: mutable; XMin, YMin, XMax, YMax: Real; - aTol: Real ) returns Boolean is redefined; - - Matches ( me: mutable; Polyline: Array1OfPnt2d from TColgp; - aBox: Box2d; aTol: Real ) returns Boolean is redefined; - -fields - myCentre : Pnt from gp is protected; - myProjCentre : Pnt2d from gp is protected; - -end SensitiveSegment; diff --git a/src/MeshVS/MeshVS_SensitiveSegment.cxx b/src/MeshVS/MeshVS_SensitiveSegment.cxx index 804fb72420..52978438e9 100644 --- a/src/MeshVS/MeshVS_SensitiveSegment.cxx +++ b/src/MeshVS/MeshVS_SensitiveSegment.cxx @@ -13,66 +13,19 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include -#include -#include -#include +#include + +#include + +IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveSegment, Select3D_SensitiveSegment) +IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveSegment, Select3D_SensitiveSegment) //======================================================================= // name : MeshVS_SensitiveSegment::MeshVS_SensitiveSegment // Purpose : //======================================================================= -MeshVS_SensitiveSegment::MeshVS_SensitiveSegment ( - const Handle(SelectBasics_EntityOwner)& theOwnerId, - const gp_Pnt& theFirstP, - const gp_Pnt& theLastP, - const Standard_Integer theMaxRect ) -: Select3D_SensitiveSegment( theOwnerId, theFirstP, theLastP, theMaxRect ) -{ - myCentre.SetXYZ( ( theFirstP.XYZ() + theLastP.XYZ() ) / 2 ); -} - -//======================================================================= -// name : MeshVS_SensitiveSegment::Project -// Purpose : -//======================================================================= -void MeshVS_SensitiveSegment::Project( const Handle(Select3D_Projector)& aProj ) -{ - Select3D_SensitiveSegment::Project( aProj ); - if ( HasLocation() ) - aProj->Project( myCentre.Transformed( Location().Transformation() ), myProjCentre ); - else - aProj->Project( myCentre, myProjCentre ); -} - -//======================================================================= -// name : MeshVS_SensitiveSegment::Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveSegment::Matches( const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol ) -{ - Bnd_Box2d aBox; - aBox.Update( XMin-aTol, YMin-aTol, XMax+aTol, YMax+aTol ); - return !aBox.IsOut( myProjCentre ); -} - -//======================================================================= -// name : MeshVS_SensitiveSegment::Matches -// Purpose : -//======================================================================= -Standard_Boolean MeshVS_SensitiveSegment::Matches( const TColgp_Array1OfPnt2d& Polyline, - const Bnd_Box2d& aBox, - const Standard_Real aTol ) -{ - Standard_Real Umin, Vmin, Umax, Vmax; - aBox.Get ( Umin,Vmin,Umax,Vmax ); - CSLib_Class2d aClassifier2d( Polyline, aTol, aTol, Umin, Vmin, Umax, Vmax ); - Standard_Integer aRes = aClassifier2d.SiDans( myProjCentre ); - - return ( aRes == 1) ; -} +MeshVS_SensitiveSegment::MeshVS_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const gp_Pnt& theFirstPnt, + const gp_Pnt& theLastPnt) +: Select3D_SensitiveSegment (theOwnerId, theFirstPnt, theLastPnt) +{} diff --git a/src/MeshVS/MeshVS_SensitiveSegment.hxx b/src/MeshVS/MeshVS_SensitiveSegment.hxx new file mode 100644 index 0000000000..d28137adc2 --- /dev/null +++ b/src/MeshVS/MeshVS_SensitiveSegment.hxx @@ -0,0 +1,44 @@ +// Created on: 2003-09-29 +// Created by: Alexander SOLOVYOV and Sergey LITONIN +// Copyright (c) 2003-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _MeshVS_SensitiveSegment_HeaderFile +#define _MeshVS_SensitiveSegment_HeaderFile + +#include +#include + +#include +#include +#include + +class SelectBasics_EntityOwner; +class gp_Pnt; + + +//! This class provides custom sensitive face, which will be selected if it center is in rectangle. +class MeshVS_SensitiveSegment : public Select3D_SensitiveSegment +{ +public: + + Standard_EXPORT MeshVS_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwner, + const gp_Pnt& theFirstPnt, + const gp_Pnt& theLastPnt); + + DEFINE_STANDARD_RTTI(MeshVS_SensitiveSegment) +}; + +DEFINE_STANDARD_HANDLE(MeshVS_SensitiveSegment, Select3D_SensitiveSegment) + +#endif // _MeshVS_SensitiveSegment_HeaderFile diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cdl b/src/PrsMgr/PrsMgr_PresentableObject.cdl index c3c4b3b40d..3dbfeb4921 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.cdl +++ b/src/PrsMgr/PrsMgr_PresentableObject.cdl @@ -234,6 +234,10 @@ is Transformation(me) returns any Trsf from gp; ---C++: inline ---C++: return const& + + InversedTransformation(me) returns any Trsf from gp; + ---C++: inline + ---C++: return const& ResetTransformation(me:mutable) is virtual; ---Purpose: resets local transformation to identity. @@ -330,6 +334,7 @@ fields myLocalTransformation : Trsf from gp; -- Own transformation of presentable object. myTransformation : Trsf from gp; -- Combined transformation of presentable object. + myInvTransformation : Trsf from gp; -- Inverted combined transformation of presentable object. myCombinedParentTransform : Trsf from gp; -- Combined transformation of presentable object excepting local transformation. myChildren : ListOfPresentableObjects from PrsMgr; -- Child objects in scene hierarchy. diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cxx b/src/PrsMgr/PrsMgr_PresentableObject.cxx index be68dd8920..d21b6588d9 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.cxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.cxx @@ -269,6 +269,7 @@ void PrsMgr_PresentableObject::SetCombinedParentTransform (const gp_Trsf& theTra void PrsMgr_PresentableObject::UpdateTransformation() { myTransformation = myCombinedParentTransform * myLocalTransformation; + myInvTransformation = myTransformation.Inverted(); Handle(Geom_Transformation) aTrsf = new Geom_Transformation (myTransformation); for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter) diff --git a/src/PrsMgr/PrsMgr_PresentableObject.lxx b/src/PrsMgr/PrsMgr_PresentableObject.lxx index 86f34921ae..7beaf60f8e 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.lxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.lxx @@ -28,6 +28,11 @@ inline const gp_Trsf& PrsMgr_PresentableObject::Transformation() const return myTransformation; } +inline const gp_Trsf& PrsMgr_PresentableObject::InversedTransformation() const +{ + return myInvTransformation; +} + inline const PrsMgr_ListOfPresentableObjects& PrsMgr_PresentableObject::Children() const { return myChildren; diff --git a/src/QABugs/QABugs_11.cxx b/src/QABugs/QABugs_11.cxx index 568d41d722..31b2467c5d 100644 --- a/src/QABugs/QABugs_11.cxx +++ b/src/QABugs/QABugs_11.cxx @@ -5270,7 +5270,7 @@ Standard_Integer CR23234 (Draw_Interpretor& di, Standard_Integer argc, const cha aisContext->OpenLocalContext(); //aisContext->ActivateStandardMode(TopAbs_ShapeEnum::TopAbs_EDGE); aisContext->ActivateStandardMode(TopAbs_EDGE); - aisContext->SetSensitivity(8); + aisContext->SetPixelTolerance(8); return 0; //TCL_OK } diff --git a/src/QABugs/QABugs_9.cxx b/src/QABugs/QABugs_9.cxx index 37dd2223af..3ee165ddfa 100644 --- a/src/QABugs/QABugs_9.cxx +++ b/src/QABugs/QABugs_9.cxx @@ -117,7 +117,7 @@ static Standard_Integer OCC137 (Draw_Interpretor& di, Standard_Integer argc, con const Handle(SelectMgr_Selection)& aSelection = AISObj->Selection(4); if(!aSelection.IsNull()) { for(aSelection->Init();aSelection->More();aSelection->Next()) { - Handle(StdSelect_BRepOwner) aO = Handle(StdSelect_BRepOwner)::DownCast(aSelection->Sensitive()->OwnerId()); + Handle(StdSelect_BRepOwner) aO = Handle(StdSelect_BRepOwner)::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId()); aO->SetHilightMode(Draw::Atoi(argv[1])); } } diff --git a/src/QABugs/QABugs_MyText.cdl b/src/QABugs/QABugs_MyText.cdl index 9176177f63..4b2131d1c5 100644 --- a/src/QABugs/QABugs_MyText.cdl +++ b/src/QABugs/QABugs_MyText.cdl @@ -20,16 +20,12 @@ uses PresentationManager3d from PrsMgr, Presentation from Prs3d, NameOfColor from Quantity, - Selection from SelectMgr + Selection from SelectMgr is Create(aText :ExtendedString from TCollection;aPosition : Pnt from gp) returns MyText from QABugs; Create(aText :ExtendedString from TCollection;aPosition : Pnt from gp;aFont : CString from Standard; aColor : NameOfColor from Quantity; aHeight :Real from Standard) returns MyText from QABugs; - - NbPossibleSelection(me) - returns Integer from Standard - is redefined virtual protected; Compute(me:mutable; aPresentationManager: PresentationManager3d from PrsMgr; diff --git a/src/QABugs/QABugs_MyText.cxx b/src/QABugs/QABugs_MyText.cxx index c1f5bf8de5..20f5c8f898 100644 --- a/src/QABugs/QABugs_MyText.cxx +++ b/src/QABugs/QABugs_MyText.cxx @@ -77,10 +77,3 @@ void QABugs_MyText::ComputeSelection(const Handle(SelectMgr_Selection)& aSelecti myPosition.Z() + 20); aSelection->Add(box); } - - -Standard_Integer QABugs_MyText::NbPossibleSelection() const -{ - return 1; -} - diff --git a/src/Select3D/FILES b/src/Select3D/FILES index 866330edfb..9ca3ccf929 100755 --- a/src/Select3D/FILES +++ b/src/Select3D/FILES @@ -1,5 +1,43 @@ Select3D_Pnt.hxx -Select3D_Pnt2d.hxx -Select3D_Box2d.hxx Select3D_Macro.hxx -Select3D_PointData.hxx \ No newline at end of file +Select3D_PointData.hxx +Select3D_BoundarySensitivePointSet.hxx +Select3D_BoundarySensitivePointSet.cxx +Select3D_BndBox3d.hxx +Select3D_BVHPrimitiveContent.hxx +Select3D_BVHPrimitiveContent.cxx +Select3D_InteriorSensitivePointSet.hxx +Select3D_InteriorSensitivePointSet.cxx +Select3D_ISensitivePointSet.hxx +Select3D_EntitySequence.hxx +Select3D_SensitiveBox.hxx +Select3D_SensitiveBox.cxx +Select3D_SensitiveCircle.hxx +Select3D_SensitiveCircle.cxx +Select3D_SensitiveCurve.hxx +Select3D_SensitiveCurve.cxx +Select3D_SensitiveEntity.hxx +Select3D_SensitiveEntity.cxx +Select3D_SensitiveFace.hxx +Select3D_SensitiveFace.cxx +Select3D_SensitiveGroup.hxx +Select3D_SensitiveGroup.cxx +Select3D_SensitiveGroup.lxx +Select3D_SensitivePoint.hxx +Select3D_SensitivePoint.cxx +Select3D_SensitivePoly.hxx +Select3D_SensitivePoly.cxx +Select3D_SensitivePoly.lxx +Select3D_SensitiveSegment.hxx +Select3D_SensitiveSegment.cxx +Select3D_SensitiveSegment.lxx +Select3D_SensitiveSet.hxx +Select3D_SensitiveSet.cxx +Select3D_SensitiveTriangle.hxx +Select3D_SensitiveTriangle.cxx +Select3D_SensitiveTriangulation.hxx +Select3D_SensitiveTriangulation.cxx +Select3D_SensitiveTriangulation.lxx +Select3D_SensitiveWire.hxx +Select3D_SensitiveWire.cxx +Select3D_TypeOfSensitivity.hxx diff --git a/src/Select3D/Select3D.cdl b/src/Select3D/Select3D.cdl index 840afa51f7..981d712d9c 100644 --- a/src/Select3D/Select3D.cdl +++ b/src/Select3D/Select3D.cdl @@ -37,60 +37,34 @@ uses TopLoc, Geom, SelectBasics, + SelectMgr, V3d, Graphic3d is - - ---Category: sensitive entities - - enumeration TypeOfSensitivity is TOS_INTERIOR,TOS_BOUNDARY - end TypeOfSensitivity; - ---Purpose: Provides values for type of sensitivity in 3D. - -- These are used to specify whether it is the interior, - -- the boundary, or the exterior of a 3D sensitive entity which is sensitive. - - deferred class SensitiveEntity; - - deferred class SensitivePoly; - - class SensitivePoint; - - class SensitiveSegment; - - class SensitiveCircle; - - class SensitiveCurve; - - class SensitiveTriangle; - - class SensitiveTriangulation; - - class SensitiveFace; - - class SensitiveBox; - - class SensitiveWire; - - class SensitiveGroup; - - class SensitiveEntitySequence instantiates Sequence from TCollection - (SensitiveEntity from Select3D); - - ---Category: selectors/projectors - - class Projector; - - - class ListOfSensitiveTriangle instantiates List from TCollection - (SensitiveTriangle from Select3D); - - class ListOfSensitive instantiates List from TCollection - (SensitiveEntity from Select3D); + imported BndBox3d; + imported BoundarySensitivePointSet; + imported BVHPrimitiveContent; + imported InteriorSensitivePointSet; + imported ISensitivePointSet; + imported EntitySequence; imported Pnt; - imported Pnt2d; - imported Box2d; imported PointData; + imported SelectingVolumeManager; + imported SensitiveBox; + imported SensitiveCircle; + imported SensitiveCurve; + imported transient class SensitiveEntity; + imported SensitiveFace; + imported SensitiveGroup; + imported SensitivePoint; + imported SensitivePoly; + imported SensitiveSegment; + imported SensitiveSet; + imported SensitiveTriangle; + imported SensitiveTriangulation; + imported SensitiveWire; + imported TypeOfSensitivity; end Select3D; diff --git a/src/Select3D/Select3D_BVHPrimitiveContent.cxx b/src/Select3D/Select3D_BVHPrimitiveContent.cxx new file mode 100644 index 0000000000..61aaec5301 --- /dev/null +++ b/src/Select3D/Select3D_BVHPrimitiveContent.cxx @@ -0,0 +1,80 @@ +// Created on: 2014-05-30 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +//======================================================================= +// function : Select3D_BVHPrimitiveContent +// purpose : Initializes new linear BVH builder for the set of sensitives +// theSensitiveSet given +//======================================================================= +Select3D_BVHPrimitiveContent::Select3D_BVHPrimitiveContent (const Handle(Select3D_SensitiveSet)& theSensitiveSet) +{ + mySensitiveSet = theSensitiveSet; + myBuilder = new BVH_LinearBuilder (8, 32); + + MarkDirty(); +} + +//======================================================================= +// function : Size +// purpose : Returns the length of set of sensitives +//======================================================================= +Standard_Integer Select3D_BVHPrimitiveContent::Size() const +{ + return mySensitiveSet->Size(); +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of sensitive with index theIdx +//======================================================================= +Select3D_BndBox3d Select3D_BVHPrimitiveContent::Box (const Standard_Integer theIdx) const +{ + return mySensitiveSet->Box (theIdx); +} + +//======================================================================= +// function : Center +// purpose : Returns center of sensitive with index theIdx in the set +// along the given axis theAxis +//======================================================================= +Standard_Real Select3D_BVHPrimitiveContent::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + return mySensitiveSet->Center (theIdx, theAxis); +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 in the set +//======================================================================= +void Select3D_BVHPrimitiveContent::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + mySensitiveSet->Swap (theIdx1, theIdx2); +} + +//======================================================================= +// function : GetBVH +// purpose : Returns the tree built for set of sensitives +//======================================================================= +const NCollection_Handle >& Select3D_BVHPrimitiveContent::GetBVH() +{ + return BVH(); +} diff --git a/src/Select3D/Select3D_BVHPrimitiveContent.hxx b/src/Select3D/Select3D_BVHPrimitiveContent.hxx new file mode 100644 index 0000000000..210c43686c --- /dev/null +++ b/src/Select3D/Select3D_BVHPrimitiveContent.hxx @@ -0,0 +1,57 @@ +// Created on: 2014-05-30 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_BVHPrimitiveContent_Header +#define _Select3D_BVHPrimitiveContent_Header + +#include + +class Select3D_SensitiveSet; + +//! The purpose of this class is to provide a link between BVH_PrimitiveSet +//! and Select3D_SensitiveSet instance to build BVH tree for set of sensitives +class Select3D_BVHPrimitiveContent : public BVH_PrimitiveSet +{ +public: + + //! Initializes new linear BVH builder for the set of sensitives + //! theSensitiveSet given + Select3D_BVHPrimitiveContent (const Handle(Select3D_SensitiveSet)& theSensitiveSet); + + ~Select3D_BVHPrimitiveContent() {}; + + //! Returns the length of set of sensitives + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns bounding box of sensitive with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns center of sensitive with index theIdx in the set along the + //! given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in the set + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Returns the tree built for set of sensitives + Standard_EXPORT const NCollection_Handle >& GetBVH(); + +protected: + Handle(Select3D_SensitiveSet) mySensitiveSet; //!< Set of sensitive entities +}; + +#endif // _Select3D_BVHPrimitiveContent_Header diff --git a/src/Select3D/Select3D_SensitiveBox.lxx b/src/Select3D/Select3D_BndBox3d.hxx similarity index 58% rename from src/Select3D/Select3D_SensitiveBox.lxx rename to src/Select3D/Select3D_BndBox3d.hxx index 2b79709c8f..0ccbf33dc3 100644 --- a/src/Select3D/Select3D_SensitiveBox.lxx +++ b/src/Select3D/Select3D_BndBox3d.hxx @@ -1,7 +1,6 @@ -// Created on: 1997-07-16 -// Created by: Robert COUBLANC -// Copyright (c) 1997-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS +// Created on: 2014-29-05 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // @@ -14,5 +13,17 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline const Bnd_Box& Select3D_SensitiveBox::Box() const -{return mybox3d;} +#ifndef _Select3D_BndBox3d_Header +#define _Select3D_BndBox3d_Header + +#include +#include + +#include + +#include + +typedef BVH_Box Select3D_BndBox3d; +typedef NCollection_Vec3 Select3D_Vec3; + +#endif // _Select3D_BndBox3d_Header diff --git a/src/Select3D/Select3D_BoundarySensitivePointSet.cxx b/src/Select3D/Select3D_BoundarySensitivePointSet.cxx new file mode 100644 index 0000000000..7a34c12189 --- /dev/null +++ b/src/Select3D/Select3D_BoundarySensitivePointSet.cxx @@ -0,0 +1,95 @@ +// Created on: 2014-11-10 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +// function : Select3D_BoundarySensitivePointSet +// purpose : Creates new instance of Select3D_SensitivePoly with BVH tree +// required and initializes it with the given array of points +//======================================================================= +Select3D_BoundarySensitivePointSet::Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId, + const TColgp_Array1OfPnt& ThePoints) + : Select3D_SensitivePoly (OwnerId, ThePoints, Standard_True) +{} + +//======================================================================= +// function : Select3D_BoundarySensitivePointSet +// purpose : Creates new instance of Select3D_SensitivePoly with BVH tree +// required and initializes it with the given array of points +//======================================================================= +Select3D_BoundarySensitivePointSet::Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId, + const Handle(TColgp_HArray1OfPnt)& ThePoints) + : Select3D_SensitivePoly (OwnerId, ThePoints, Standard_True) +{} + +//======================================================================= +// function : Matches +// purpose : Checks whether the point set overlaps current selecting +// volume +//======================================================================= +Standard_Boolean Select3D_BoundarySensitivePointSet::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) +{ + return Select3D_SensitivePoly::Matches (theMgr, thePickResult); +} + +//======================================================================= +// function : GetPoints +// purpose : Initializes the given array theHArrayOfPnt by 3d +// coordinates of vertices of the point set +//======================================================================= +void Select3D_BoundarySensitivePointSet::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) +{ + Points3D (theHArrayOfPnt); +} + +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of the point set. If location transformation +// is set, it will be applied +//======================================================================= +Select3D_BndBox3d Select3D_BoundarySensitivePointSet::BoundingBox() +{ + return Select3D_SensitivePoly::BoundingBox(); +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the point set. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_BoundarySensitivePointSet::CenterOfGeometry() const +{ + return Select3D_SensitivePoly::CenterOfGeometry(); +} + +//======================================================================= +// function : BVH +// purpose : Builds BVH tree for the point set +//======================================================================= +void Select3D_BoundarySensitivePointSet::BVH() +{ + Select3D_SensitivePoly::BVH(); +} + +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of points in set +//======================================================================= +Standard_Integer Select3D_BoundarySensitivePointSet::NbSubElements() +{ + return Select3D_SensitivePoly::NbSubElements(); +} diff --git a/src/Select3D/Select3D_BoundarySensitivePointSet.hxx b/src/Select3D/Select3D_BoundarySensitivePointSet.hxx new file mode 100644 index 0000000000..f04c6133ad --- /dev/null +++ b/src/Select3D/Select3D_BoundarySensitivePointSet.hxx @@ -0,0 +1,67 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_BoundarySensitivePointSet_HeaderFile +#define _Select3D_BoundarySensitivePointSet_HeaderFile + +#include +#include + +#include +#include + +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; +class TColgp_HArray1OfPnt; + +//! This class handles the selection of arbitrary point set with boundary type of sensitivity. +class Select3D_BoundarySensitivePointSet : public Select3D_ISensitivePointSet, public Select3D_SensitivePoly +{ +public: + + //! Creates new instance of Select3D_SensitivePoly with BVH tree + //! required and initializes it with the given array of points + Standard_EXPORT Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId, + const TColgp_Array1OfPnt& ThePoints); + + //! Creates new instance of Select3D_SensitivePoly with BVH tree + //! required and initializes it with the given array of points + Standard_EXPORT Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId, + const Handle(TColgp_HArray1OfPnt)& ThePoints); + + //! Checks whether the point set overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Initializes the given array theHArrayOfPnt by 3d coordinates + //! of vertices of the point set + Standard_EXPORT virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) Standard_OVERRIDE; + + //! Returns bounding box of the point set. If there is a + //! location transformation set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of the point set. If there is a + //! location transformation set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Builds BVH tree for the point set + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + //! Returns the amount of points in set + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; +}; + +#endif // _Select3D_BoundarySensitivePointSet_HeaderFile diff --git a/src/Select3D/Select3D_Box2d.hxx b/src/Select3D/Select3D_Box2d.hxx deleted file mode 100644 index 79eab85194..0000000000 --- a/src/Select3D/Select3D_Box2d.hxx +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _Select3D_Box2d_HeaderFile -#define _Select3D_Box2d_HeaderFile - -#include -#include -#include - -struct Select3D_Box2d -{ - Standard_ShortReal xmin, ymin, xmax, ymax; - - Select3D_Box2d() - : xmin( ShortRealLast() ), - ymin( ShortRealLast() ), - xmax( ShortRealFirst() ), - ymax( ShortRealFirst() ) - { - } - - Select3D_Box2d(const Bnd_Box2d& theBox) - { - SetField(theBox); - } - - inline operator Bnd_Box2d() const - { - Bnd_Box2d aBox; - aBox.SetVoid(); - if( !IsVoid() ) - aBox.Update(xmin, ymin, xmax, ymax); - return aBox; - } - - inline Select3D_Box2d operator = ( const Bnd_Box2d& theBox) - { - SetField(theBox); - return *this; - } - - inline void Update(const gp_Pnt2d& thePnt) - { - Bnd_Box2d aBox; - aBox.Set(thePnt); - if( !IsVoid() ) - aBox.Update(xmin, ymin, xmax, ymax); - SetField(aBox); - } - - inline void SetVoid() - { - xmin = ymin = ShortRealLast(); - xmax = ymax = ShortRealFirst(); - } - - inline Standard_Boolean IsVoid() const - { - return ( xmin == ShortRealLast() && ymin == ShortRealLast() && xmax == ShortRealFirst() && ymax == ShortRealFirst() ); - } - -private: - inline void SetField(const Bnd_Box2d& theBox) - { - if( theBox.IsVoid() ) - SetVoid(); - else { - Standard_Real x, y, x1, y1; - theBox.Get(x, y, x1, y1); - - xmin = DToF(x); - ymin = DToF(y); - xmax = DToF(x1); - ymax = DToF(y1); - } - } - -}; - -#endif - - - - diff --git a/src/Select3D/Select3D_EntitySequence.hxx b/src/Select3D/Select3D_EntitySequence.hxx new file mode 100644 index 0000000000..68e4e3ab5e --- /dev/null +++ b/src/Select3D/Select3D_EntitySequence.hxx @@ -0,0 +1,11 @@ +#ifndef _Select3D_EntitySequence_Header +#define _Select3D_EntitySequence_Header + +#include + +class Handle(Select3D_SensitiveEntity); + +typedef NCollection_Sequence Select3D_EntitySequence; +typedef NCollection_Sequence::Iterator Select3D_EntitySequenceIter; + +#endif // _Select3D_EntitySequence_Header diff --git a/src/Select3D/Select3D_ISensitivePointSet.hxx b/src/Select3D/Select3D_ISensitivePointSet.hxx new file mode 100644 index 0000000000..7cb05642f1 --- /dev/null +++ b/src/Select3D/Select3D_ISensitivePointSet.hxx @@ -0,0 +1,70 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_ISensitivePointSet_HeaderFile +#define _Select3D_ISensitivePointSet_HeaderFile + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +class gp_Pnt; +class Standard_ConstructionError; +class Standard_OutOfRange; +class TColgp_Array1OfPnt; +class TColgp_HArray1OfPnt; +class TColgp_Array1OfPnt2d; +class TopLoc_Location; + +//! Interface class to unify the work with both internal and boundary +//! sensitive sets of points. +class Select3D_ISensitivePointSet +{ +public: + + //! Checks whether the point set overlaps current selecting volume + virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) = 0; + + //! Initializes the given array theHArrayOfPnt by 3d coordinates + //! of vertices of the point set + virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) = 0; + + //! Returns bounding box of the point set. If location + //! transformation is set, it will be applied + virtual Select3D_BndBox3d BoundingBox() = 0; + + //! Returns center of the point set. If location + //! transformation is set, it will be applied + virtual gp_Pnt CenterOfGeometry() const = 0; + + //! Builds BVH tree for the point set + virtual void BVH() = 0; + + //! Returns the amount of points in set + virtual Standard_Integer NbSubElements() = 0; +}; + +#endif // _Select3D_ISensitivePointSet_HeaderFile diff --git a/src/Select3D/Select3D_InteriorSensitivePointSet.cxx b/src/Select3D/Select3D_InteriorSensitivePointSet.cxx new file mode 100644 index 0000000000..1ea7e35d37 --- /dev/null +++ b/src/Select3D/Select3D_InteriorSensitivePointSet.cxx @@ -0,0 +1,418 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#include +#include + +#include + +// Internal class for creation of planar polygons +class Select3D_Plane +{ +public: + + Select3D_Plane() + : myPlane (0.0), + myIsInitialized (Standard_False) + {} + + Standard_Boolean Contains (const gp_Pnt& thePnt) const + { + if (!myIsInitialized) + return Standard_False; + + Standard_Real aRes = myPlane.x() * thePnt.X() + + myPlane.y() * thePnt.Y() + + myPlane.z() * thePnt.Z() + + myPlane.w(); + + if (aRes < Precision::Confusion()) + return Standard_True; + + return Standard_False; + } + + void MakePlane (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3) + { + const gp_XYZ& aVec1 = thePnt2.XYZ() - thePnt1.XYZ(); + const gp_XYZ& aVec2 = thePnt3.XYZ() - thePnt1.XYZ(); + const gp_XYZ& aDir = aVec1.Crossed (aVec2); + Standard_Real aD = aDir.Dot (thePnt1.XYZ().Reversed()); + myPlane = NCollection_Vec4 (aDir.X(), aDir.Y(), aDir.Z(), aD); + myIsInitialized = Standard_True; + } + + void Invalidate() + { + myIsInitialized = Standard_False; + } + + Standard_Boolean IsValid() const + { + return myIsInitialized; + } + +private: + NCollection_Vec4 myPlane; + Standard_Boolean myIsInitialized; +}; + +// ======================================================================= +// function : Select3D_InteriorSensitivePointSet +// purpose : Splits the given point set thePoints onto planar convex +// polygons +// ======================================================================= +Select3D_InteriorSensitivePointSet::Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints) + : Select3D_SensitiveSet (theOwnerId) +{ + Select3D_Plane aPlane; + Standard_Integer aStartIdx = 1, anEndIdx = 0; + Standard_Integer aLowerIdx = thePoints.Lower(); + Standard_Integer anUpperIdx = thePoints.Upper(); + Select3D_BndBox3d aBndBox; + gp_XYZ aPntSum (0.0, 0.0, 0.0); + if (thePoints.Length() > 3) + { + for (Standard_Integer aPntIter = aLowerIdx; aPntIter <= anUpperIdx; ++aPntIter) + { + gp_Pnt aPnt1, aPnt2; + const gp_Pnt& aPnt3 = thePoints.Value (aPntIter); + aBndBox.Add (SelectMgr_Vec3 (aPnt3.X(), aPnt3.Y(), aPnt3.Z())); + aPntSum += aPnt3.XYZ(); + if (aPntIter - aLowerIdx >= 2) + { + aPnt1 = thePoints.Value (aPntIter - 2); + aPnt2 = thePoints.Value (aPntIter - 1); + } + if (aPntIter - aStartIdx == 2 && !aPlane.IsValid()) + { + aPlane.MakePlane (aPnt1, aPnt2, aPnt3); + aStartIdx = aPntIter - 2; + anEndIdx = aPntIter; + } + else if (aPlane.IsValid()) + { + const gp_XYZ& aVec1 = aPnt1.XYZ() - aPnt2.XYZ(); + const gp_XYZ& aVec2 = aPnt3.XYZ() - aPnt2.XYZ(); + Standard_Real anAngle = aVec1.Dot (aVec2); + if (!aPlane.Contains (thePoints.Value (aPntIter)) || anAngle > Precision::Confusion()) + { + Standard_Integer anUpperBound = aPntIter - aStartIdx; + Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anUpperBound); + for (Standard_Integer aIdx = aStartIdx; aIdx <= aStartIdx + anUpperBound; ++aIdx) + { + aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx)); + } + Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId, + aPointsArray, + Standard_False); + myPlanarPolygons.Append (aPlanarPolyg); + aStartIdx = aPntIter; + anEndIdx = aPntIter; + aPlane.Invalidate(); + } + else + { + if (anEndIdx == anUpperIdx) + { + Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx); + for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx) + { + aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx)); + } + Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId, + aPointsArray, + Standard_False); + myPlanarPolygons.Append (aPlanarPolyg); + } + anEndIdx++; + } + } + } + } + else + { + Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, 2); + const gp_Pnt& aPnt1 = thePoints.Value (aLowerIdx); + const gp_Pnt& aPnt2 = thePoints.Value (aLowerIdx + 1); + const gp_Pnt& aPnt3 = thePoints.Value (aLowerIdx + 2); + aPointsArray->SetValue (0, aPnt1); + aPointsArray->SetValue (1, aPnt2); + aPointsArray->SetValue (2, aPnt3); + aBndBox.Add (SelectMgr_Vec3 (aPnt1.X(), aPnt1.Y(), aPnt1.Z())); + aBndBox.Add (SelectMgr_Vec3 (aPnt2.X(), aPnt2.Y(), aPnt2.Z())); + aBndBox.Add (SelectMgr_Vec3 (aPnt3.X(), aPnt3.Y(), aPnt3.Z())); + aPntSum += aPnt1.XYZ() + aPnt2.XYZ() + aPnt3.XYZ(); + Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId, + aPointsArray, + Standard_False); + myPlanarPolygons.Append (aPlanarPolyg); + } + + myPolygonsIdxs = new TColStd_HArray1OfInteger (0, myPlanarPolygons.Length() - 1); + for (Standard_Integer aIdx = 0; aIdx < myPlanarPolygons.Length(); ++aIdx) + { + myPolygonsIdxs->SetValue (aIdx, aIdx); + } + + myCOG = aPntSum / thePoints.Length(); + myBndBox = aBndBox; +} + +// ======================================================================= +// function : Select3D_InteriorSensitivePointSet +// purpose : Splits the given point set thePoints onto planar convex +// polygons +// ======================================================================= +Select3D_InteriorSensitivePointSet::Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints) + : Select3D_SensitiveSet (theOwnerId) +{ + Select3D_Plane aPlane; + Standard_Integer aLowerIdx = thePoints->Lower(); + Standard_Integer anUpperIdx = thePoints->Upper(); + Standard_Integer aStartIdx = aLowerIdx, anEndIdx = 0; + Select3D_BndBox3d aBndBox; + gp_XYZ aPntSum (0.0, 0.0, 0.0); + for (Standard_Integer aPntIter = aLowerIdx; aPntIter <= anUpperIdx; ++aPntIter) + { + gp_Pnt aPnt1, aPnt2; + const gp_Pnt& aPnt3 = thePoints->Value (aPntIter); + aPntSum += aPnt3.XYZ(); + SelectMgr_Vec3 aCurrPnt (aPnt3.X(), aPnt3.Y(), aPnt3.Z()); + aBndBox.Add (aCurrPnt); + if (aPntIter - aLowerIdx >= 2) + { + aPnt1 = thePoints->Value (aPntIter - 2); + aPnt2 = thePoints->Value (aPntIter - 1); + } + if (aPntIter - aStartIdx == 2 && !aPlane.IsValid()) + { + aPlane.MakePlane (aPnt1, aPnt2, aPnt3); + aStartIdx = aPntIter - 2; + anEndIdx = aPntIter; + } + else if (aPlane.IsValid()) + { + const gp_XYZ& aVec1 = aPnt1.XYZ() - aPnt2.XYZ(); + const gp_XYZ& aVec2 = aPnt3.XYZ() - aPnt2.XYZ(); + Standard_Real anAngle = aVec1.Dot (aVec2); + if (!aPlane.Contains (thePoints->Value (aPntIter)) || anAngle > Precision::Confusion()) + { + Standard_Integer anUpperBound = aPntIter - aStartIdx; + Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anUpperBound); + for (Standard_Integer aIdx = aStartIdx; aIdx <= aStartIdx + anUpperBound; ++aIdx) + { + aPointsArray->SetValue (aIdx - aStartIdx, thePoints->Value (aIdx)); + } + Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId, + aPointsArray, + Standard_False); + myPlanarPolygons.Append (aPlanarPolyg); + aStartIdx = aPntIter; + anEndIdx = aPntIter; + aPlane.Invalidate(); + } + else + { + anEndIdx++; + if (anEndIdx == anUpperIdx) + { + Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx); + for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx) + { + aPointsArray->SetValue (aIdx - aStartIdx, thePoints->Value (aIdx)); + } + Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId, + aPointsArray, + Standard_False); + myPlanarPolygons.Append (aPlanarPolyg); + } + } + } + } + + myPolygonsIdxs = new TColStd_HArray1OfInteger (0, myPlanarPolygons.Length() - 1); + for (Standard_Integer aIdx = 0; aIdx < myPlanarPolygons.Length(); ++aIdx) + { + myPolygonsIdxs->SetValue (aIdx, aIdx); + } + + myCOG = aPntSum / thePoints->Length(); + myBndBox = aBndBox; +} + +// ======================================================================= +// function : Matches +// purpose : Checks whether the point set overlaps current selecting +// volume +// ======================================================================= +Standard_Boolean Select3D_InteriorSensitivePointSet::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) +{ + return Select3D_SensitiveSet::Matches (theMgr, thePickResult); +} + +// ======================================================================= +// function : GetPoints +// purpose : Initializes the given array theHArrayOfPnt by 3d +// coordinates of vertices of the whole point set +// ======================================================================= +void Select3D_InteriorSensitivePointSet::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) +{ + Standard_Integer aSize = 0; + for (Standard_Integer anIdx = 0; anIdx < myPlanarPolygons.Length(); ++anIdx) + { + const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (anIdx); + aSize += aPolygon->NbSubElements(); + } + aSize -= (myPlanarPolygons.Length() - 1) * 2; + + theHArrayOfPnt = new TColgp_HArray1OfPnt (1, aSize); + Standard_Integer anOutputPntArrayIdx = 1; + + for (Standard_Integer aPolygIdx = 0; aPolygIdx < myPlanarPolygons.Length(); ++aPolygIdx) + { + const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx); + Handle(TColgp_HArray1OfPnt) aPoints; + aPolygon->Points3D (aPoints); + Standard_Integer anUpper = aPolygIdx < myPlanarPolygons.Length() - 1 ? aPoints->Upper() : aPoints->Upper() + 1; + for (Standard_Integer aPntIter = 1; aPntIter < anUpper; ++aPntIter) + { + theHArrayOfPnt->SetValue (anOutputPntArrayIdx, aPoints->Value (aPntIter)); + anOutputPntArrayIdx++; + } + aPoints.Nullify(); + } +} + +//======================================================================= +// function : Size +// purpose : Returns the length of vector of planar convex polygons +//======================================================================= +Standard_Integer Select3D_InteriorSensitivePointSet::Size() const +{ + return myPlanarPolygons.Length(); +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of planar convex polygon with index +// theIdx +//======================================================================= +Select3D_BndBox3d Select3D_InteriorSensitivePointSet::Box (const Standard_Integer theIdx) const +{ + Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx); + return myPlanarPolygons.Value (aPolygIdx)->BoundingBox(); +} + +//======================================================================= +// function : Center +// purpose : Returns geometry center of planar convex polygon with index +// theIdx in the vector along the given axis theAxis +//======================================================================= +Standard_Real Select3D_InteriorSensitivePointSet::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx); + const gp_XYZ& aCOG = myPlanarPolygons.Value (aPolygIdx)->CenterOfGeometry().XYZ(); + Standard_Real aCenter = theAxis == 0 ? aCOG.X() : (theAxis == 1 ? aCOG.Y() : aCOG.Z()); + + return aCenter; +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector +//======================================================================= +void Select3D_InteriorSensitivePointSet::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + Standard_Integer aPolygIdx1 = myPolygonsIdxs->Value (theIdx1); + Standard_Integer aPolygIdx2 = myPolygonsIdxs->Value (theIdx2); + + myPolygonsIdxs->ChangeValue (theIdx1) = aPolygIdx2; + myPolygonsIdxs->ChangeValue (theIdx2) = aPolygIdx1; +} + +// ======================================================================= +// function : overlapsElement +// purpose : Checks whether the planar convex polygon with index theIdx +// in myPlanarPolygons overlaps the current selecting volume +// ======================================================================= +Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) +{ + Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theElemIdx); + const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx); + Handle(TColgp_HArray1OfPnt) aPoints; + aPolygon->Points3D (aPoints); + return theMgr.Overlaps (aPoints, Select3D_TOS_INTERIOR, theMatchDepth); +} + +// ======================================================================= +// function : distanceToCOG +// purpose : Calculates distance from the 3d projection of used-picked +// screen point to center of the geometry +// ======================================================================= +Standard_Real Select3D_InteriorSensitivePointSet::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) +{ + return theMgr.DistToGeometryCenter (myCOG); +} + +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of the point set. If location +// transformation is set, it will be applied +//======================================================================= +Select3D_BndBox3d Select3D_InteriorSensitivePointSet::BoundingBox() +{ + return myBndBox; +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the point set. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_InteriorSensitivePointSet::CenterOfGeometry() const +{ + return myCOG; +} + +//======================================================================= +// function : BVH +// purpose : Builds BVH tree for the point set +//======================================================================= +void Select3D_InteriorSensitivePointSet::BVH() +{ + BVH(); +} + +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of points in set +//======================================================================= +Standard_Integer Select3D_InteriorSensitivePointSet::NbSubElements() +{ + return myPlanarPolygons.Length(); +} diff --git a/src/Select3D/Select3D_InteriorSensitivePointSet.hxx b/src/Select3D/Select3D_InteriorSensitivePointSet.hxx new file mode 100644 index 0000000000..2e1dab0ef4 --- /dev/null +++ b/src/Select3D/Select3D_InteriorSensitivePointSet.hxx @@ -0,0 +1,109 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_InteriorSensitivePointSet_HeaderFile +#define _Select3D_InteriorSensitivePointSet_HeaderFile + +#include + +#include +#include +#include + +#include +#include +#include + +class gp_Pnt; +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; +class TColgp_HArray1OfPnt; +class TColStd_HArray1OfInteger; + +typedef NCollection_Vector Select3D_VectorOfHPoly; + +//! This class handles the selection of arbitrary point set with internal type of sensitivity. +//! The main principle is to split the point set given onto planar convex polygons and search +//! for the overlap with one or more of them through traverse of BVH tree. +class Select3D_InteriorSensitivePointSet : public Select3D_ISensitivePointSet, public Select3D_SensitiveSet +{ +public: + + //! Splits the given point set thePoints onto planar convex polygons + Standard_EXPORT Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints); + + //! Splits the given point set thePoints onto planar convex polygons + Standard_EXPORT Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints); + + //! Checks whether the point set overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Initializes the given array theHArrayOfPnt by 3d coordinates of vertices of the + //! whole point set + Standard_EXPORT virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) Standard_OVERRIDE; + + //! Returns the length of vector of planar convex polygons + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns bounding box of planar convex polygon with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns geometry center of planar convex polygon with index + //! theIdx in the vector along the given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in the vector + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Returns bounding box of the point set. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of the point set. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Builds BVH tree for the point set + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + //! Returns the amount of points in set + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + +protected: + + //! Checks whether the planar convex polygon with index theIdx + //! in myPlanarPolygons overlaps the current selecting volume + Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) Standard_OVERRIDE; + + //! Calculates distance from the 3d projection of used-picked + //! screen point to center of the geometry + Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; + +protected: + + Select3D_VectorOfHPoly myPlanarPolygons; //!< Vector of planar polygons + Handle_TColStd_HArray1OfInteger myPolygonsIdxs; //!< Indexes array for BVH calculation + gp_Pnt myCOG; //!< Center of the point set + Select3D_BndBox3d myBndBox; //!< Bounding box of the point set +}; + +#endif // _Select3D_InteriorSensitivePointSet_HeaderFile diff --git a/src/Select3D/Select3D_Pnt2d.hxx b/src/Select3D/Select3D_Pnt2d.hxx deleted file mode 100644 index d8658d0f0f..0000000000 --- a/src/Select3D/Select3D_Pnt2d.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef _Select3D_Pnt2d_HeaderFile -#define _Select3D_Pnt2d_HeaderFile - -#include -#include -#include - -struct Select3D_Pnt2d{ - - Standard_ShortReal x, y; - - inline operator gp_Pnt2d() const - { - return gp_Pnt2d(x, y); - } - - inline operator gp_XY() const - { - return gp_XY(x, y); - } - - inline gp_Pnt2d operator = (const gp_Pnt2d& thePnt) - { - x = DToF(thePnt.X()); - y = DToF(thePnt.Y()); - return *this; - } - - -}; - -#endif - diff --git a/src/Select3D/Select3D_PointData.hxx b/src/Select3D/Select3D_PointData.hxx index 4773ee87fd..0193ef7a55 100644 --- a/src/Select3D/Select3D_PointData.hxx +++ b/src/Select3D/Select3D_PointData.hxx @@ -15,14 +15,13 @@ #define _Select3D_PointData_HeaderFile #include -#include -// A framework for safe management of Select3D_SensitivePoly polygons of 3D and 2D points +// A framework for safe management of Select3D_SensitivePoly polygons of 3D points class Select3D_PointData { public: - // Constructs internal arrays of 2D and 3D points defined + // Constructs internal array of 3D points defined // by number of points theNbPoints Select3D_PointData (const Standard_Integer theNbPoints) : mynbpoints(theNbPoints) @@ -31,14 +30,12 @@ public: Standard_ConstructionError::Raise("Select3D_PointData"); mypolyg3d = new Select3D_Pnt[mynbpoints]; - mypolyg2d = new Select3D_Pnt2d[mynbpoints]; } // Destructor ~Select3D_PointData () { delete [] mypolyg3d; - delete [] mypolyg2d; } // Sets Select3D_Pnt to internal array @@ -61,26 +58,6 @@ public: mypolyg3d[theIndex] = theValue; } - // Sets Select3D_Pnt2d to internal array - // of 2D points if theIndex is valid - void SetPnt2d (const Standard_Integer theIndex, - const Select3D_Pnt2d& theValue) - { - if (theIndex < 0 || theIndex >= mynbpoints) - Standard_OutOfRange::Raise("Select3D_PointData::SetPnt2d"); - mypolyg2d[theIndex] = theValue; - } - - // Sets gp_Pnt2d to internal array - // of 2D points if theIndex is valid - void SetPnt2d (const Standard_Integer theIndex, - const gp_Pnt2d& theValue) - { - if (theIndex < 0 || theIndex >= mynbpoints) - Standard_OutOfRange::Raise("Select3D_PointData::SetPnt2d"); - mypolyg2d[theIndex] = theValue; - } - // Returns 3D point from internal array // if theIndex is valid Select3D_Pnt Pnt (const Standard_Integer theIndex) const @@ -90,13 +67,13 @@ public: return mypolyg3d[theIndex]; } - // Returns 2D point from internal array + // Returns 3D point from internal array // if theIndex is valid - Select3D_Pnt2d Pnt2d (const Standard_Integer theIndex) const + gp_Pnt Pnt3d (const Standard_Integer theIndex) const { if (theIndex < 0 || theIndex >= mynbpoints) - Standard_OutOfRange::Raise("Select3D_PointData::Pnt2d"); - return mypolyg2d[theIndex]; + Standard_OutOfRange::Raise("Select3D_PointData::Pnt"); + return mypolyg3d[theIndex]; } // Returns size of internal arrays @@ -112,7 +89,6 @@ private: private: Select3D_Pnt* mypolyg3d; - Select3D_Pnt2d* mypolyg2d; Standard_Integer mynbpoints; }; diff --git a/src/Select3D/Select3D_Projector.cdl b/src/Select3D/Select3D_Projector.cdl deleted file mode 100644 index ca375983d4..0000000000 --- a/src/Select3D/Select3D_Projector.cdl +++ /dev/null @@ -1,257 +0,0 @@ --- Created on: 1992-03-12 --- Created by: Christophe MARION --- Copyright (c) 1992-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - --- copie quasi exacte de HLRAlgo_Projector - -class Projector from Select3D inherits Transient from Standard - ---Purpose: A framework to define 3D projectors. - -- Projector provides services for projecting points from - -- world-coordinates to a viewing plane. Projection could be defined by - -- corresponding transformation, or coordinate system. The transformation - -- could be constructed for a view with transposed view transformation - -- matrix ( that represents view-orientation ), including, for perspective - -- view, focal distance ( distance from an eye to the view plane ) and - -- translational part that represents translation of focal point in - -- view-coordinate space. The Select3D_Projector class recognizes the - -- predefined set of popular projections: axonometric, top view, front - -- view and uses more efficient algorithm for projection computations. - -- User-defined transformation could be also defined in constructor. - -- Perspective projection consists of two separate parts, that are - -- composed together during computation: transformation component and - -- focale distance. - -uses - Real from Standard, - Boolean from Standard, - Trsf from gp, - GTrsf from gp, - Lin from gp, - Pnt from gp, - Vec from gp, - Ax2 from gp, - Vec2d from gp, - Pnt2d from gp, - Box from Bnd, - View from V3d, - Mat4 from Graphic3d, - Mat4d from Graphic3d - -raises - NoSuchObject from Standard - -is - - Create (theView : View from V3d) returns Projector from Select3D; - --- Purpose: Constructs the 3D projector object from the passed view. - -- The projector captures current model-view and projection transformation - -- of the passed view. - - Create returns Projector from Select3D; - --- Purpose: Constructs identity projector. - - Create (theCS : Ax2 from gp) - ---Purpose: Builds the Projector from the model-view transformation specified - -- by the passed viewing coordinate system . The Projector has - -- identity projection transformation, is orthogonal. - -- The viewing coordinate system could be constructed from x direction, - -- view plane normal direction, and view point location in - -- world-coordinate space. - returns Projector from Select3D; - - Create (theCS : Ax2 from gp; - theFocus : Real from Standard) - ---Purpose: Builds the Projector from the model-view transformation specified - -- by the passed view coordinate system and simplified perspective - -- projection transformation defined by parameter. - -- The viewing coordinate system could be constructed from x direction, - -- view plane normal direction, and focal point location in world-coordinate - -- space. should represent distance of an eye from view plane - -- in world-coordinate space (focal distance). - returns Projector from Select3D; - - Create (theViewTrsf : Trsf from gp; - theIsPersp : Boolean from Standard; - theFocus : Real from Standard) - ---Purpose: Build the Projector from the model-view transformation passed - -- as and simplified perspective projection transformation - -- parameters passed as and . - -- In case, when transformation should represent custom view - -- projection, it could be constructed from two separate components: - -- transposed view orientation matrix and translation of focal point - -- in view-coordinate system. - -- could be built up from x direction, up direction, - -- view plane normal direction vectors and translation with SetValues(...) - -- method, where first row arguments (a11, a12, a13, a14) are x, y, z - -- component of x direction vector, and x value of reversed translation - -- vector. Second row arguments, are x y z for up direction and y value of - -- reversed translation, and the third row defined in the same manner. - -- This also suits for simple perspective view, where is the focale - -- distance of an eye from view plane in world-space coordinates. - -- Note, that in that case amount of perspective distortion (perspective - -- angle) should be defined through focal distance. - returns Projector from Select3D; - - Create (theViewTrsf : GTrsf from gp; - theIsPersp : Boolean from Standard; - theFocus : Real from Standard) - ---Purpose: Builds the Projector from the model-view transformation passed - -- as and projection transformation for and - -- parameters. - -- In case, when transformation should represent custom view - -- projection, it could be constructed from two separate components: - -- transposed view orientation matrix and translation of a focal point - -- in view-coordinate system. - -- This also suits for perspective view, with that could be - -- equal to distance from an eye to a view plane in - -- world-coordinates (focal distance). - -- The 3x3 transformation matrix is built up from three vectors: - -- x direction, up direction and view plane normal vectors, where each - -- vector is a matrix row. Then is constructed from matrix and - -- reversed translation with methods SetTranslationPart(..) and - -- SetVectorialPart(..). - -- Note, that in that case amount of perspective distortion (perspective - -- angle) should be defined through focal distance. - returns Projector from Select3D; - - Create (theViewTrsf : Mat4d from Graphic3d; - theProjTrsf : Mat4d from Graphic3d; - theZNear : Real from Standard = 0.0; - theZFar : Real from Standard = 10.0) - ---Purpose: Builds the Projector from the passed model-view - -- and projection transformation matrices. Parameters - -- and are passed to define view frustum depth for further projection - -- line computation using perspective projection. - returns Projector from Select3D; - - Set (me : mutable; - theViewTrsf : Trsf from gp; - theIsPersp : Boolean from Standard; - theFocus : Real from Standard); - ---Purpose: Sets new parameters for the Projector. - - Set (me : mutable; - theViewTrsf : Mat4d from Graphic3d; - theProjTrsf : Mat4d from Graphic3d; - theZNear : Real from Standard; - theZFar : Real from Standard); - ---Purpose: Sets new parameters for the Projector. - - SetView (me : mutable; - theView : View from V3d); - ---Purpose: Sets new parameters for the Projector - -- captured from the passed view. - - Scaled (me : mutable; theToCheckOptimized : Boolean from Standard = Standard_False) - ---Purpose: Pre-compute inverse transformation and ensure whether it is possible - -- to use optimized transformation for the common view-orientation type or not - -- if is TRUE. - is virtual; - - Perspective (me) returns Boolean - ---Purpose: Returns True if there is simplified perspective - -- projection approach is used. Distortion defined by Focus. - ---C++: inline - is virtual; - - Focus (me) returns Real from Standard - ---Purpose: Returns the focal length of simplified perspective - -- projection approach. Raises program error exception if the - -- the projection transformation is not specified as simplified - -- Perspective (for example, custom projection transformation is defined - -- or the orthogonal Projector is defined). - ---C++: inline - is virtual; - - Projection (me) returns Mat4d from Graphic3d; - ---Purpose: Returns projection transformation. Please note that for - -- simplified perspective projection approach, defined by Focus, the - -- returned transformation is identity. - ---C++: inline - ---C++: return const & - - Transformation (me) returns GTrsf from gp - ---Purpose: Returns the view transformation. - ---C++: inline - ---C++: return const & - is virtual; - - InvertedTransformation (me) returns GTrsf from gp - ---Purpose: Returns the inverted view transformation. - ---C++: inline - ---C++: return const & - is virtual; - - FullTransformation (me) returns Trsf from gp - ---Purpose: Returns the uniform-scaled view transformation. - ---C++: inline - ---C++: return const & - is virtual; - - Transform (me; theD : in out Vec from gp) - ---Purpose: Transforms the vector into view-coordinate space. - ---C++: inline - is virtual; - - Transform (me; thePnt : in out Pnt from gp) - ---Purpose: Transforms the point into view-coordinate space. - ---C++: inline - is virtual; - - Project (me; theP : Pnt from gp; thePout : out Pnt2d from gp) - ---Purpose: Transforms the point into view-coordinate space - -- and applies projection transformation. - is virtual; - - Project (me; theP : Pnt from gp; theX, theY, theZ : out Real from Standard) - ---Purpose: Transforms the point into view-coordinate space - -- and applies projection transformation. - is static; - - Project (me; theP : Pnt from gp; - theD1 : Vec from gp; - thePout : out Pnt2d from gp; - theD1out : out Vec2d from gp) - ---Purpose: Transforms the point and vector passed from its location - -- into view-coordinate space and applies projection transformation. - is virtual; - - Shoot (me; theX, theY : Real from Standard) returns Lin from gp - ---Purpose: Return projection line going through the 2d point - is virtual; - - Transform(me; thePnt : in out Pnt from gp; - theTrsf : GTrsf from gp) - ---C++: inline - is virtual; - - Transform(me; theLin : in out Lin from gp; - theTrsf : GTrsf from gp) - ---C++: inline - is virtual; - -fields - - myType : Integer from Standard; - myPersp : Boolean from Standard is protected; - myFocus : Real from Standard is protected; - myGTrsf : GTrsf from gp is protected; - myInvTrsf : GTrsf from gp is protected; - myScaledTrsf : Trsf from gp is protected; - myProjTrsf : Mat4d from Graphic3d is protected; - myZNear : Real from Standard is protected; - myZFar : Real from Standard is protected; - -end Projector; diff --git a/src/Select3D/Select3D_Projector.cxx b/src/Select3D/Select3D_Projector.cxx deleted file mode 100644 index f7975cb488..0000000000 --- a/src/Select3D/Select3D_Projector.cxx +++ /dev/null @@ -1,492 +0,0 @@ -// Created on: 1992-03-13 -// Created by: Christophe MARION -// Copyright (c) 1992-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - //======================================================================= - //function : TrsfType - //purpose : - //======================================================================= - static Standard_Integer TrsfType(const gp_GTrsf& theTrsf) - { - const gp_Mat& aMat = theTrsf.VectorialPart(); - if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15) - && (Abs (aMat.Value (2, 2) - 1.0) < 1e-15) - && (Abs (aMat.Value (3, 3) - 1.0) < 1e-15)) - { - return 1; // top - } - else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (1, 2) + 0.5) < 1e-15) - && (Abs (aMat.Value (1, 3) - 0.5) < 1e-15) - && (Abs (aMat.Value (2, 1) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15) - && (Abs (aMat.Value (2, 3) + 0.5) < 1e-15) - && (Abs (aMat.Value (3, 1)) < 1e-15) - && (Abs (aMat.Value (3, 2) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15)) - { - return 0; // inverse axo - } - else if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15) - && (Abs (aMat.Value (2, 3) - 1.0) < 1e-15) - && (Abs (aMat.Value (3, 2) + 1.0) < 1e-15)) - { - return 2; // front - } - else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (1, 2) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (1, 3)) < 1e-15) - && (Abs (aMat.Value (2, 1) + 0.5) < 1e-15) - && (Abs (aMat.Value (2, 2) - 0.5) < 1e-15) - && (Abs (aMat.Value (2, 3) - 0.7071067811865476) < 1e-15) - && (Abs (aMat.Value (3, 1) - 0.5) < 1e-15) - && (Abs (aMat.Value (3, 2) + 0.5) < 1e-15) - && (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15)) - { - return 3; // axo - } - - return -1; - } - - //====== TYPE 0 (inverse axonometric) - // (0.7071067811865476, -0.5 , 0.4999999999999999) - // (0.7071067811865475, 0.5000000000000001, -0.5 ) - // (0.0, 0.7071067811865475, 0.7071067811865476) - - // ====== TYPE 1 (top) - // (1.0, 0.0, 0.0) - // (0.0, 1.0, 0.0) - // (0.0, 0.0, 1.0) - - // ======= TYPE 2 (front) - // (1.0, 0.0 , 0.0) - // (0.0, 1.110223024625157e-16 , 1.0) - // (0.0, -1.0 , 1.110223024625157e-16) - - // ======= TYPE 3 (axonometric) - // ( 0.7071067811865476, 0.7071067811865475, 0.0) - // (-0.5 , 0.5000000000000001, 0.7071067811865475) - // ( 0.4999999999999999, -0.5 , 0.7071067811865476) -} - -// formula for derivating a perspective, from Mathematica - -// X'[t] X[t] Z'[t] -// D1 = -------- + ------------- -// Z[t] Z[t] 2 -// 1 - ---- f (1 - ----) -// f f - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const Handle(V3d_View)& theView) -: myPersp (Standard_False), - myFocus (0.0), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - SetView (theView); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector() -: myPersp (Standard_False), - myFocus (0.0), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - Scaled(); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS) -: myPersp (Standard_False), - myFocus (0.0), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - myScaledTrsf.SetTransformation (theCS); - myGTrsf.SetTrsf (myScaledTrsf); - Scaled(); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS, const Standard_Real theFocus) -: myPersp (Standard_True), - myFocus (theFocus), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - myScaledTrsf.SetTransformation (theCS); - myGTrsf.SetTrsf (myScaledTrsf); - Scaled(); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const gp_Trsf& theViewTrsf, - const Standard_Boolean theIsPersp, - const Standard_Real theFocus) -: myPersp (theIsPersp), - myFocus (theFocus), - myGTrsf (theViewTrsf), - myScaledTrsf (theViewTrsf), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - Scaled(); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const gp_GTrsf& theViewTrsf, - const Standard_Boolean theIsPersp, - const Standard_Real theFocus) -: myPersp (theIsPersp), - myFocus (theFocus), - myGTrsf (theViewTrsf), - myScaledTrsf (theViewTrsf.Trsf()), - myZNear (0.0), - myZFar (10.0), - myType (-1) -{ - Scaled(); -} - -//======================================================================= -//function : Select3D_Projector -//purpose : -//======================================================================= -Select3D_Projector::Select3D_Projector (const Graphic3d_Mat4d& theViewTrsf, - const Graphic3d_Mat4d& theProjTrsf, - const Standard_Real theZNear, - const Standard_Real theZFar) -: myPersp (Standard_False), - myFocus (0.0), - myType (-1) -{ - Set (theViewTrsf, theProjTrsf, theZNear, theZFar); -} - -//======================================================================= -//function : Set -//purpose : -//======================================================================= -void Select3D_Projector::Set (const gp_Trsf& theViewTrsf, - const Standard_Boolean theIsPersp, - const Standard_Real theFocus) -{ - myPersp = theIsPersp; - myFocus = theFocus; - myScaledTrsf = theViewTrsf; - myProjTrsf.InitIdentity(); - Scaled(); -} - -//======================================================================= -//function : Set -//purpose : -//======================================================================= -void Select3D_Projector::Set (const Graphic3d_Mat4d& theViewTrsf, - const Graphic3d_Mat4d& theProjTrsf, - const Standard_Real theZNear, - const Standard_Real theZFar) -{ - // Copy elements corresponding to common view-transformation - for (Standard_Integer aRowIt = 0; aRowIt < 3; ++aRowIt) - { - for (Standard_Integer aColIt = 0; aColIt < 4; ++aColIt) - { - myGTrsf.SetValue (aRowIt + 1, aColIt + 1, theViewTrsf.GetValue (aRowIt, aColIt)); - } - } - - // Adapt scaled transformation for compatibilty - gp_Dir aViewY (theViewTrsf.GetValue (0, 1), theViewTrsf.GetValue (1, 1), theViewTrsf.GetValue (2, 1)); - gp_Dir aViewZ (theViewTrsf.GetValue (0, 2), theViewTrsf.GetValue (1, 2), theViewTrsf.GetValue (2, 2)); - gp_XYZ aViewT (theViewTrsf.GetValue (0, 3), theViewTrsf.GetValue (1, 3), theViewTrsf.GetValue (2, 3)); - gp_Dir aViewX = aViewY ^ aViewZ; - gp_Ax3 aViewAx3 (gp_Pnt (aViewT), aViewZ, aViewX); - myScaledTrsf.SetTransformation (aViewAx3); - - myPersp = Standard_False; - myFocus = 0.0; - myProjTrsf = theProjTrsf; - myZNear = theZNear; - myZFar = theZFar; - Scaled(); -} - -//======================================================================= -//function : SetView -//purpose : -//======================================================================= -void Select3D_Projector::SetView (const Handle(V3d_View)& theView) -{ - const Graphic3d_Mat4d& aViewTrsf = theView->Camera()->OrientationMatrix(); - const Graphic3d_Mat4d& aProjTrsf = theView->Camera()->ProjectionMatrix(); - - gp_XYZ aFrameScale = theView->Camera()->ViewDimensions(); - Graphic3d_Mat4d aScale; - aScale.ChangeValue (0, 0) = aFrameScale.X(); - aScale.ChangeValue (1, 1) = aFrameScale.Y(); - aScale.ChangeValue (2, 2) = aFrameScale.Z(); - Graphic3d_Mat4d aScaledProjTrsf = aScale * aProjTrsf; - - Set (aViewTrsf, - aScaledProjTrsf, - theView->Camera()->ZNear(), - theView->Camera()->ZFar()); -} - -//======================================================================= -//function : Scaled -//purpose : -//======================================================================= -void Select3D_Projector::Scaled (const Standard_Boolean theToCheckOptimized) -{ - myType = -1; - - if (!theToCheckOptimized && !myPersp && myProjTrsf.IsIdentity()) - { - myType = TrsfType (myGTrsf); - } - - myInvTrsf = myGTrsf.Inverted(); -} - -//======================================================================= -//function : Project -//purpose : -//======================================================================= -void Select3D_Projector::Project (const gp_Pnt& theP, gp_Pnt2d& thePout) const -{ - Standard_Real aXout = 0.0; - Standard_Real aYout = 0.0; - Standard_Real aZout = 0.0; - Project (theP, aXout, aYout, aZout); - thePout.SetCoord (aXout, aYout); -} - -//======================================================================= -//function : Project -//purpose : -//======================================================================= -void Select3D_Projector::Project (const gp_Pnt& theP, - Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const -{ - Graphic3d_Vec4d aTransformed (0.0, 0.0, 0.0, 1.0); - - // view transformation - switch (myType) - { - case 0 : // inverse axo - { - Standard_Real aX07 = theP.X() * 0.7071067811865475; - Standard_Real aY05 = theP.Y() * 0.5; - Standard_Real aZ05 = theP.Z() * 0.5; - aTransformed.x() = aX07 - aY05 + aZ05; - aTransformed.y() = aX07 + aY05 - aZ05; - aTransformed.z() = 0.7071067811865475 * (theP.Y() + theP.Z()); - break; - } - - case 1 : // top - { - aTransformed.x() = theP.X(); - aTransformed.y() = theP.Y(); - aTransformed.z() = theP.Z(); - break; - } - - case 2 : // front - { - aTransformed.x() = theP.X(); - aTransformed.y() = theP.Z(); - aTransformed.z() = -theP.Y(); - break; - } - - case 3 : // axo - { - Standard_Real aXmy05 = (theP.X() - theP.Y()) * 0.5; - Standard_Real aZ07 = theP.Z() * 0.7071067811865476; - aTransformed.x() = 0.7071067811865476 * (theP.X() + theP.Y()); - aTransformed.y() = -aXmy05 + aZ07; - aTransformed.z() = aXmy05 + aZ07; - break; - } - - default : - { - gp_Pnt aTransformPnt = theP; - Transform (aTransformPnt); - aTransformed.x() = aTransformPnt.X(); - aTransformed.y() = aTransformPnt.Y(); - aTransformed.z() = aTransformPnt.Z(); - } - } - - // projection transformation - if (myPersp) - { - // simplified perspective - Standard_Real aDistortion = 1.0 - aTransformed.z() / myFocus; - theX = aTransformed.x() / aDistortion; - theY = aTransformed.y() / aDistortion; - theZ = aTransformed.z(); - return; - } - - if (myProjTrsf.IsIdentity()) - { - // no projection transformation - theX = aTransformed.x(); - theY = aTransformed.y(); - theZ = aTransformed.z(); - return; - } - - Graphic3d_Vec4d aProjected = myProjTrsf * aTransformed; - - theX = aProjected.x() / aProjected.w(); - theY = aProjected.y() / aProjected.w(); - theZ = aProjected.z() / aProjected.w(); -} - -//======================================================================= -//function : Project -//purpose : -//======================================================================= -void Select3D_Projector::Project (const gp_Pnt& theP, - const gp_Vec& theD1, - gp_Pnt2d& thePout, - gp_Vec2d& theD1out) const -{ - // view transformation - gp_Pnt aTP = theP; - Transform (aTP); - - gp_Vec aTD1 = theD1; - Transform (aTD1); - - // projection transformation - if (myPersp) - { - // simplified perspective - Standard_Real aDist = 1.0 - aTP.Z() / myFocus; - thePout.SetCoord (aTP.X() / aDist, aTP.Y() / aDist); - theD1out.SetCoord (aTD1.X() / aDist + aTP.X() * aTD1.Z() / (myFocus * aDist * aDist), - aTD1.Y() / aDist + aTP.Y() * aTD1.Z() / (myFocus * aDist * aDist)); - return; - } - - if (myProjTrsf.IsIdentity()) - { - // no projection transformation - thePout.SetCoord (aTP.X(), aTP.Y()); - theD1out.SetCoord (aTD1.X(), aTD1.Y()); - } - - Graphic3d_Vec4d aTransformedPnt1 (aTP.X(), aTP.Y(), aTP.Z(), 1.0); - Graphic3d_Vec4d aTransformedPnt2 (aTP.X() + aTD1.X(), aTP.Y() + aTD1.Y(), aTP.Z() + aTD1.Z(), 1.0); - - Graphic3d_Vec4d aProjectedPnt1 = myProjTrsf * aTransformedPnt1; - Graphic3d_Vec4d aProjectedPnt2 = myProjTrsf * aTransformedPnt2; - - aProjectedPnt1 /= aProjectedPnt1.w(); - aProjectedPnt2 /= aProjectedPnt2.w(); - - Graphic3d_Vec4d aProjectedD1 = aProjectedPnt2 - aProjectedPnt1; - - thePout.SetCoord (aProjectedPnt1.x(), aProjectedPnt1.y()); - theD1out.SetCoord (aProjectedD1.x(), aProjectedD1.y()); -} - -//======================================================================= -//function : Shoot -//purpose : -//======================================================================= -gp_Lin Select3D_Projector::Shoot (const Standard_Real theX, const Standard_Real theY) const -{ - gp_Lin aViewLin; - - if (myPersp) - { - // simplified perspective - aViewLin = gp_Lin (gp_Pnt (0.0, 0.0, myFocus), gp_Dir (theX, theY, -myFocus)); - } - else if (myProjTrsf.IsIdentity()) - { - // no projection transformation - aViewLin = gp_Lin (gp_Pnt (theX, theY, 0.0), gp_Dir (0.0, 0.0, -1.0)); - } - else - { - // get direction of projection over the point in view space - Graphic3d_Mat4d aProjInv; - if (!myProjTrsf.Inverted (aProjInv)) - { - return gp_Lin(); - } - - Graphic3d_Vec4d aVPnt1 = aProjInv * Graphic3d_Vec4d (theX, theY, myZNear, 1.0); - Graphic3d_Vec4d aVPnt2 = aProjInv * Graphic3d_Vec4d (theX, theY, myZFar, 1.0); - aVPnt1 /= aVPnt1.w(); - aVPnt2 /= aVPnt2.w(); - - gp_Vec aViewDir (aVPnt2.x() - aVPnt1.x(), aVPnt2.y() - aVPnt1.y(), aVPnt2.z() - aVPnt1.z()); - - aViewLin = gp_Lin (gp_Pnt (aVPnt1.x(), aVPnt1.y(), aVPnt1.z()), gp_Dir (aViewDir)); - } - - // view transformation - Transform (aViewLin, myInvTrsf); - - return aViewLin; -} diff --git a/src/Select3D/Select3D_Projector.lxx b/src/Select3D/Select3D_Projector.lxx deleted file mode 100644 index f62cf41373..0000000000 --- a/src/Select3D/Select3D_Projector.lxx +++ /dev/null @@ -1,145 +0,0 @@ -// Created on: 1992-07-09 -// Created by: Christophe MARION -// Copyright (c) 1992-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include -#include - -//======================================================================= -//function : Perspective -//purpose : -//======================================================================= -inline Standard_Boolean Select3D_Projector::Perspective() const -{ - return myPersp; -} - -//======================================================================= -//function : ProjectionTransformation -//purpose : -//======================================================================= -inline const Graphic3d_Mat4d& Select3D_Projector::Projection() const -{ - return myProjTrsf; -} - -//======================================================================= -//function : Transformation -//purpose : -//======================================================================= -inline const gp_GTrsf& Select3D_Projector::Transformation() const -{ - return myGTrsf; -} - -//======================================================================= -//function : InvertedTransformation -//purpose : -//======================================================================= -inline const gp_GTrsf& Select3D_Projector::InvertedTransformation() const -{ - return myInvTrsf; -} - -//======================================================================= -//function : FullTransformation -//purpose : -//======================================================================= -inline const gp_Trsf& Select3D_Projector::FullTransformation() const -{ - return myScaledTrsf; -} - -//======================================================================= -//function : Focus -//purpose : -//======================================================================= -inline Standard_Real Select3D_Projector::Focus() const -{ - Standard_ASSERT_RAISE (myPersp, "Not a simplified Perspective."); - return myFocus; -} - -//======================================================================= -//function : Transform -//purpose : -//======================================================================= -inline void Select3D_Projector::Transform (gp_Vec& theD) const -{ - gp_XYZ aXYZ = theD.XYZ(); - - if (myGTrsf.Form() == gp_PntMirror) - { - aXYZ.Reverse(); - } - else if (myGTrsf.Form() != gp_Identity && myGTrsf.Form() != gp_Translation) - { - aXYZ.Multiply (myGTrsf.VectorialPart()); - } - - theD.SetXYZ (aXYZ); -} - -//======================================================================= -//function : Transform -//purpose : -//======================================================================= -inline void Select3D_Projector::Transform (gp_Pnt& thePnt) const -{ - Transform (thePnt, myGTrsf); -} - -//======================================================================= -//function : Transform -//purpose : -//======================================================================= -inline void Select3D_Projector::Transform (gp_Lin& theLin, const gp_GTrsf& theTrsf) const -{ - gp_Ax1 anAx1 = theLin.Position(); - gp_XYZ aXYZ = anAx1.Location().XYZ(); - theTrsf.Transforms (aXYZ); - anAx1.SetLocation (gp_Pnt (aXYZ)); - gp_Dir aDir = anAx1.Direction(); - gp_XYZ aDirXYZ = aDir.XYZ(); - - if (theTrsf.Form() == gp_PntMirror) - { - aDirXYZ.Reverse(); - } - else if (theTrsf.Form() != gp_Identity && theTrsf.Form() != gp_Translation) - { - aDirXYZ.Multiply (theTrsf.VectorialPart()); - Standard_Real aModulus = aDirXYZ.Modulus(); - aDirXYZ.Divide (aModulus); - } - - aDir.SetXYZ (aDirXYZ); - anAx1.SetDirection (aDir); - theLin.SetPosition (anAx1); -} - -//======================================================================= -//function : Transform -//purpose : -//======================================================================= -inline void Select3D_Projector::Transform (gp_Pnt& thePnt, const gp_GTrsf& theTrsf) const -{ - gp_XYZ aXYZ = thePnt.XYZ(); - theTrsf.Transforms (aXYZ); - thePnt = gp_Pnt (aXYZ); -} diff --git a/src/Select3D/Select3D_SensitiveBox.cdl b/src/Select3D/Select3D_SensitiveBox.cdl deleted file mode 100644 index e92cacba21..0000000000 --- a/src/Select3D/Select3D_SensitiveBox.cdl +++ /dev/null @@ -1,121 +0,0 @@ --- Created on: 1995-04-13 --- Created by: Robert COUBLANC --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveBox from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define selection by a sensitive box. - -uses - Pnt from gp, - Pnt2d from gp, - Box from Bnd, - Box2d from Bnd, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt2d from TColgp, - Location from TopLoc - -is - - - Create (OwnerId : EntityOwner from SelectBasics; - BoundingBox : Box from Bnd) - returns SensitiveBox; - ---Purpose: Constructs a sensitive box object defined by the - -- owner OwnerId, and the bounding box BoundingBox. - Create (OwnerId : EntityOwner from SelectBasics; - XMin,YMin,ZMin, - XMax,YMax,ZMax : Real) - returns SensitiveBox; - --- Purpose: Constructs a sensitive box object defined by the - -- owner OwnerId, and the coordinates Xmin, YMin, ZMin, XMax, YMax, ZMax. - -- Xmin, YMin and ZMin define the minimum point in - -- the front lower left hand corner of the box, - -- and XMax, YMax and ZMax define the maximum - -- point in the back upper right hand corner of the box. - - Project (me:mutable;aProjector : Projector from Select3D) - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) - is redefined static; - ---Level: Public - ---Purpose: gives the 2D boxes which represent the Box in the - -- selection process... - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean is redefined static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard; - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - Box(me) returns Box from Bnd; - ---Purpose: Returns the sensitive 3D box used at the time of construction. - ---C++: inline - ---C++: return const & - - - ProjectBox(me:mutable;aPrj: Projector from Select3D;aBox:Box from Bnd) - is static private; - -fields - - mybox3d : Box from Bnd; - mybox2d : Box2d from Bnd; - -end SensitiveBox; - - - - - - - - - - diff --git a/src/Select3D/Select3D_SensitiveBox.cxx b/src/Select3D/Select3D_SensitiveBox.cxx index 8ccf511c53..114de8ad9e 100644 --- a/src/Select3D/Select3D_SensitiveBox.cxx +++ b/src/Select3D/Select3D_SensitiveBox.cxx @@ -14,198 +14,126 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include #include #include #include #include - +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveBox, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveBox, Select3D_SensitiveEntity) //================================================== -// Function: Constructor +// Function: Select3D_SensitiveBox // Purpose : //================================================== - -Select3D_SensitiveBox::Select3D_SensitiveBox(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Bnd_Box& BBox): -Select3D_SensitiveEntity(OwnerId), -mybox3d(BBox){} - -//================================================== -// Function: Constructor -// Purpose : -//================================================== - -Select3D_SensitiveBox:: -Select3D_SensitiveBox(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real ZMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real ZMax): -Select3D_SensitiveEntity(OwnerId) +Select3D_SensitiveBox::Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Bnd_Box& theBox) +: Select3D_SensitiveEntity (theOwnerId) { - mybox3d.Update(XMin,YMin,ZMin,XMax,YMax,ZMax); + Standard_Real aXMax, aYMax, aZMax; + Standard_Real aXMin, aYMin, aZMin; + theBox.Get (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax); + myBox = Select3D_BndBox3d (SelectMgr_Vec3 (aXMin, aYMin, aZMin), + SelectMgr_Vec3 (aXMax, aYMax, aZMax)); + myCenter3d = (gp_XYZ (aXMin, aYMin, aZMin) + gp_XYZ (aXMax, aYMax, aZMax)) + * (1.0 / 2.0); } //================================================== -// Function: Project +// Function: Select3D_SensitiveBox // Purpose : //================================================== -void Select3D_SensitiveBox:: -Project(const Handle(Select3D_Projector)& aProj) +Select3D_SensitiveBox::Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Real theXMin, + const Standard_Real theYMin, + const Standard_Real theZMin, + const Standard_Real theXMax, + const Standard_Real theYMax, + const Standard_Real theZMax) +: Select3D_SensitiveEntity (theOwnerId) { - if(HasLocation()) - { - Bnd_Box B = mybox3d.Transformed(Location().Transformation()); - ProjectBox(aProj,B); - } - else - ProjectBox(aProj,mybox3d); + myBox = Select3D_BndBox3d (SelectMgr_Vec3 (theXMin, theYMin, theZMin), + SelectMgr_Vec3 (theXMax, theYMax, theZMax)); + myCenter3d = (gp_XYZ (theXMin, theYMin, theZMin) + gp_XYZ (theXMax, theYMax, theZMax)) + * (1.0 / 2.0); } -//================================================== -// Function: Areas -// Purpose : -//================================================== - -void Select3D_SensitiveBox:: -Areas(SelectBasics_ListOfBox2d& aSeq) -{ aSeq.Append(mybox2d);} +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of sub-entities in sensitive +//======================================================================= +Standard_Integer Select3D_SensitiveBox::NbSubElements() +{ + return 1; +} //======================================================================= //function : GetConnected //purpose : //======================================================================= -Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected(const TopLoc_Location& aLoc) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected() { - Handle(Select3D_SensitiveBox) NiouEnt = new Select3D_SensitiveBox(myOwnerId,mybox3d); - - if(HasLocation()) NiouEnt->SetLocation(Location()); - NiouEnt->UpdateLocation(aLoc); - return NiouEnt; + Bnd_Box aBox; + aBox.Update (myBox.CornerMin().x(), myBox.CornerMin().y(), myBox.CornerMin().z(), + myBox.CornerMax().x(), myBox.CornerMax().y(), myBox.CornerMax().z()); + Handle(Select3D_SensitiveBox) aNewEntity = new Select3D_SensitiveBox (myOwnerId, aBox); + + return aNewEntity; } -//================================================== -// Function: Matches -// Purpose : -//================================================== - -Standard_Boolean Select3D_SensitiveBox::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) +//======================================================================= +// function : Matches +// purpose : Checks whether the box overlaps current selecting volume +//======================================================================= +Standard_Boolean Select3D_SensitiveBox::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - // check that sensitive box passes by depth - Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine()); - if (thePickArgs.IsClipped (aDepth)) + Standard_Real aDepth = RealLast(); + Standard_Real aDistToCOG = RealLast(); + Standard_Boolean isMatched = theMgr.Overlaps (myBox, aDepth); + + if (isMatched) { - return Standard_False; + aDistToCOG = theMgr.DistToGeometryCenter (myCenter3d); } - theMatchDMin = 0.0; - theMatchDepth = aDepth; - return Standard_True; + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); + + return isMatched; } -//================================================== -// Function: Matches -// Purpose : -//================================================== - -Standard_Boolean Select3D_SensitiveBox:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the box. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveBox::CenterOfGeometry() const { - Bnd_Box2d BoundBox; - BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol); - return(!BoundBox.IsOut(mybox2d)); + return myCenter3d; } //======================================================================= -//function : Matches -//purpose : +// function : BoundingBox +// purpose : Returns coordinates of the box. If location transformation +// is set, it will be applied //======================================================================= - -Standard_Boolean Select3D_SensitiveBox:: -Matches (const TColgp_Array1OfPnt2d& /*aPoly*/, - const Bnd_Box2d& aBox, - const Standard_Real /*aTol*/) +Select3D_BndBox3d Select3D_SensitiveBox::BoundingBox() { - return(!aBox.IsOut(mybox2d)); + return myBox; } //======================================================================= -//function : Dump -//purpose : +// function : Box +// purpose : //======================================================================= - -void Select3D_SensitiveBox::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const +Bnd_Box Select3D_SensitiveBox::Box() const { - S<<"\tSensitiveBox 3D :\n"; - if(HasLocation()) - S<<"\t\tExisting Location"<Project(gp_Pnt(XMin,YMin,ZMin),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMax,YMin,ZMin),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMax,YMax,ZMin),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMin,YMax,ZMin),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMin,YMin,ZMax),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMax,YMin,ZMax),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMax,YMax,ZMax),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); - aPrj->Project(gp_Pnt(XMin,YMax,ZMax),curp2d); - mybox2d.Update(curp2d.X(),curp2d.Y()); -} - -//======================================================================= -//function : ComputeDepth -//purpose : -//======================================================================= - -Standard_Real Select3D_SensitiveBox::ComputeDepth(const gp_Lin& EyeLine) const -{ - Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax; - mybox3d.Get(XMin,YMin,ZMin,XMax,YMax,ZMax); - gp_Pnt PMid((XMin+XMax)/2.,(YMin+YMax)/2.,(ZMin+ZMax)/2.); - return ElCLib::Parameter(EyeLine,PMid); + return aBox; } diff --git a/src/Select3D/Select3D_SensitiveBox.hxx b/src/Select3D/Select3D_SensitiveBox.hxx new file mode 100644 index 0000000000..0692e7fee5 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveBox.hxx @@ -0,0 +1,88 @@ +// Created on: 1995-04-13 +// Created by: Robert COUBLANC +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitiveBox_HeaderFile +#define _Select3D_SensitiveBox_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class Bnd_Box; +class TopLoc_Location; + + +//! A framework to define selection by a sensitive box. +class Select3D_SensitiveBox : public Select3D_SensitiveEntity +{ +public: + + //! Constructs a sensitive box object defined by the + //! owner theOwnerId, and the box theBox. + Standard_EXPORT Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId, const Bnd_Box& theBox); + + //! Constructs a sensitive box object defined by the + //! owner theOwnerId, and the coordinates theXmin, theYMin, theZMin, theXMax, theYMax, theZMax. + //! theXmin, theYMin and theZMin define the minimum point in + //! the front lower left hand corner of the box, + //! and theXMax, theYMax and theZMax define the maximum + //! point in the back upper right hand corner of the box. + Standard_EXPORT Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Real theXMin, + const Standard_Real theYMin, + const Standard_Real theZMin, + const Standard_Real theXMax, + const Standard_Real theYMax, + const Standard_Real theZMax); + + //! Returns the amount of sub-entities in sensitive + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Checks whether the box overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + Bnd_Box Box() const; + + //! Returns center of the box. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Returns coordinates of the box. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveBox) + +private: + + Select3D_BndBox3d myBox; //!< 3d coordinates of box corners + gp_Pnt myCenter3d; //!< 3d coordinate of box's center +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveBox, Select3D_SensitiveEntity) + +#endif // _Select3D_SensitiveBox_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveCircle.cdl b/src/Select3D/Select3D_SensitiveCircle.cdl deleted file mode 100644 index a2af4fe386..0000000000 --- a/src/Select3D/Select3D_SensitiveCircle.cdl +++ /dev/null @@ -1,155 +0,0 @@ --- Created on: 1996-02-06 --- Created by: Robert COUBLANC --- Copyright (c) 1996-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveCircle from Select3D -inherits SensitivePoly from Select3D - - ---Purpose: A framework to define sensitive 3D arcs and circles. - -- In some cases this class can raise Standard_ConstructionError and - -- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. -uses - Pnt from gp, - Pnt2d from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Circle from Geom, - Array1OfPnt from TColgp, - HArray1OfPnt from TColgp, - Array1OfPnt2d from TColgp, - Box2d from Bnd, - Location from TopLoc, - Pnt from Select3D, - Pnt2d from Select3D, - Projector from Select3D, - SensitiveEntity from Select3D, - Circle from Geom - -raises - ConstructionError from Standard, - OutOfRange from Standard - -is - Create (OwnerId : EntityOwner from SelectBasics; - TheCircle : Circle from Geom; - FilledCircle : Boolean = Standard_False; - NbOfPoints : Integer = 6) - returns SensitiveCircle; - ---Level: Public - ---Purpose: Constructs the sensitive circle object defined by the - -- owner OwnerId, the circle Circle, the Boolean - -- FilledCircle and the number of points NbOfPoints. - - Create (OwnerId : EntityOwner from SelectBasics; - TheCircle : Circle from Geom; - u1 : Real ; - u2 : Real; - FilledCircle : Boolean = Standard_False; - NbOfPoints : Integer = 6) - returns SensitiveCircle; - ---Level: Public - ---Purpose: Constructs the sensitive arc object defined by the - -- owner OwnerId, the circle Circle, the parameters u1 - -- and u2, the Boolean FilledCircle and the number of points NbOfPoints. - -- u1 and u2 define the first and last points of the arc on Circle. - - Create(OwnerId : EntityOwner from SelectBasics; - apolyg3d : HArray1OfPnt from TColgp; - FilledCircle : Boolean from Standard = Standard_False) - returns SensitiveCircle; - ---Level: Internal - ---Purpose: Constructs the sensitive circle object defined by the - -- owner OwnerId, the array of triangles apolyg3d, and the Boolean FilledCircle. - -- apolyg3d is an array of consecutive triangles on the - -- circle. The triangle i+1 lies on the intersection of the - -- tangents to the circle of i and i+2. Note, that the first point of apolyg3d - -- must be equal to the last point of apolyg3d. - - Create(OwnerId : EntityOwner from SelectBasics; - apolyg3d : Array1OfPnt from TColgp; - FilledCircle : Boolean from Standard = Standard_False) - returns SensitiveCircle; - ---Purpose: Constructs the sensitive circle object defined by the - -- owner OwnerId, the array of points apolyg3d, and the Boolean FilledCircle. - -- If the length of apolyg3d is more then 1, the first point of apolyg3d - -- must be equal to the last point of apolyg3d. - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is redefined static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth (me; - thePickLine : Lin from gp; - theDetectedIndex : Integer from Standard) - returns Real from Standard; - ---Level: Public - ---Purpose: Compute depth of sensitive circle for the detected sub-part. - -- @param thePickLine [in] the picking line. - -- @param theDetectedIndex [in] index of the detected sub-part. - -- @return depth on the picking line. - - ArrayBounds(me;Low,Up:in out Integer); - - GetPoint3d(me;rank:Integer) returns Pnt from gp; - ---Level: Internal - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - GetConnected(me: mutable; theLocation : Location from TopLoc) - returns SensitiveEntity from Select3D - is redefined virtual; - ---Level: Public - ---Purpose: Returns the copy of this. - - Project(me: mutable;aProjector: Projector from Select3D) is redefined virtual; - - ComputeCenter3D(me: mutable) is private; - ---Level: Internal - ---Purpose: Computes myCenter3D as the barycenter of points from mypolyg3d - -fields - - myFillStatus : Boolean; - myCenter2D : Pnt2d from Select3D; -- used for Matches() - myCenter3D : Pnt from Select3D; -- used for Matches() - myCircle : Circle from Geom; - mystart : Real from Standard; -- used for GetConnected() - myend : Real from Standard; -- used for GetConnected() - -end SensitiveCircle; - diff --git a/src/Select3D/Select3D_SensitiveCircle.cxx b/src/Select3D/Select3D_SensitiveCircle.cxx index d7883b4ee2..53a246c097 100644 --- a/src/Select3D/Select3D_SensitiveCircle.cxx +++ b/src/Select3D/Select3D_SensitiveCircle.cxx @@ -14,43 +14,41 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// Modified Tue Apr 14 1998 by rob : fix Bug : Case of Null Radius Circle... +#include -#include -#include -#include - -#include -#include -#include #include -#include -#include +#include +#include +#include -static Standard_Integer S3D_GetCircleNBPoints(const Handle(Geom_Circle)& C, - const Standard_Integer anInputNumber) +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCircle, Select3D_SensitivePoly) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitivePoly) + +static Standard_Integer GetCircleNbPoints (const Handle(Geom_Circle)& theCircle, + const Standard_Integer theNbPnts) { // Check if number of points is invalid. - // In this case mypolyg raises Standard_ConstructionError + // In this case myPolyg raises Standard_ConstructionError // exception (look constructor bellow). - if (anInputNumber <= 0) + if (theNbPnts <= 0) return 0; - if (C->Radius()>Precision::Confusion()) - return 2*anInputNumber+1; + if (theCircle->Radius() > Precision::Confusion()) + return 2 * theNbPnts + 1; + // The radius is too small and circle degenerates into point return 1; } -static Standard_Integer S3D_GetArcNBPoints(const Handle(Geom_Circle)& C, - const Standard_Integer anInputNumber) +static Standard_Integer GetArcNbPoints (const Handle(Geom_Circle)& theCircle, + const Standard_Integer theNbPnts) { // There is no need to check number of points here. // In case of invalid number of points this method returns // -1 or smaller value. - if (C->Radius()>Precision::Confusion()) - return 2*anInputNumber-1; + if (theCircle->Radius() > Precision::Confusion()) + return 2 * theNbPnts - 1; // The radius is too small and circle degenerates into point return 1; @@ -60,53 +58,57 @@ static Standard_Integer S3D_GetArcNBPoints(const Handle(Geom_Circle)& C, //function : Select3D_SensitiveCircle (constructor) //purpose : Definition of a sensitive circle //======================================================================= - -Select3D_SensitiveCircle:: -Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Geom_Circle)& TheCircle, - const Standard_Boolean FilledCircle, - const Standard_Integer NbPoints): -Select3D_SensitivePoly(OwnerId, S3D_GetCircleNBPoints(TheCircle,NbPoints)), -myFillStatus(FilledCircle), -myCircle(TheCircle), -mystart(0), -myend(0) +Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Circle)& theCircle, + const Standard_Boolean theIsFilled, + const Standard_Integer theNbPnts) +: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)), + myCircle (theCircle), + myStart (0), + myEnd (0) { - if (mypolyg.Size() != 1) + mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + if (myPolyg.Size() != 1) { - gp_Pnt p1,p2; - gp_Vec v1; - Standard_Real ustart = TheCircle->FirstParameter(),uend = TheCircle->LastParameter(); - Standard_Real du = (uend-ustart)/NbPoints; - Standard_Real R = TheCircle->Radius(); - Standard_Integer rank = 1; - Standard_Real curu =ustart; - for(Standard_Integer anIndex=1;anIndex<=NbPoints;anIndex++) + gp_Pnt aP1, aP2; + gp_Vec aV1; + Standard_Real anUStart = theCircle->FirstParameter(); + Standard_Real anUEnd = theCircle->LastParameter(); + Standard_Real aStep = (anUEnd - anUStart) / theNbPnts; + Standard_Real aRadius = theCircle->Radius(); + Standard_Integer aPntIdx = 1; + Standard_Real aCurU = anUStart; + for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; anIndex++) { - TheCircle->D1(curu,p1,v1); + theCircle->D1 (aCurU, aP1, aV1); - v1.Normalize(); - mypolyg.SetPnt(rank-1, p1); - rank++; - p2 = gp_Pnt(p1.X()+v1.X()*tan(du/2.)*R, - p1.Y()+v1.Y()*tan(du/2.)*R, - p1.Z()+v1.Z()*tan(du/2.)*R); - mypolyg.SetPnt(rank-1, p2); - rank++; - curu+=du; + aV1.Normalize(); + myPolyg.SetPnt (aPntIdx - 1, aP1); + aPntIdx++; + aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep / 2.0) * aRadius, + aP1.Y() + aV1.Y() * tan (aStep / 2.0) * aRadius, + aP1.Z() + aV1.Z() * tan (aStep / 2.0) * aRadius); + myPolyg.SetPnt (aPntIdx - 1, aP2); + aPntIdx++; + aCurU += aStep; } - // Copy the first point to the last point of mypolyg - mypolyg.SetPnt(NbPoints*2, mypolyg.Pnt(0)); + // Copy the first point to the last point of myPolyg + myPolyg.SetPnt (theNbPnts * 2, myPolyg.Pnt (0)); // Get myCenter3D - myCenter3D = TheCircle->Location(); + myCenter3D = theCircle->Location(); } // Radius = 0.0 else { - mypolyg.SetPnt(0, TheCircle->Location()); + myPolyg.SetPnt (0, theCircle->Location()); // Get myCenter3D - myCenter3D = mypolyg.Pnt(0); + myCenter3D = myPolyg.Pnt (0); + } + + if (mySensType == Select3D_TOS_BOUNDARY) + { + SetSensitivityFactor (6.0); } } @@ -114,59 +116,81 @@ myend(0) //function : Select3D_SensitiveCircle (constructor) //purpose : Definition of a sensitive arc //======================================================================= - -Select3D_SensitiveCircle:: -Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Geom_Circle)& TheCircle, - const Standard_Real u1, - const Standard_Real u2, - const Standard_Boolean FilledCircle, - const Standard_Integer NbPoints): -Select3D_SensitivePoly(OwnerId, S3D_GetArcNBPoints(TheCircle,NbPoints)), -myFillStatus(FilledCircle), -myCircle(TheCircle), -mystart(u1), -myend(u2) +Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Circle)& theCircle, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theIsFilled, + const Standard_Integer theNbPnts) +: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetArcNbPoints (theCircle, theNbPnts)), + myCircle (theCircle), + myStart (Min (theU1, theU2)), + myEnd (Max (theU1, theU2)) { - if (mypolyg.Size() != 1) + mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + + if (myPolyg.Size() != 1) { - gp_Pnt p1,p2; - gp_Vec v1; + gp_Pnt aP1, aP2; + gp_Vec aV1; - if (u1 > u2) + Standard_Real aStep = (myEnd - myStart) / (theNbPnts - 1); + Standard_Real aRadius = theCircle->Radius(); + Standard_Integer aPntIdx = 1; + Standard_Real aCurU = myStart; + + for (Standard_Integer anIndex = 1; anIndex <= theNbPnts - 1; anIndex++) { - mystart = u2; - myend = u1; + theCircle->D1 (aCurU, aP1, aV1); + aV1.Normalize(); + myPolyg.SetPnt (aPntIdx - 1, aP1); + aPntIdx++; + aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep /2.0) * aRadius, + aP1.Y() + aV1.Y() * tan (aStep /2.0) * aRadius, + aP1.Z() + aV1.Z() * tan (aStep /2.0) * aRadius); + myPolyg.SetPnt (aPntIdx - 1, aP2); + aPntIdx++; + aCurU += aStep; } - - Standard_Real du = (myend-mystart)/(NbPoints-1); - Standard_Real R = TheCircle->Radius(); - Standard_Integer rank = 1; - Standard_Real curu = mystart; - - for(Standard_Integer anIndex=1;anIndex<=NbPoints-1;anIndex++) - { - TheCircle->D1(curu,p1,v1); - v1.Normalize(); - mypolyg.SetPnt(rank-1, p1); - rank++; - p2 = gp_Pnt(p1.X()+v1.X()*tan(du/2.)*R, - p1.Y()+v1.Y()*tan(du/2.)*R, - p1.Z()+v1.Z()*tan(du/2.)*R); - mypolyg.SetPnt(rank-1, p2); - rank++; - curu+=du; - } - TheCircle->D0(myend,p1); - mypolyg.SetPnt(NbPoints*2-2, p1); + theCircle->D0 (myEnd, aP1); + myPolyg.SetPnt (theNbPnts * 2 - 2, aP1); // Get myCenter3D - myCenter3D = TheCircle->Location(); + myCenter3D = theCircle->Location(); } else { - mypolyg.SetPnt(0, TheCircle->Location()); + myPolyg.SetPnt (0, theCircle->Location()); // Get myCenter3D - myCenter3D = mypolyg.Pnt(0); + myCenter3D = myPolyg.Pnt (0); + } + + if (mySensType == Select3D_TOS_BOUNDARY) + { + SetSensitivityFactor (6.0); + } +} + +//======================================================================= +//function : Select3D_SensitiveCircle +//purpose : +//======================================================================= +Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePnts3d, + const Standard_Boolean theIsFilled) +: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled), + myStart (0), + myEnd (0) +{ + mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + + if (myPolyg.Size() != 1) + computeCenter3D(); + else + myCenter3D = myPolyg.Pnt (0); + + if (mySensType == Select3D_TOS_BOUNDARY) + { + SetSensitivityFactor (6.0); } } @@ -175,338 +199,161 @@ myend(u2) //purpose : //======================================================================= -Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(TColgp_HArray1OfPnt)& Thepolyg3d, - const Standard_Boolean FilledCircle): -Select3D_SensitivePoly(OwnerId, Thepolyg3d), -myFillStatus(FilledCircle), -mystart(0), -myend(0) +Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePnts3d, + const Standard_Boolean theIsFilled) +: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled), + myStart (0), + myEnd (0) { - if (mypolyg.Size() != 1) - ComputeCenter3D(); + mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + + if (myPolyg.Size() != 1) + computeCenter3D(); else - myCenter3D = mypolyg.Pnt(0); -} + myCenter3D = myPolyg.Pnt (0); -//======================================================================= -//function : Select3D_SensitiveCircle -//purpose : -//======================================================================= - -Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, - const TColgp_Array1OfPnt& Thepolyg3d, - const Standard_Boolean FilledCircle): -Select3D_SensitivePoly(OwnerId, Thepolyg3d), -myFillStatus(FilledCircle), -mystart(0), -myend(0) -{ - if (mypolyg.Size() != 1) - ComputeCenter3D(); - else - myCenter3D = mypolyg.Pnt(0); -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - Standard_Integer aSize = mypolyg.Size(); - Standard_Integer aDetectedIndex = -1; - gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y()); - if (aSize != 1) + if (mySensType == Select3D_TOS_BOUNDARY) { - Standard_Boolean Found = Standard_False; - Standard_Integer anIndex = 0; + SetSensitivityFactor (6.0); + } +} - if(!myFillStatus) - { - while(anIndex < aSize-2 && !Found) - { - Standard_Integer TheStat = - Select3D_SensitiveTriangle::Status(mypolyg.Pnt2d(anIndex), - mypolyg.Pnt2d(anIndex+1), - mypolyg.Pnt2d(anIndex+2), - aPickXY, thePickArgs.Tolerance(), - theMatchDMin); - Found = (TheStat != 2); - if (Found) - { - aDetectedIndex = anIndex; - } +//======================================================================= +// function : BVH +// purpose : Builds BVH tree for a circle's edge segments if needed +//======================================================================= +void Select3D_SensitiveCircle::BVH() +{ + if (mySensType == Select3D_TOS_BOUNDARY) + { + Select3D_SensitivePoly::BVH(); + } +} - anIndex += 2; - } - } - else - { - Standard_Real Xmin,Ymin,Xmax,Ymax; +//======================================================================= +// function : Matches +// purpose : Checks whether the circle overlaps current selecting volume +//======================================================================= +Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) +{ + Standard_Real aDepth = RealLast(); + Standard_Real aDistToCOG = RealLast(); - // Get coordinates of the bounding box - Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax); - TColgp_Array1OfPnt2d anArrayOf2dPnt(1, aSize); - - // Fill anArrayOf2dPnt with points from mypolig2d - Points2D(anArrayOf2dPnt); - - CSLib_Class2d anInOutTool (anArrayOf2dPnt, - thePickArgs.Tolerance(), - thePickArgs.Tolerance(), - Xmin, Ymin, Xmax, Ymax); - - // Method SiDans returns the status : - // 1 - the point is inside the circle - // 0 - the point is on the circle - // -1 - the point is outside the circle - Standard_Integer aStat = anInOutTool.SiDans (gp_Pnt2d (aPickXY)); - if(aStat != -1) - { - // Compute DMin (a distance between the center and the point) - theMatchDMin = gp_XY (myCenter2D.x - aPickXY.X(), myCenter2D.y - aPickXY.Y()).Modulus(); - - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); - - return !thePickArgs.IsClipped (theMatchDepth); - } - - return Standard_False; - } - - if (Found) - { - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); - - return !thePickArgs.IsClipped (theMatchDepth); - } - - return Standard_False; + Standard_Boolean isCollisionDetected = Standard_False; + if (mySensType == Select3D_TOS_BOUNDARY) + { + isCollisionDetected = Select3D_SensitivePoly::Matches (theMgr, thePickResult); + } + else if (mySensType == Select3D_TOS_INTERIOR) + { + Handle(TColgp_HArray1OfPnt) anArrayOfPnt; + Points3D (anArrayOfPnt); + isCollisionDetected = theMgr.Overlaps (anArrayOfPnt, + Select3D_TOS_INTERIOR, + aDepth); } - // Circle degenerates into point - theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0)); - if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor()) + if (isCollisionDetected) { - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); - - return !thePickArgs.IsClipped (theMatchDepth); + aDistToCOG = theMgr.DistToGeometryCenter (myCenter3D); } - return Standard_False; + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); + + return isCollisionDetected; } -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveCircle:: -Matches(const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) +void Select3D_SensitiveCircle::ArrayBounds (Standard_Integer & theLow, + Standard_Integer & theUp) const { - Bnd_Box2d abox; - abox.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax)); - abox.Enlarge(aTol); - - for(Standard_Integer anIndex=0;anIndex=0 && Rank= 0 && thePntIdx < myPolyg.Size()) + return myPolyg.Pnt (thePntIdx); + return gp_Pnt(); } - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= - -void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const -{ - Standard_Integer aSize = mypolyg.Size(); - - S<<"\tSensitiveCircle 3D :"; - - Standard_Boolean isclosed = 1== aSize; - if(isclosed) - S<<"(Closed Circle)"< Precision::Confusion()) + if ((myEnd - myStart) > Precision::Confusion()) { // Arc - aNewEntity = new Select3D_SensitiveCircle(myOwnerId, myCircle, mystart, myend, myFillStatus); + aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled); } else { // Circle - aNewEntity = new Select3D_SensitiveCircle(myOwnerId, myCircle, myFillStatus); + aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled); } } // this was constructed using TColgp_Array1OfPnt else { - Standard_Integer aSize = mypolyg.Size(); - TColgp_Array1OfPnt aPolyg(1, aSize); + Standard_Integer aSize = myPolyg.Size(); + TColgp_Array1OfPnt aPolyg (1, aSize); for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex) { - aPolyg.SetValue(anIndex, mypolyg.Pnt(anIndex-1)); + aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1)); } - aNewEntity = new Select3D_SensitiveCircle(myOwnerId, aPolyg, myFillStatus); + aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled); } - if(HasLocation()) - aNewEntity->SetLocation(Location()); - - aNewEntity->UpdateLocation(theLocation); - return aNewEntity; } //======================================================================= -//function : Project +//function : computeCenter3D //purpose : //======================================================================= - -void Select3D_SensitiveCircle::Project(const Handle(Select3D_Projector) &aProjector) -{ - Select3D_SensitivePoly::Project(aProjector); - gp_Pnt2d aCenter; - aProjector->Project(myCenter3D, aCenter); - myCenter2D = aCenter; -} - -//======================================================================= -//function : ComputeCenter3D -//purpose : -//======================================================================= - -void Select3D_SensitiveCircle::ComputeCenter3D() +void Select3D_SensitiveCircle::computeCenter3D() { gp_XYZ aCenter; - Standard_Integer nbpoints = mypolyg.Size(); - if (nbpoints != 1) + Standard_Integer aNbPnts = myPolyg.Size(); + if (aNbPnts != 1) { // The mass of points system - Standard_Integer aMass = nbpoints - 1; + Standard_Integer aMass = aNbPnts - 1; // Find the circle barycenter - for (Standard_Integer anIndex = 0; anIndex < nbpoints-1; ++anIndex) + for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex) { - aCenter += mypolyg.Pnt(anIndex); + aCenter += myPolyg.Pnt(anIndex); } myCenter3D = aCenter / aMass; } else { - myCenter3D = mypolyg.Pnt(0); + myCenter3D = myPolyg.Pnt(0); } } + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the circle. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const +{ + return myCenter3D; +} diff --git a/src/Select3D/Select3D_SensitiveCircle.hxx b/src/Select3D/Select3D_SensitiveCircle.hxx new file mode 100644 index 0000000000..65c06b0801 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveCircle.hxx @@ -0,0 +1,124 @@ +// Created on: 1996-02-06 +// Created by: Robert COUBLANC +// Copyright (c) 1996-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Modified Tue Apr 14 1998 by rob : fix Bug : Case of Null Radius Circle... + +#ifndef _Select3D_SensitiveCircle_HeaderFile +#define _Select3D_SensitiveCircle_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class Geom_Circle; +class Standard_ConstructionError; +class Standard_OutOfRange; +class SelectBasics_EntityOwner; +class TColgp_HArray1OfPnt; +class TColgp_Array1OfPnt; +class gp_Pnt; +class TopLoc_Location; + + +//! A framework to define sensitive 3D arcs and circles. +//! In some cases this class can raise Standard_ConstructionError and +//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. +class Select3D_SensitiveCircle : public Select3D_SensitivePoly +{ +public: + + //! Constructs the sensitive circle object defined by the + //! owner theOwnerId, the circle theCircle, the boolean + //! theIsFilled and the number of points theNbPnts. + Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Circle)& theCircle, + const Standard_Boolean theIsFilled = Standard_False, + const Standard_Integer theNbPnts = 12); + + //! Constructs the sensitive arc object defined by the + //! owner theOwnerId, the circle theCircle, the parameters theU1 + //! and theU2, the boolean theIsFilled and the number of points theNbPnts. + //! theU1 and theU2 define the first and last points of the arc on theCircle. + Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Circle)& theCircle, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theIsFilled = Standard_False, + const Standard_Integer theNbPnts = 12); + + //! Constructs the sensitive circle object defined by the + //! owner theOwnerId, the array of triangles thePnts3d, and the boolean theIsFilled. + //! thePnts3d is an array of consecutive triangles on the + //! circle. The triangle i+1 lies on the intersection of the + //! tangents to the circle of i and i+2. Note, that the first point of thePnts3d + //! must be equal to the last point of thePnts3d. + Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePnts3d, + const Standard_Boolean theIsFilled = Standard_False); + + //! Constructs the sensitive circle object defined by the + //! owner theOwnerId, the array of points thePnts3d, and the boolean theIsFilled. + //! If the length of thePnts3d is more then 1, the first point of thePnts3d + //! must be equal to the last point of thePnts3d. + Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePnts3d, + const Standard_Boolean theIsFilled = Standard_False); + + //! Checks whether the circle overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + + Standard_EXPORT void ArrayBounds (Standard_Integer & theLow, Standard_Integer & theUp) const; + + Standard_EXPORT gp_Pnt GetPoint3d (const Standard_Integer thePntIdx) const; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Returns center of the circle. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Builds BVH tree for a circle's edge segments if needed + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveCircle) + +private: + + //! Computes myCenter3D as the barycenter of points from mypolyg3d + void computeCenter3D(); + +private: + + Select3D_TypeOfSensitivity mySensType; //!< True if type of selection is interior, false otherwise + gp_Pnt myCenter3D; //!< Center of a circle + Handle_Geom_Circle myCircle; //!< Points of the circle + Standard_Real myStart; //!< Sensitive arc parameter + Standard_Real myEnd; //!< Sensitive arc parameter +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitivePoly) + +#endif // _Select3D_SensitiveCircle_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveCurve.cdl b/src/Select3D/Select3D_SensitiveCurve.cdl deleted file mode 100644 index c5ddfedaf7..0000000000 --- a/src/Select3D/Select3D_SensitiveCurve.cdl +++ /dev/null @@ -1,139 +0,0 @@ --- Created on: 1995-03-10 --- Created by: Mister rmi --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - --- Modified on july 97 by ROB : Field HArray instead Of ArrayOfPnt3D --- (connected entities) - - -class SensitiveCurve from Select3D -inherits SensitivePoly from Select3D - - ---Purpose: A framework to define a sensitive 3D curve. - -- In some cases this class can raise Standard_ConstructionError and - -- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. - -uses - Pnt from gp, - Pnt2d from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Curve from Geom, - Array1OfPnt from TColgp, - Array1OfPnt2d from TColgp, - HArray1OfPnt from TColgp, - Box2d from Bnd, - Location from TopLoc, - SensitiveEntity from Select3D, - XYZ from gp - -raises - ConstructionError from Standard, - OutOfRange from Standard -is - - - Create (OwnerId : EntityOwner from SelectBasics; - TheCurve : Curve from Geom; - MaxPoints : Integer = 17) - returns SensitiveCurve; - ---Level: Public - ---Purpose: Constructs a sensitive curve object defined by the - -- owner OwnerId, the curve TheCurve, and the - -- maximum number of points on the curve: MaxPoints. - - Create (OwnerId : EntityOwner from SelectBasics; - ThePoints : HArray1OfPnt from TColgp) - returns SensitiveCurve; - ---Level: Public - ---Purpose: Constructs a sensitive curve object defined by the - -- owner OwnerId and the set of points ThePoints. - - Create (OwnerId : EntityOwner from SelectBasics; - ThePoints : Array1OfPnt from TColgp) - returns SensitiveCurve; - ---Level: Public - ---Purpose: Creation of Sensitive Curve from Points. - -- Warning : This Method should disappear in the next version... - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth (me; - thePickLine : Lin from gp; - theDetectedIndex : Integer from Standard) - returns Real from Standard; - ---Level: Public - ---Purpose: Compute depth of sensitive circle for the detected sub-part. - -- @param thePickLine [in] the picking line. - -- @param theDetectedIndex [in] index of the detected sub-part. - -- @return depth on the picking line. - - GetLastDetected(me) returns Integer from Standard; - ---Purpose: Gets index of last detected segment - ---C++: inline - - - ---Category: Internal Methods - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - LoadPoints(me:mutable;aCurve:Curve from Geom;NbPoints: Integer) is static private; - - GetConnected(me: mutable; theLocation : Location from TopLoc) - returns SensitiveEntity from Select3D - is redefined virtual; - ---Level: Public - ---Purpose: Returns the copy of this - - ComputeDepth(me; - thePickLine : Lin from gp; - theP1 : XYZ from gp; - theP2 : XYZ from gp; - theDepth : out Real from Standard) - ---Purpose: Computes the depth by means of intersection of - -- a segment of the curve defined by and - -- the eye-line . - returns Boolean from Standard - is protected; - -fields - mylastseg : Integer from Standard; - myCurve : Curve from Geom; -end SensitiveCurve; - diff --git a/src/Select3D/Select3D_SensitiveCurve.cxx b/src/Select3D/Select3D_SensitiveCurve.cxx index 9c3144681f..149b8a8378 100644 --- a/src/Select3D/Select3D_SensitiveCurve.cxx +++ b/src/Select3D/Select3D_SensitiveCurve.cxx @@ -14,300 +14,126 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include -#include +#include #include -#include -#include -#include +#include + +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCurve, Select3D_SensitivePoly) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCurve, Select3D_SensitivePoly) //================================================== // Function: Creation // Purpose : //================================================== - -Select3D_SensitiveCurve -::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Geom_Curve)& C, - const Standard_Integer NbPoints): -Select3D_SensitivePoly(OwnerId, NbPoints), -mylastseg(0), -myCurve(C) +Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Curve)& theCurve, + const Standard_Integer theNbPnts) +: Select3D_SensitivePoly (theOwnerId, theNbPnts > 2, theNbPnts), + myCurve (theCurve) { - LoadPoints(C,NbPoints); + loadPoints (theCurve, theNbPnts); + SetSensitivityFactor (3.0); } //================================================== // Function: Creation // Purpose : //================================================== +Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints) +: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints->Length() > 2) -Select3D_SensitiveCurve -::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(TColgp_HArray1OfPnt)& ThePoints): -Select3D_SensitivePoly(OwnerId, ThePoints), -mylastseg(0) { + SetSensitivityFactor (3.0); } //================================================== // Function: Creation // Purpose : //================================================== - -Select3D_SensitiveCurve -::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId, - const TColgp_Array1OfPnt& ThePoints): -Select3D_SensitivePoly(OwnerId, ThePoints), -mylastseg(0) +Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints) +: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints.Length() > 2) { + SetSensitivityFactor (3.0); } //================================================== -// Function: Matches +// Function: loadPoints // Purpose : //================================================== - -Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) +void Select3D_SensitiveCurve::loadPoints (const Handle(Geom_Curve)& theCurve, const Standard_Integer theNbPnts) { - Standard_Integer Rank; - TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size()); - Points2D(aArrayOf2dPnt); - if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt, - thePickArgs.X(), thePickArgs.Y(), - thePickArgs.Tolerance(), - theMatchDMin, - Rank)) + Standard_Real aStep = (theCurve->LastParameter() - theCurve->FirstParameter()) / (theNbPnts - 1); + Standard_Real aParam = theCurve->FirstParameter(); + for (Standard_Integer aPntIdx = 0; aPntIdx < myPolyg.Size(); ++aPntIdx) { - // remember detected segment (for GetLastDetected) - mylastseg = Rank; - - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank); - - return !thePickArgs.IsClipped (theMatchDepth); + myPolyg.SetPnt (aPntIdx, theCurve->Value (aParam)); + aParam += aStep; } - - return Standard_False; -} - -//================================================== -// Function: Matches -// Purpose : know if a box touches the projected polygon -// of the Curve. -//================================================== - -Standard_Boolean Select3D_SensitiveCurve:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Bnd_Box2d BoundBox; - BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol); - - for(Standard_Integer anIndex=0; anIndexLength() was removed*/ - - Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1); - Standard_Real Curparam = aCurve->FirstParameter(); - for(Standard_Integer anIndex=0;anIndexValue(Curparam)); - Curparam+=Step; - } -} - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= - -void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const -{ - S<<"\tSensitiveCurve 3D :"<= mypolyg.Size()) - { - return aDepth; - } - - gp_XYZ aCDG = mypolyg.Pnt (theSegment); - - // Check depth of a line forward within the curve. - if (theSegment + 1 < mypolyg.Size()) - { - gp_XYZ aCDG1 = mypolyg.Pnt (theSegment + 1); - if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth)) - { - return aDepth; - } - } - - // Check depth of a line backward within the curve. - if (theSegment - 1 >= 0) - { - gp_XYZ aCDG1 = mypolyg.Pnt (theSegment - 1); - if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth)) - { - return aDepth; - } - } - - // Calculate the depth in the middle point of - // a next (forward) segment of the curve. - if (theSegment + 1 < mypolyg.Size()) - { - aCDG += mypolyg.Pnt(theSegment + 1); - aCDG /= 2.; - } - - return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG)); } //======================================================================= //function : GetConnected //purpose : //======================================================================= - -Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const TopLoc_Location &theLocation) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected() { // Create a copy of this Handle(Select3D_SensitiveEntity) aNewEntity; // this was constructed using Handle(Geom_Curve) if (!myCurve.IsNull()) { - aNewEntity = new Select3D_SensitiveCurve(myOwnerId, myCurve); + aNewEntity = new Select3D_SensitiveCurve (myOwnerId, myCurve); } // this was constructed using TColgp_HArray1OfPnt else { - Standard_Integer aSize = mypolyg.Size(); - Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(1, aSize); + Standard_Integer aSize = myPolyg.Size(); + Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt (1, aSize); // Fill the array with points from mypolyg3d for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex) { - aPoints->SetValue(anIndex, mypolyg.Pnt(anIndex-1)); + aPoints->SetValue (anIndex, myPolyg.Pnt (anIndex-1)); } - aNewEntity = new Select3D_SensitiveCurve(myOwnerId, aPoints); + aNewEntity = new Select3D_SensitiveCurve (myOwnerId, aPoints); } - if (HasLocation()) - aNewEntity->SetLocation(Location()); - - aNewEntity->UpdateLocation(theLocation); - return aNewEntity; } //======================================================================= -//function : ComputeDepth() -//purpose : Computes the depth by means of intersection of -// a segment of the curve defined by and -// the eye-line . +// function : Matches +// purpose : Checks whether the curve overlaps current selecting volume //======================================================================= - -Standard_Boolean Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& thePickLine, - const gp_XYZ& theP1, - const gp_XYZ& theP2, - Standard_Real& theDepth) const +Standard_Boolean Select3D_SensitiveCurve::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - // The segment may have null length. - gp_XYZ aVec = theP2 - theP1; - Standard_Real aLength = aVec.Modulus(); - if (aLength <= gp::Resolution()) - { - theDepth = ElCLib::Parameter(thePickLine, theP1); - return Standard_True; - } + if (myPolyg.Size() > 2) + return Select3D_SensitivePoly::Matches (theMgr, thePickResult); - // Compute an intersection point of the segment-line and the eye-line. - gp_Lin aLine (theP1, aVec); - Extrema_ExtElC anExtrema(aLine, thePickLine, Precision::Angular()); - if (anExtrema.IsDone() && !anExtrema.IsParallel() ) + const gp_Pnt aPnt1 = myPolyg.Pnt3d (0); + const gp_Pnt aPnt2 = myPolyg.Pnt3d (1); + Standard_Real aDepth = RealLast(); + Standard_Boolean isMatched = theMgr.Overlaps (aPnt1, aPnt2, aDepth); + + if (isMatched) { - // Iterator on solutions (intersection points). - for (Standard_Integer i = 1; i <= anExtrema.NbExt(); i++) + Standard_Real aDistToCOG = RealLast(); + if (myCOG.X() == RealLast() && myCOG.Y() == RealLast() && myCOG.Z() == RealLast()) { - // Get the intersection point. - Extrema_POnCurv aPointOnLine1, aPointOnLine2; - anExtrema.Points(i, aPointOnLine1, aPointOnLine2); - - // Check bounds: the point of intersection should lie within the segment. - if (aPointOnLine1.Parameter() > 0.0 && aPointOnLine1.Parameter() < aLength) + gp_XYZ aCenter (0.0, 0.0, 0.0); + for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx) { - theDepth = ElCLib::Parameter(thePickLine, aPointOnLine1.Value()); - return Standard_True; + aCenter += myPolyg.Pnt (aIdx); } + myCOG = aCenter / myPolyg.Size(); } + + aDistToCOG = theMgr.DistToGeometryCenter (myCOG); + + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); + return Standard_True; } return Standard_False; diff --git a/src/Select3D/Select3D_SensitiveCurve.hxx b/src/Select3D/Select3D_SensitiveCurve.hxx new file mode 100644 index 0000000000..ca265cc368 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveCurve.hxx @@ -0,0 +1,91 @@ +// Created on: 1995-03-13 +// Created by: Robert COUBLANC +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitiveCurve_HeaderFile +#define _Select3D_SensitiveCurve_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Geom_Curve; +class Standard_ConstructionError; +class Standard_OutOfRange; +class SelectBasics_EntityOwner; +class TColgp_HArray1OfPnt; +class TColgp_Array1OfPnt; +class Select3D_SensitiveEntity; +class TopLoc_Location; + + +//! A framework to define a sensitive 3D curve. +//! In some cases this class can raise Standard_ConstructionError and +//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. +class Select3D_SensitiveCurve : public Select3D_SensitivePoly +{ +public: + + //! Constructs a sensitive curve object defined by the + //! owner theOwnerId, the curve theCurve, and the + //! maximum number of points on the curve: theNbPnts. + Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Geom_Curve)& theCurve, + const Standard_Integer theNbPnts = 17); + + //! Constructs a sensitive curve object defined by the + //! owner theOwnerId and the set of points ThePoints. + Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints); + + //! Creation of Sensitive Curve from Points. + //! Warning : This Method should disappear in the next version... + Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints); + + //! Checks whether the curve overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the copy of this + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + +public: + + DEFINE_STANDARD_RTTI(Select3D_SensitiveCurve) + +private: + + void loadPoints (const Handle(Geom_Curve)& aCurve, + const Standard_Integer NbPoints); + +private: + + Handle_Geom_Curve myCurve; //!< Curve points +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveCurve, Select3D_SensitivePoly) + +#endif // _Select3D_SensitiveCurve_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveCurve.lxx b/src/Select3D/Select3D_SensitiveCurve.lxx deleted file mode 100644 index bb17bef605..0000000000 --- a/src/Select3D/Select3D_SensitiveCurve.lxx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -inline Standard_Integer Select3D_SensitiveCurve::GetLastDetected() const -{return mylastseg;} diff --git a/src/Select3D/Select3D_SensitiveEntity.cdl b/src/Select3D/Select3D_SensitiveEntity.cdl deleted file mode 100644 index 866954303e..0000000000 --- a/src/Select3D/Select3D_SensitiveEntity.cdl +++ /dev/null @@ -1,135 +0,0 @@ --- Created on: 1995-01-24 --- Created by: Rob --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - --- modified by rob jul/ 21/ 97 : inserting locations ... --- modified by rob jan/ 29/ 98 : Sort by deph-> add a field to be able --- to compute a depth --- -> Virtual methods rather than --- Deferred for Project --- WARNING : Must be redefined for --- each kind of sensitive entity - - -deferred class SensitiveEntity from Select3D inherits - SensitiveEntity from SelectBasics - - ---Purpose: Abstract framework to define 3D sensitive entities. - -- As the selection process uses the principle of a - -- projection of 3D shapes onto a 2D view where - -- nearness to a rectangle determines whether a shape - -- is picked or not, all 3D shapes need to be converted - -- into 2D ones in order to be selected. - - -uses - - Projector from Select3D, - EntityOwner from SelectBasics, - Location from TopLoc, - Lin from gp, - Box2d from Bnd, - Array1OfPnt2d from TColgp - -is - - Initialize(OwnerId : EntityOwner from SelectBasics); - - NeedsConversion(me) returns Boolean is redefined static; - ---Level: Public - ---Purpose: Returns true if this framework needs conversion. - ---C++: inline - - Is3D(me) returns Boolean from Standard is redefined static; - ---Purpose: Returns true if this framework provides 3D information. - - Project (me:mutable;aProjector : Projector from Select3D) is deferred; - ---Level: Public - ---Purpose: In classes inheriting this framework, you must - -- redefine this function in order to get a sensitive 2D - -- rectangle from a 3D entity. This rectangle is the - -- sensitive zone which makes the 3D entity selectable. - - MaxBoxes(me) returns Integer is redefined virtual; - ---Level: Public - ---Purpose: Returns the max number of sensitive areas returned - -- by this class is 1 by default. - -- Else on must redefine this method. - - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is virtual; - ---Purpose: Originally this method intended to return sensitive - -- entity with new location aLocation, but currently sensitive - -- entities do not hold a location, instead HasLocation() and - -- Location() methods call corresponding entity owner's methods. - -- Thus all entities returned by GetConnected() share the same - -- location propagated from corresponding selectable object. - -- You must redefine this function for any type of - -- sensitive entity which can accept another connected - -- sensitive entity.//can be connected to another sensitive entity. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean from Standard is redefined virtual; - ---Purpose: Matches the box defined by the coordinates Xmin, - -- Ymin, Xmax, Ymax with the entity found at that point - -- within the tolerance aTol. - -- Xmin, YMin define the minimum point in the lower left - -- hand corner of the box, and XMax, YMax define the - -- maximum point in the upper right hand corner of the box. - -- You must redefine this function for every inheriting entity. - -- You will have to call this framework inside the redefined function. - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean from Standard is redefined virtual; - ---Purpose: prevents from hiding virtual methods... - - ---Category: Location of sensitive entities... - -- Default implementations of HasLocation() and Location() rely on - -- location obtained from the entity owner, to minimize memory usage. - -- SetLocation() and ResetLocation() do nothing by default. - - HasLocation(me) returns Boolean from Standard is virtual; - ---Purpose: Returns true if this framework has a location defined. - - Location(me) returns Location from TopLoc is virtual; - ---C++: return const - - ResetLocation(me:mutable) is virtual; - ---Purpose: sets the location to Identity - - SetLocation(me:mutable;aLoc :Location from TopLoc) is virtual; - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is virtual; - ---Purpose: 2 options : - -- = False -> general information - -- = True -> whole informtion 3D +2d ... - - DumpBox(myclass; S: in out OStream;abox:Box2d from Bnd) ; - - UpdateLocation(me:mutable;aLoc:Location from TopLoc); - -end SensitiveEntity; - - - - - - diff --git a/src/Select3D/Select3D_SensitiveEntity.cxx b/src/Select3D/Select3D_SensitiveEntity.cxx index 913e715e98..19f73a5ca5 100644 --- a/src/Select3D/Select3D_SensitiveEntity.cxx +++ b/src/Select3D/Select3D_SensitiveEntity.cxx @@ -14,153 +14,60 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include #include #include #include +#include + +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveEntity, SelectBasics_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity) //======================================================================= //function : Select3D_SensitiveEntity //purpose : //======================================================================= -Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId): -SelectBasics_SensitiveEntity(OwnerId) -{} +Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& theOwnerId) +: SelectBasics_SensitiveEntity (theOwnerId) {} //======================================================================= -//function : Matches -//purpose : +// function : Matches +// purpose : Checks whether sensitive overlaps current selecting volume. +// Stores minimum depth, distance to center of geometry and +// closest point detected into thePickResult //======================================================================= - -Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real, - const Standard_Real, - const Standard_Real, - const Standard_Real, - const Standard_Real) +Standard_Boolean Select3D_SensitiveEntity::Matches (SelectBasics_SelectingVolumeManager& /*theMgr*/, + SelectBasics_PickResult& /*thePickResult*/) { return Standard_False; } -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveEntity::Matches(const TColgp_Array1OfPnt2d&, - const Bnd_Box2d&, - const Standard_Real) -{ - return Standard_False; -} - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= - -void Select3D_SensitiveEntity::Dump(Standard_OStream& S, const Standard_Boolean) const -{ - S<<"\tSensitive Entity 3D"<Location(); -} - -//======================================================================= -//function : HasLocation -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveEntity::HasLocation() const -{ - Handle(SelectBasics_EntityOwner) anOwner = OwnerId(); - return (!anOwner.IsNull() && anOwner->HasLocation()); -} - -//======================================================================= -//function : Is3D -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveEntity::Is3D() const -{return Standard_True;} - -//======================================================================= -//function : MaxBoxes -//purpose : -//======================================================================= - -Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const -{return 1;} - //======================================================================= //function : GetConnected //purpose : //======================================================================= -Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const TopLoc_Location&) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected() { - Handle(Select3D_SensitiveEntity) NiouEnt; - return NiouEnt; + Handle(Select3D_SensitiveEntity) aNewEntity; + return aNewEntity; +} + +//======================================================================= +// function : BVH +// purpose : Builds BVH tree for a sensitive if needed +//======================================================================= +void Select3D_SensitiveEntity::BVH() +{ + return; +} + +//======================================================================= +// function : Clear +// purpose : Cleans up resources and memory +//======================================================================= +void Select3D_SensitiveEntity::Clear() +{ + Set (NULL); } diff --git a/src/Select3D/Select3D_SensitiveEntity.hxx b/src/Select3D/Select3D_SensitiveEntity.hxx new file mode 100644 index 0000000000..a235f15ad0 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveEntity.hxx @@ -0,0 +1,92 @@ +// Created on: 1995-03-13 +// Created by: Robert COUBLANC +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitiveEntity_HeaderFile +#define _Select3D_SensitiveEntity_HeaderFile + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +class Select3D_SensitiveEntity; +class Handle(Select3D_SensitiveEntity); +class SelectBasics_EntityOwner; + +//! Abstract framework to define 3D sensitive entities. +//! As the selection process uses the principle of a +//! projection of 3D shapes onto a 2D view where +//! nearness to a rectangle determines whether a shape +//! is picked or not, all 3D shapes need to be converted +//! into 2D ones in order to be selected. +class Select3D_SensitiveEntity : public SelectBasics_SensitiveEntity +{ +public: + + //! Originally this method intended to return sensitive + //! entity with new location aLocation, but currently sensitive + //! entities do not hold a location, instead HasLocation() and + //! Location() methods call corresponding entity owner's methods. + //! Thus all entities returned by GetConnected() share the same + //! location propagated from corresponding selectable object. + //! You must redefine this function for any type of + //! sensitive entity which can accept another connected + //! sensitive entity.//can be connected to another sensitive entity. + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected(); + + //! Checks whether sensitive overlaps current selecting volume. + //! Stores minimum depth, distance to center of geometry and + //! closest point detected into thePickResult + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the number of sub-entities or elements in + //! sensitive entity. Is used to determine if entity is + //! complex and needs to pre-build BVH at the creation of + //! sensitive entity step or is light-weighted so the tree + //! can be build on demand with unnoticeable delay + virtual Standard_Integer NbSubElements() = 0; + + //! Returns bounding box of a sensitive with transformation applied + virtual Select3D_BndBox3d BoundingBox() = 0; + + //! Returns center of a sensitive with transformation applied + virtual gp_Pnt CenterOfGeometry() const = 0; + + //! Builds BVH tree for a sensitive if needed + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + //! Clears up all resources and memory + Standard_EXPORT virtual void Clear() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveEntity) + +protected: + + Standard_EXPORT Select3D_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId); +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity) + +#endif // _Select3D_SensitiveEntity_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveFace.cdl b/src/Select3D/Select3D_SensitiveFace.cdl deleted file mode 100644 index e6e66280d6..0000000000 --- a/src/Select3D/Select3D_SensitiveFace.cdl +++ /dev/null @@ -1,118 +0,0 @@ --- Created on: 1995-03-24 --- Created by: Robert COUBLANC --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveFace from Select3D -inherits SensitivePoly from Select3D - - ---Purpose: Sensitive Entity to make a face selectable. - -- In some cases this class can raise Standard_ConstructionError and - -- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. - -uses - EntityOwner from SelectBasics, - Projector from Select3D, - Lin from gp, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt from TColgp, - HArray1OfPnt from TColgp, - Array1OfPnt2d from TColgp, - Box2d from Bnd, - TypeOfSensitivity from Select3D, - Location from TopLoc, - SensitiveEntity from Select3D - -raises - ConstructionError from Standard, - OutOfRange from Standard - -is - - Create (OwnerId : EntityOwner from SelectBasics; - ThePoints : Array1OfPnt from TColgp; - Sensitivity : TypeOfSensitivity = Select3D_TOS_INTERIOR) - returns SensitiveFace; - ---Level: Public - ---Purpose: Constructs a sensitive face object defined by the - -- owner OwnerId, the array of points ThePoints, and - -- the sensitivity type Sensitivity. - -- The array of points is the outer polygon of the geometric face. - - Create (OwnerId : EntityOwner from SelectBasics; - ThePoints : HArray1OfPnt from TColgp; - Sensitivity : TypeOfSensitivity = Select3D_TOS_INTERIOR) - returns SensitiveFace; - ---Level: Public - ---Purpose: Constructs a sensitive face object defined by the - -- owner OwnerId, the array of points ThePoints, and - -- the sensitivity type Sensitivity. - -- The array of points is the outer polygon of the geometric face. - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined virtual; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth (me; - thePickLine : Lin from gp; - theDepthMin, theDepthMax : Real from Standard) - returns Real from Standard - is virtual; - ---Level: Public - ---Purpose: Computes the depth values for all 3D points defining this face and returns - -- the minimal value among them. - -- If the "minimal depth" approach is not suitable and gives wrong detection results - -- in some particular case, a custom sensitive face class can redefine this method. - - ComputeDepth(me;EyeLine: Lin from gp) - is private; - ---Level: Public - ---Purpose: Warning: Obsolete. - -- Use newer version of the method with min, max limits passed as arguments. - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - GetConnected(me: mutable; theLocation : Location from TopLoc) - returns SensitiveEntity from Select3D - is redefined virtual; - ---Level: Public - ---Purpose: Returns the copy of this - - -fields - - mytype : TypeOfSensitivity; -end SensitiveFace; diff --git a/src/Select3D/Select3D_SensitiveFace.cxx b/src/Select3D/Select3D_SensitiveFace.cxx index 87454db9d1..5fdd578f09 100644 --- a/src/Select3D/Select3D_SensitiveFace.cxx +++ b/src/Select3D/Select3D_SensitiveFace.cxx @@ -18,261 +18,124 @@ // pour teste si on est dedans ou dehors... //Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ... -#include -#include -#include -#include +#include #include #include -#include -#include +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveFace, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveFace, Select3D_SensitiveEntity) //================================================== // Function: Hide this constructor to the next version... // Purpose : simply avoid interfering with the version update //================================================== - -Select3D_SensitiveFace:: -Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId, - const TColgp_Array1OfPnt& ThePoints, - const Select3D_TypeOfSensitivity aType): -Select3D_SensitivePoly(OwnerId, ThePoints), -mytype (aType) +Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints, + const Select3D_TypeOfSensitivity theType) +: Select3D_SensitiveEntity (theOwnerId), + mySensType (theType) { + if (mySensType == Select3D_TOS_INTERIOR) + { + myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints); + } + else + { + myFacePoints = new Select3D_BoundarySensitivePointSet (theOwnerId, thePoints); + } } //================================================== // Function: Creation // Purpose : //================================================== - -Select3D_SensitiveFace:: -Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(TColgp_HArray1OfPnt)& ThePoints, - const Select3D_TypeOfSensitivity aType): -Select3D_SensitivePoly(OwnerId, ThePoints), -mytype (aType) +Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints, + const Select3D_TypeOfSensitivity theType) +: Select3D_SensitiveEntity (theOwnerId), + mySensType (theType) { -} - -//================================================== -// Function: Matches -// Purpose : -//================================================== - -Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - Standard_Real DMin2 = 0.; - Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.; - if(!Bnd_Box2d(mybox2d).IsVoid()) + if (mySensType == Select3D_TOS_INTERIOR) { - Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax); - DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus(); + myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints); } - // calculation of a criterion of minimum distance... - // from start Dmin = size of the bounding box 2D, - // then min. distance of the polyhedron or cdg... - - Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance(); - Standard_Integer aSize = mypolyg.Size(), anIndex; - gp_XY CDG; - for(anIndex=0;anIndex1) - { - CDG/=(aSize-1); - } - DMin2 = Min (DMin2, gp_XY (CDG.X() - thePickArgs.X(), CDG.Y() - thePickArgs.Y()).SquareModulus()); - theMatchDMin = Sqrt(DMin2); - - Standard_Boolean isplane2d(Standard_True); - - for(anIndex=1;anIndex thePickArgs.Tolerance()) isplane2d=Standard_False; - } - if (isplane2d) - { - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), - thePickArgs.DepthMin(), - thePickArgs.DepthMax()); - - return !thePickArgs.IsClipped (theMatchDepth); - } - - //otherwise it is checked if the point is in the face... - TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize); - Points2D(aArrayOf2dPnt); - CSLib_Class2d TheInOutTool (aArrayOf2dPnt, - thePickArgs.Tolerance(), - thePickArgs.Tolerance(), - Xmin, Ymin, Xmax, Ymax); - Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())); - - Standard_Boolean res(Standard_False); - switch(TheStat) - { - case 0: - res = Standard_True; - case 1: - { - if(mytype!=Select3D_TOS_BOUNDARY) - res = Standard_True; - } - } - if (res) - { - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), - thePickArgs.DepthMin(), - thePickArgs.DepthMax()); - - return !thePickArgs.IsClipped (theMatchDepth); - } - return Standard_False; -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveFace:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Bnd_Box2d BoundBox; - BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol); - - for(Standard_Integer anIndex=0;anIndex theDepthMin) && (aPointDepth < theDepthMax)) - { - aDepth = aPointDepth; - } - } - return aDepth; + myFacePoints->GetPoints (theHArrayOfPnt); } //======================================================================= -//function : ComputeDepth -//purpose : +// function : BVH +// purpose : Builds BVH tree for the face //======================================================================= - -void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const +void Select3D_SensitiveFace::BVH() { - // this method is obsolete. + myFacePoints->BVH(); +} + +//======================================================================= +// function : Matches +// purpose : Checks whether the face overlaps current selecting volume +//======================================================================= +Standard_Boolean Select3D_SensitiveFace::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) +{ + return myFacePoints->Matches (theMgr, thePickResult); } //======================================================================= //function : GetConnected //purpose : //======================================================================= - -Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected(const TopLoc_Location &theLocation) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected() { // Create a copy of this - Standard_Integer aSize = mypolyg.Size(); - TColgp_Array1OfPnt aPoints(1, aSize); - for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex) - { - aPoints.SetValue(anIndex, mypolyg.Pnt(anIndex-1)); - } + Handle(TColgp_HArray1OfPnt) aPoints; + myFacePoints->GetPoints (aPoints); Handle(Select3D_SensitiveEntity) aNewEntity = - new Select3D_SensitiveFace(myOwnerId, aPoints, mytype); - - if (HasLocation()) - aNewEntity->SetLocation(Location()); - - aNewEntity->UpdateLocation(theLocation); + new Select3D_SensitiveFace (myOwnerId, aPoints, mySensType); return aNewEntity; } + +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of the face. If location transformation +// is set, it will be applied +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveFace::BoundingBox() +{ + return myFacePoints->BoundingBox(); +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the face. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveFace::CenterOfGeometry() const +{ + return myFacePoints->CenterOfGeometry(); +} + +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of sub-entities (points or planar convex +// polygons) +//======================================================================= +Standard_Integer Select3D_SensitiveFace::NbSubElements() +{ + return myFacePoints->NbSubElements(); +} diff --git a/src/Select3D/Select3D_SensitiveFace.hxx b/src/Select3D/Select3D_SensitiveFace.hxx new file mode 100644 index 0000000000..82e08caa0d --- /dev/null +++ b/src/Select3D/Select3D_SensitiveFace.hxx @@ -0,0 +1,108 @@ +// Created on: 1995-03-27 +// Created by: Robert COUBLANC +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +//Modif on jun-24-97 : introduction de CSLib_Class2d de LBR +// pour teste si on est dedans ou dehors... +//Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ... + +#ifndef _Select3D_SensitiveFace_HeaderFile +#define _Select3D_SensitiveFace_HeaderFile + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class Standard_ConstructionError; +class Standard_OutOfRange; +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; +class TColgp_HArray1OfPnt; +class TopLoc_Location; + + +//! Sensitive Entity to make a face selectable. +//! In some cases this class can raise Standard_ConstructionError and +//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. +class Select3D_SensitiveFace : public Select3D_SensitiveEntity +{ +public: + + //! Constructs a sensitive face object defined by the + //! owner theOwnerId, the array of points thePoints, and + //! the sensitivity type theType. + //! The array of points is the outer polygon of the geometric face. + Standard_EXPORT Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints, + const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR); + + //! Constructs a sensitive face object defined by the + //! owner theOwnerId, the array of points thePoints, and + //! the sensitivity type theType. + //! The array of points is the outer polygon of the geometric face. + Standard_EXPORT Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints, + const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR); + + //! Initializes the given array theHArrayOfPnt by 3d + //! coordinates of vertices of the face + Standard_EXPORT void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt); + + //! Checks whether the face overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Returns bounding box of the face. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of the face. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Builds BVH tree for the face + Standard_EXPORT virtual void BVH() Standard_OVERRIDE; + + //! Returns the amount of sub-entities (points or planar convex polygons) + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveFace) + +private: + + Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: interior or boundary + NCollection_Handle myFacePoints; //!< Wrapper for overlap detection created depending on sensitivity type +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveFace, Select3D_SensitiveEntity) + +#endif // _Select3D_SensitiveFace_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveGroup.cdl b/src/Select3D/Select3D_SensitiveGroup.cdl deleted file mode 100644 index 7e8a0e11dd..0000000000 --- a/src/Select3D/Select3D_SensitiveGroup.cdl +++ /dev/null @@ -1,150 +0,0 @@ --- Created on: 1998-04-16 --- Created by: Robert COUBLANC --- Copyright (c) 1998-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveGroup from Select3D inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define selection of a sensitive group - -- by a sensitive entity which is a set of 3D sensitive entities. - -- Remark: 2 modes are possible for rectangle selection - -- the group is considered selected - -- 1) when all the entities inside are selected in the rectangle - -- 2) only one entity inside is selected by the rectangle - -- By default the "Match All entities" mode is set. - -uses - Pnt from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - SensitiveEntity from Select3D, - ListOfSensitive from Select3D, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt2d from TColgp, - Box2d from Bnd, - Location from TopLoc - - -is - - Create (OwnerId : EntityOwner from SelectBasics; - MatchAll : Boolean from Standard = Standard_True) - returns SensitiveGroup from Select3D; - ---Purpose: Constructs an empty sensitive group object. - -- This is a set of sensitive 3D entities. The sensitive - -- entities will be defined using the function Add to fill - -- the entity owner OwnerId. If MatchAll is false, nothing can be added. - - Create(OwnerId : EntityOwner from SelectBasics; - TheList : in out ListOfSensitive from Select3D; - MatchAll : Boolean from Standard = Standard_True) - returns SensitiveGroup from Select3D; - ---Purpose: Constructs a sensitive group object defined by the list - -- TheList and the entity owner OwnerId. If MatchAll is false, nothing is done. - - Add (me :mutable; LL: in out ListOfSensitive from Select3D); - ---Purpose: Adds the list of sensitive entities LL to the empty - -- sensitive group object created at construction time. - - Add (me :mutable;aSensitive : SensitiveEntity from Select3D); - ---Purpose: Adds the sensitive entity aSensitive to the non-empty - -- sensitive group object created at construction time. - - Remove(me:mutable; aSensitive :SensitiveEntity from Select3D); - - Clear(me:mutable) ; - ---Purpose: Removes all sensitive entities from the list used at the - -- time of construction, or added using the function Add. - - IsIn(me;aSensitive: SensitiveEntity from Select3D) - returns Boolean from Standard; - ---Purpose: Returns true if the sensitive entity aSensitive is in - -- the list used at the time of construction, or added using the function Add. - Set(me:mutable; MustMatchAllEntities: Boolean from Standard); - ---Purpose: Sets the requirement that all sensitive entities in the - -- list used at the time of construction, or added using - -- the function Add must be matched. - ---C++: inline - MustMatchAll(me) returns Boolean from Standard; - ---Purpose: Returns true if all sensitive entities in the list used - -- at the time of construction, or added using the function Add must be matched. - ---C++: inline - - - - - Project (me:mutable;aProjector : Projector from Select3D) - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) - is redefined static; - ---Level: Public - ---Purpose: gives the 2D boxes which represent the segment in the - -- selection process... - - - MaxBoxes(me) returns Integer from Standard is redefined static; - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - - SetLocation(me:mutable;aLoc:Location from TopLoc) is redefined static; - ---Purpose: propagation of location on all the sensitive inside... - ResetLocation(me:mutable) is redefined static; - ---Purpose: propagation of location on all the sensitive inside... - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; - ---Purpose: Sets the owner for all entities in group - - GetEntities(me) - returns ListOfSensitive from Select3D; - ---Purpose: Gets group content - ---C++: inline - ---C++: return const& - - -fields - myList : ListOfSensitive from Select3D; - myMustMatchAll : Boolean from Standard; -end SensitiveGroup; - diff --git a/src/Select3D/Select3D_SensitiveGroup.cxx b/src/Select3D/Select3D_SensitiveGroup.cxx index 07e9be2fdc..583edf04c3 100644 --- a/src/Select3D/Select3D_SensitiveGroup.cxx +++ b/src/Select3D/Select3D_SensitiveGroup.cxx @@ -14,84 +14,129 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include #include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveGroup, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveGroup, Select3D_SensitiveEntity) //======================================================================= //function : Creation -//purpose : +//purpose : //======================================================================= -Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Standard_Boolean MatchAll): -Select3D_SensitiveEntity(OwnerId), -myMustMatchAll(MatchAll) -{ -} +Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Boolean theIsMustMatchAll) +: Select3D_SensitiveSet (theOwnerId), + myMustMatchAll (theIsMustMatchAll), + myCenter (0.0, 0.0, 0.0) {} //======================================================================= //function : Creation -//purpose : +//purpose : //======================================================================= - -Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId, - Select3D_ListOfSensitive& TheList, - const Standard_Boolean MatchAll): -Select3D_SensitiveEntity(OwnerId), -myMustMatchAll(MatchAll) +Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId, + Select3D_EntitySequence& theEntities, + const Standard_Boolean theIsMustMatchAll) +: Select3D_SensitiveSet (theOwnerId), + myMustMatchAll (theIsMustMatchAll) { - myList.Append(TheList); -} + myCenter = gp_Pnt (0.0, 0.0, 0.0); -//======================================================================= -//function : Add -//purpose : No control of entities inside -//======================================================================= - -void Select3D_SensitiveGroup::Add(Select3D_ListOfSensitive& LL) -{myList.Append(LL);} - -//======================================================================= -//function : Add -//purpose : -//======================================================================= - -void Select3D_SensitiveGroup::Add(const Handle(Select3D_SensitiveEntity)& aSensitive) -{ - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) + for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next()) { - if(It.Value()==aSensitive) return; + const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value(); + myEntities.Append (anEntity); + myBndBox.Combine (anEntity->BoundingBox()); + myBVHPrimIndexes.Append (myEntities.Size()); + myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ(); + } + + myCenter.ChangeCoord().Divide (static_cast (myEntities.Size())); + + MarkDirty(); +} + +//======================================================================= +//function : Add +//purpose : No control of entities inside +//======================================================================= +void Select3D_SensitiveGroup::Add (Select3D_EntitySequence& theEntities) +{ + gp_Pnt aCent (0.0, 0.0, 0.0); + for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next()) + { + myEntities.Append (anIter.Value()); + myBndBox.Combine (anIter.Value()->BoundingBox()); + myBVHPrimIndexes.Append (myEntities.Size()); + aCent.ChangeCoord() += anIter.Value()->CenterOfGeometry().XYZ(); + } + aCent.ChangeCoord().Divide (myEntities.Length()); + myCenter = (myCenter.XYZ() + aCent.XYZ()).Multiplied (0.5); +} + +//======================================================================= +//function : Add +//purpose : +//======================================================================= +void Select3D_SensitiveGroup::Add (const Handle(Select3D_SensitiveEntity)& theSensitive) +{ + for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next()) + { + if (anIter.Value() == theSensitive) + return; + } + myEntities.Append (theSensitive); + myBVHPrimIndexes.Append (myEntities.Size()); + myBndBox.Combine (theSensitive->BoundingBox()); + myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ(); + if (myEntities.First() != myEntities.Last()) + { + myCenter.ChangeCoord().Multiply (0.5); } - myList.Append(aSensitive); } //======================================================================= //function : Remove -//purpose : +//purpose : //======================================================================= - -void Select3D_SensitiveGroup::Remove(const Handle(Select3D_SensitiveEntity)& aSensitive) +void Select3D_SensitiveGroup::Remove (const Handle(Select3D_SensitiveEntity)& theSensitive) { - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) + Standard_Boolean isSensitiveRemoved = Standard_False; + for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next()) { - if(It.Value()==aSensitive) + if (anIter.Value() == theSensitive) { - myList.Remove(It); - return; + myEntities.Remove (anIter); + isSensitiveRemoved = Standard_True; + break; } } + + if (isSensitiveRemoved) + { + myBndBox.Clear(); + myCenter = gp_Pnt (0.0, 0.0, 0.0); + myBVHPrimIndexes.Clear(); + for (Standard_Integer anIdx = 1; anIdx <= myEntities.Size(); ++anIdx) + { + myBndBox.Combine (myEntities.Value (anIdx)->BoundingBox()); + myCenter.ChangeCoord() += myEntities.Value (anIdx)->CenterOfGeometry().XYZ(); + myBVHPrimIndexes.Append (anIdx); + } + myCenter.ChangeCoord().Divide (static_cast (myEntities.Size())); + } } //======================================================================= //function : IsIn -//purpose : +//purpose : //======================================================================= - -Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEntity)& aSensitive) const +Standard_Boolean Select3D_SensitiveGroup::IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const { - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) + for(Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next()) { - if(It.Value()==aSensitive) + if (anIter.Value() == theSensitive) return Standard_True; } return Standard_False; @@ -99,224 +144,192 @@ Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEn //======================================================================= //function : Clear -//purpose : +//purpose : //======================================================================= void Select3D_SensitiveGroup::Clear() -{myList.Clear();} - -//======================================================================= -//function : Project -//purpose : -//======================================================================= - -void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector) { - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - It.Value()->Project(aProjector); - } + myEntities.Clear(); + myBndBox.Clear(); + myCenter = gp_Pnt (0.0, 0.0, 0.0); + myEntities.Clear(); } //======================================================================= -//function : Areas -//purpose : +// function : NbSubElements +// purpose : Returns the amount of sub-entities //======================================================================= - -void Select3D_SensitiveGroup::Areas(SelectBasics_ListOfBox2d& boxes) +Standard_Integer Select3D_SensitiveGroup::NbSubElements() { - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - It.Value()->Areas(boxes); - } + return myEntities.Size(); } //======================================================================= //function : GetConnected -//purpose : +//purpose : //======================================================================= -Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected(const TopLoc_Location& aLocation) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected() { - Handle(Select3D_SensitiveGroup) newgroup = new Select3D_SensitiveGroup(myOwnerId,myMustMatchAll); - Select3D_ListOfSensitive LL; - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) + Handle(Select3D_SensitiveGroup) aNewEntity = new Select3D_SensitiveGroup (myOwnerId, myMustMatchAll); + Select3D_EntitySequence aConnectedEnt; + for (Select3D_EntitySequenceIter It (myEntities); It.More(); It.Next()) { - LL.Append(It.Value()->GetConnected(aLocation)); + aConnectedEnt.Append (It.Value()->GetConnected()); } - newgroup->Add(LL); - return newgroup; -} - -//======================================================================= -//function : SetLocation -//purpose : -//======================================================================= - -void Select3D_SensitiveGroup::SetLocation(const TopLoc_Location& aLoc) -{ - if(aLoc.IsIdentity()) return; - - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - It.Value()->SetLocation(aLoc); - } - - if(HasLocation()) - if(aLoc == Location()) return; - - Select3D_SensitiveEntity::SetLocation(aLoc); - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - if(It.Value()->HasLocation()) - { - if(It.Value()->Location()!=aLoc) - It.Value()->SetLocation(It.Value()->Location()*aLoc); - } - else - It.Value()->SetLocation(aLoc); - } -} - -//======================================================================= -//function : ResetLocation -//purpose : -//======================================================================= - -void Select3D_SensitiveGroup::ResetLocation() -{ - if(!HasLocation()) return; - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - if(It.Value()->HasLocation() && It.Value()->Location()!=Location()) - It.Value()->SetLocation(It.Value()->Location()*Location().Inverted()); - else - It.Value()->ResetLocation(); - } - Select3D_SensitiveEntity::ResetLocation(); + aNewEntity->Add (aConnectedEnt); + return aNewEntity; } //======================================================================= //function : Matches -//purpose : +//purpose : //======================================================================= - -Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) +Standard_Boolean Select3D_SensitiveGroup::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - theMatchDMin = RealLast(); - theMatchDepth = RealLast(); - Standard_Real aChildDMin, aChildDepth; - Standard_Boolean isMatched = Standard_False; + if (!myMustMatchAll + || theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point) + return Select3D_SensitiveSet::Matches (theMgr, thePickResult); - Select3D_ListIteratorOfListOfSensitive anIt (myList); - for (; anIt.More(); anIt.Next()) + Standard_Real aDepth = RealLast(); + Standard_Real aDistToCOG = RealLast(); + + for (Select3D_EntitySequenceIter anIt (myEntities); anIt.More(); anIt.Next()) { - Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value(); - if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth)) + SelectBasics_PickResult aMatchResult; + Handle(SelectBasics_SensitiveEntity)& aChild = anIt.ChangeValue(); + if (!aChild->Matches (theMgr, aMatchResult)) { - continue; + aMatchResult = SelectBasics_PickResult (RealLast(), RealLast()); + return Standard_False; } - if (!isMatched) - { - theMatchDMin = aChildDMin; - isMatched = Standard_True; - } - - theMatchDepth = Min (aChildDepth, theMatchDepth); + aDepth = Min (aMatchResult.Depth(), aDepth); } - return isMatched; -} + aDistToCOG = theMgr.DistToGeometryCenter (CenterOfGeometry()); + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); -//======================================================================= -//function : Matches -//purpose : si on doit tout matcher, on ne repond oui que si toutes -// les primitives repondent oui -//======================================================================= -Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Standard_Boolean result(Standard_True); - - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - if(It.Value()->Matches(XMin,YMin,XMax,YMax,aTol)) - { - if(!myMustMatchAll) - return Standard_True; - } - // ca ne matches pas.. - else - { - if(myMustMatchAll) - return Standard_False; - else - result = Standard_False; - } - } - return result; -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveGroup:: -Matches (const TColgp_Array1OfPnt2d& aPoly, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Standard_Boolean result(Standard_True); - - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - if(It.Value()->Matches(aPoly, aBox, aTol)) - { - if(!myMustMatchAll) - return Standard_True; - } - else - { - if(myMustMatchAll) - return Standard_False; - else - result = Standard_False; - } - } - return result; -} - -//======================================================================= -//function : MaxBoxes -//purpose : -//======================================================================= - -Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const -{ - Standard_Integer nbboxes(0); - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){ - nbboxes+=It.Value()->MaxBoxes(); - } - return nbboxes; + return Standard_True; } //======================================================================= //function : Set -//purpose : +//purpose : //======================================================================= - -void Select3D_SensitiveGroup::Set - (const Handle(SelectBasics_EntityOwner)& TheOwnerId) +void Select3D_SensitiveGroup::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId) { - Select3D_SensitiveEntity::Set(TheOwnerId); + Select3D_SensitiveEntity::Set (theOwnerId); // set TheOwnerId for each element of sensitive group - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - It.Value()->Set(TheOwnerId); + for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next()) + anIter.Value()->Set (theOwnerId); +} + +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of the group. If location +// transformation is set, it will be applied +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveGroup::BoundingBox() +{ + if (myBndBox.IsValid()) + return myBndBox; + + // do not apply the transformation because sensitives AABBs + // are already transformed + for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next()) + { + myBndBox.Combine (anIter.Value()->BoundingBox()); + } + + return myBndBox; +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of group. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveGroup::CenterOfGeometry() const +{ + return myCenter; +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of sensitive entity with index theIdx +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveGroup::Box (const Standard_Integer theIdx) const +{ + const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx); + return myEntities.Value (anElemIdx)->BoundingBox(); +} + +//======================================================================= +// function : Center +// purpose : Returns geometry center of sensitive entity with index +// theIdx in the vector along the given axis theAxis +//======================================================================= +Standard_Real Select3D_SensitiveGroup::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx); + const gp_Pnt aCenter = myEntities.Value (anElemIdx)->CenterOfGeometry(); + return theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z()); +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector +//======================================================================= +void Select3D_SensitiveGroup::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + const Standard_Integer anEntIdx1 = myBVHPrimIndexes.Value (theIdx1); + const Standard_Integer anEntIdx2 = myBVHPrimIndexes.Value (theIdx2); + + myBVHPrimIndexes.ChangeValue (theIdx1) = anEntIdx2; + myBVHPrimIndexes.ChangeValue (theIdx2) = anEntIdx1; +} + +//======================================================================= +// function : Size +// purpose : Returns the length of vector of sensitive entities +//======================================================================= +Standard_Integer Select3D_SensitiveGroup::Size() const +{ + return myBVHPrimIndexes.Size(); +} + +// ======================================================================= +// function : overlapsElement +// purpose : Checks whether the entity with index theIdx overlaps the +// current selecting volume +// ======================================================================= +Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) +{ + theMatchDepth = RealLast(); + const Standard_Integer aSensitiveIdx = myBVHPrimIndexes.Value (theElemIdx); + SelectBasics_PickResult aResult; + Standard_Boolean isMatching = myEntities.Value (aSensitiveIdx)->Matches (theMgr, aResult); + if (isMatching) + { + theMatchDepth = aResult.Depth(); + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : distanceToCOG +// purpose : Calculates distance from the 3d projection of used-picked +// screen point to center of the geometry +// ======================================================================= +Standard_Real Select3D_SensitiveGroup::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) +{ + return theMgr.DistToGeometryCenter (CenterOfGeometry()); } diff --git a/src/Select3D/Select3D_SensitiveGroup.hxx b/src/Select3D/Select3D_SensitiveGroup.hxx new file mode 100644 index 0000000000..bb6b681029 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveGroup.hxx @@ -0,0 +1,149 @@ +// Created on: 1998-04-16 +// Created by: Robert COUBLANC +// Copyright (c) 1998-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + + +#ifndef _Select3D_SensitiveGroup_HeaderFile +#define _Select3D_SensitiveGroup_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class TopLoc_Location; + + +//! A framework to define selection of a sensitive group +//! by a sensitive entity which is a set of 3D sensitive entities. +//! Remark: 2 modes are possible for rectangle selection +//! the group is considered selected +//! 1) when all the entities inside are selected in the rectangle +//! 2) only one entity inside is selected by the rectangle +//! By default the "Match All entities" mode is set. +class Select3D_SensitiveGroup : public Select3D_SensitiveSet +{ +public: + + //! Constructs an empty sensitive group object. + //! This is a set of sensitive 3D entities. The sensitive + //! entities will be defined using the function Add to fill + //! the entity owner OwnerId. If MatchAll is false, nothing can be added. + Standard_EXPORT Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Boolean theIsMustMatchAll = Standard_True); + + //! Constructs a sensitive group object defined by the list + //! TheList and the entity owner OwnerId. If MatchAll is false, nothing is done. + Standard_EXPORT Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId, + Select3D_EntitySequence& theEntities, + const Standard_Boolean theIsMustMatchAll = Standard_True); + + //! Adds the list of sensitive entities LL to the empty + //! sensitive group object created at construction time. + Standard_EXPORT void Add (Select3D_EntitySequence& theEntities); + + //! Adds the sensitive entity aSensitive to the non-empty + //! sensitive group object created at construction time. + Standard_EXPORT void Add (const Handle(Select3D_SensitiveEntity)& theSensitive); + + Standard_EXPORT void Remove (const Handle(Select3D_SensitiveEntity)& theSensitive); + + //! Removes all sensitive entities from the list used at the + //! time of construction, or added using the function Add. + Standard_EXPORT void Clear(); + + //! Returns true if the sensitive entity aSensitive is in + //! the list used at the time of construction, or added using the function Add. + Standard_EXPORT Standard_Boolean IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const; + + //! Sets the requirement that all sensitive entities in the + //! list used at the time of construction, or added using + //! the function Add must be matched. + void SetMatchType (const Standard_Boolean theIsMustMatchAll); + + //! Returns true if all sensitive entities in the list used + //! at the time of construction, or added using the function Add must be matched. + Standard_Boolean MustMatchAll() const; + + //! Checks whether the group overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the amount of sub-entities + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Sets the owner for all entities in group + Standard_EXPORT void Set (const Handle(SelectBasics_EntityOwner)& theOwnerId); + + //! Gets group content + const Select3D_EntitySequence& GetEntities() const; + + //! Returns bounding box of the group. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of entity set. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Returns bounding box of sensitive entity with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns geometry center of sensitive entity index theIdx in + //! the vector along the given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in the vector + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Returns the length of vector of sensitive entities + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveGroup) + +private: + + //! Checks whether the entity with index theIdx overlaps the current selecting volume + virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) Standard_OVERRIDE; + + //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry + virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; + +private: + + Select3D_EntitySequence myEntities; //!< Grouped sensitive entities + Standard_Boolean myMustMatchAll; //!< Determines whether all entities in the group should be overlapped or not + gp_Pnt myCenter; //!< Center of geometry of the group + mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the group + NCollection_Vector myBVHPrimIndexes; //!< Vector of sub-entities indexes for BVH tree build +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveGroup, Select3D_SensitiveEntity) + +#include + +#endif // _Select3D_SensitiveGroup_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveGroup.lxx b/src/Select3D/Select3D_SensitiveGroup.lxx index 488d2c1572..1dda86a297 100644 --- a/src/Select3D/Select3D_SensitiveGroup.lxx +++ b/src/Select3D/Select3D_SensitiveGroup.lxx @@ -14,14 +14,29 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline void Select3D_SensitiveGroup::Set(const Standard_Boolean MustMatchAllEntities) -{myMustMatchAll = MustMatchAllEntities;} +//======================================================================= +//function : SetMatchType +//purpose : +//======================================================================= +inline void Select3D_SensitiveGroup::SetMatchType (const Standard_Boolean theIsMustMatchAll) +{ + myMustMatchAll = theIsMustMatchAll; +} - -inline Standard_Boolean Select3D_SensitiveGroup::MustMatchAll() const -{return myMustMatchAll;} +//======================================================================= +//function : MustMatchAll +//purpose : +//======================================================================= +inline Standard_Boolean Select3D_SensitiveGroup::MustMatchAll() const +{ + return myMustMatchAll; +} -inline const Select3D_ListOfSensitive& Select3D_SensitiveGroup::GetEntities() const -{return myList;} - - +//======================================================================= +//function : GetEntities +//purpose : +//======================================================================= +inline const Select3D_EntitySequence& Select3D_SensitiveGroup::GetEntities() const +{ + return myEntities; +} diff --git a/src/Select3D/Select3D_SensitivePoint.cdl b/src/Select3D/Select3D_SensitivePoint.cdl deleted file mode 100644 index 56155421b4..0000000000 --- a/src/Select3D/Select3D_SensitivePoint.cdl +++ /dev/null @@ -1,104 +0,0 @@ --- Created on: 1995-02-23 --- Created by: Mister rmi --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitivePoint from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define sensitive 3D points. - -uses - Pnt from gp, - Pnt2d from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Location from TopLoc, - Box2d from Bnd, - Array1OfPnt2d from TColgp, - Pnt from Select3D, - Pnt2d from Select3D - -is - - Create (OwnerId : EntityOwner from SelectBasics; - Point : Pnt from gp) - returns SensitivePoint; - ---Purpose: Constructs a sensitive point object defined by the - -- owner OwnerId and the point Point. - - - Project (me:mutable;aProjector : Projector from Select3D) - is redefined static; - ---Level: Public - ---Purpose:Converts the stored 3D point into a 2D point according - -- to ; this method is called by the selection Manager. - - - Areas(me:mutable; aresult : in out ListOfBox2d from SelectBasics) - is redefined static; - ---Level: Public - ---Purpose: stores in the 2D sensitive box which represents - -- the point area in the selection process. - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is static; - - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard; - - - Point(me) returns Pnt from gp; - ---Purpose: Returns the point used at the time of construction. - - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - -fields - - mypoint : Pnt from Select3D; - myprojpt : Pnt2d from Select3D; - - -end SensitivePoint; - - diff --git a/src/Select3D/Select3D_SensitivePoint.cxx b/src/Select3D/Select3D_SensitivePoint.cxx index 95047eec86..8c5acb67a2 100644 --- a/src/Select3D/Select3D_SensitivePoint.cxx +++ b/src/Select3D/Select3D_SensitivePoint.cxx @@ -14,166 +14,88 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include -#include -#include -#include -#include +#include + +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitivePoint, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoint, Select3D_SensitiveEntity) //================================================== // Function: Creation // Purpose : //================================================== - -Select3D_SensitivePoint -::Select3D_SensitivePoint(const Handle(SelectBasics_EntityOwner)& anOwner, - const gp_Pnt& aPoint): -Select3D_SensitiveEntity(anOwner) +Select3D_SensitivePoint::Select3D_SensitivePoint (const Handle(SelectBasics_EntityOwner)& theOwner, + const gp_Pnt& thePoint) +: Select3D_SensitiveEntity (theOwner) { - SetSensitivityFactor(4.); - mypoint = aPoint; -} - -//================================================== -// Function: Project -// Purpose : -//================================================== - -void Select3D_SensitivePoint -::Project (const Handle(Select3D_Projector)& aProj) -{ - gp_Pnt2d aPoint2d; - if(!HasLocation()) - aProj->Project(mypoint, aPoint2d); - else - { - gp_Pnt aP(mypoint.x, mypoint.y, mypoint.z); - aProj->Project(aP.Transformed(Location().Transformation()), aPoint2d); - } - myprojpt = aPoint2d; -} - -//================================================== -// Function: Areas -// Purpose : -//================================================== - -void Select3D_SensitivePoint -::Areas(SelectBasics_ListOfBox2d& boxes) -{ - Bnd_Box2d abox; - abox.Set(myprojpt); - boxes.Append(abox); + SetSensitivityFactor (12.0); + myPoint = thePoint; } //================================================== // Function: Matches // Purpose : //================================================== - -Standard_Boolean Select3D_SensitivePoint::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) +Standard_Boolean Select3D_SensitivePoint::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - // check coordinate matching - Standard_Real aDist = gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()).Distance (myprojpt); - if (aDist > thePickArgs.Tolerance() * SensitivityFactor()) - { - return Standard_False; - } + Standard_Real aDepth = RealLast(); + Standard_Real aDistToCOG = RealLast(); + Standard_Boolean isMatched = theMgr.Overlaps (myPoint, aDepth); + if (isMatched) + aDistToCOG = aDepth; - Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine()); - if (thePickArgs.IsClipped (aDepth)) - { - return Standard_False; - } + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); - theMatchDMin = aDist; - theMatchDepth = aDepth; - return Standard_True; -} - -//================================================== -// Function: Matches -// Purpose : -//================================================== - -Standard_Boolean Select3D_SensitivePoint:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Bnd_Box2d B; - B.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax)); - B.Enlarge(aTol); - return !B.IsOut(myprojpt); -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitivePoint:: -Matches (const TColgp_Array1OfPnt2d& aPoly, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Standard_Real Umin,Vmin,Umax,Vmax; - aBox.Get(Umin,Vmin,Umax,Vmax); - CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); - - Standard_Integer RES = aClassifier2d.SiDans(myprojpt); - if(RES==1) return Standard_True; - - return Standard_False; + return isMatched; } //======================================================================= //function : Point //purpose : //======================================================================= - gp_Pnt Select3D_SensitivePoint::Point() const -{return mypoint;} +{ + return myPoint; +} //======================================================================= //function : GetConnected //purpose : //======================================================================= - -Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected(const TopLoc_Location& aLoc) +Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected() { - Handle(Select3D_SensitivePoint) NiouEnt = new Select3D_SensitivePoint(myOwnerId,mypoint); - if(HasLocation()) NiouEnt->SetLocation(Location()); - NiouEnt->UpdateLocation(aLoc); - return NiouEnt; + Handle(Select3D_SensitivePoint) aNewEntity = new Select3D_SensitivePoint (myOwnerId, myPoint); + return aNewEntity; } //======================================================================= -//function : Dump -//purpose : +// function : CenterOfGeometry +// purpose : Returns center of point. If location transformation +// is set, it will be applied //======================================================================= - -void Select3D_SensitivePoint::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const +gp_Pnt Select3D_SensitivePoint::CenterOfGeometry() const { - S<<"\tSensitivePoint 3D :"; - if(HasLocation()) - S<<"\t\tExisting Location"< +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class gp_Pnt; +class TopLoc_Location; + +//! A framework to define sensitive 3D points. +class Select3D_SensitivePoint : public Select3D_SensitiveEntity +{ +public: + + //! Constructs a sensitive point object defined by the + //! owner OwnerId and the point Point. + Standard_EXPORT Select3D_SensitivePoint (const Handle(SelectBasics_EntityOwner)& theOwnerId, const gp_Pnt& thePoint); + + //! Returns the amount of sub-entities in sensitive + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Checks whether the point overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the point used at the time of construction. + Standard_EXPORT gp_Pnt Point() const; + + //! Returns center of point. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Returns bounding box of the point. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitivePoint) + +private: + + gp_Pnt myPoint; //!< 3d coordinates of the point +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitivePoint, Select3D_SensitiveEntity) + +#endif // _Select3D_SensitivePoint_HeaderFile diff --git a/src/Select3D/Select3D_SensitivePoly.cdl b/src/Select3D/Select3D_SensitivePoly.cdl deleted file mode 100644 index d31a1f51bc..0000000000 --- a/src/Select3D/Select3D_SensitivePoly.cdl +++ /dev/null @@ -1,86 +0,0 @@ --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -deferred class SensitivePoly from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: Sensitive Entity to make a face selectable. - -- In some cases this class can raise Standard_ConstructionError and - -- Standard_OutOfRange exceptions from its member Select3D_PointData - -- mypolyg. - -uses - EntityOwner from SelectBasics, - Projector from Select3D, - ListOfBox2d from SelectBasics, - Array1OfPnt from TColgp, - HArray1OfPnt from TColgp, - Array1OfPnt2d from TColgp, - Box2d from Select3D, - PointData from Select3D - -raises - ConstructionError from Standard, - OutOfRange from Standard - -is - - Initialize (OwnerId : EntityOwner from SelectBasics; - ThePoints : Array1OfPnt from TColgp) - returns SensitivePoly; - ---Level: Public - ---Purpose: Constructs a sensitive face object defined by the - -- owner OwnerId, the array of points ThePoints, and - -- the sensitivity type Sensitivity. - -- The array of points is the outer polygon of the geometric face. - - Initialize (OwnerId : EntityOwner from SelectBasics; - ThePoints : HArray1OfPnt from TColgp) - returns SensitivePoly; - ---Level: Public - ---Purpose: Constructs a sensitive face object defined by the - -- owner OwnerId, the array of points ThePoints, and - -- the sensitivity type Sensitivity. - -- The array of points is the outer polygon of the geometric face. - - Initialize(OwnerId : EntityOwner from SelectBasics; - NbOfPoints : Integer = 6) - returns SensitivePoly; - ---Level: Public - ---Purpose: Constructs the sensitive circle object defined by the - -- owner OwnerId, the circle Circle, the Boolean - -- FilledCircle and the number of points NbOfPoints. - - Project (me:mutable;aProjector : Projector from Select3D) is redefined virtual; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) is redefined static; - ---Level: Public - ---Purpose: stores in the 2D Boxes which represent the sensitive face - -- in the selection algorithm. - - Points3D(me:mutable; theHArrayOfPnt : in out HArray1OfPnt from TColgp); - ---Purpose: Returns the 3D points of the array used at construction time. - ---C++: inline - - Points2D(me:mutable; theArrayOfPnt2d : in out Array1OfPnt2d from TColgp); - ---Purpose: Returns the 2D points of the array used at construction time. - ---C++: inline - -fields - - mybox2d : Box2d from Select3D is protected; - mypolyg : PointData from Select3D is protected; -end SensitivePoly; diff --git a/src/Select3D/Select3D_SensitivePoly.cxx b/src/Select3D/Select3D_SensitivePoly.cxx index 6847e2d44d..3a161fd96f 100644 --- a/src/Select3D/Select3D_SensitivePoly.cxx +++ b/src/Select3D/Select3D_SensitivePoly.cxx @@ -11,93 +11,268 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include #include -#include -#include -#include #include +#include + +#include + +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitivePoly, Select3D_SensitiveSet) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly, Select3D_SensitiveSet) //================================================== -// Function: faire disparaitre ce constructeur a la prochaine version... -// Purpose : simplement garde pour ne pas perturber la version update -//================================================== - -Select3D_SensitivePoly:: -Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId, - const TColgp_Array1OfPnt& ThePoints): -Select3D_SensitiveEntity(OwnerId), -mypolyg(ThePoints.Upper()-ThePoints.Lower()+1) -{ - for (Standard_Integer theIndex = 0 ; theIndex < mypolyg.Size(); ++theIndex) - mypolyg.SetPnt(theIndex, ThePoints.Value(ThePoints.Lower()+theIndex)); -} - -//================================================== -// Function: Creation +// Function: Select3D_SensitivePoly // Purpose : //================================================== - -Select3D_SensitivePoly:: -Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(TColgp_HArray1OfPnt)& ThePoints): -Select3D_SensitiveEntity(OwnerId), -mypolyg(ThePoints->Upper()-ThePoints->Lower()+1) +Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints, + const Standard_Boolean theIsBVHEnabled) +: Select3D_SensitiveSet (theOwnerId), + myPolyg (thePoints.Upper() - thePoints.Lower() + 1) { - for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); theIndex++) - mypolyg.SetPnt(theIndex, ThePoints->Value(ThePoints->Lower()+theIndex)); -} + Standard_Integer aLowerIdx = thePoints.Lower(); + Standard_Integer anUpperIdx = thePoints.Upper(); + gp_XYZ aPntSum (0.0, 0.0, 0.0); -//================================================== -// Function: Creation -// Purpose : -//================================================== - -Select3D_SensitivePoly:: -Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Standard_Integer NbPoints): -Select3D_SensitiveEntity(OwnerId), -mypolyg(NbPoints) -{ -} - -//================================================== -// Function: Project -// Purpose : -//================================================== - -void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj) -{ - mybox2d.SetVoid(); - - Standard_Boolean hasloc = HasLocation(); - gp_Pnt2d aPnt2d; - gp_Pnt aPnt; - for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); ++theIndex) + Select3D_BndBox3d aBndBox; + for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx) { - aPnt = mypolyg.Pnt(theIndex); - if (hasloc) + aPntSum += thePoints.Value (aIdx).XYZ(); + const SelectMgr_Vec3 aPnt (thePoints.Value (aIdx).X(), + thePoints.Value (aIdx).Y(), + thePoints.Value (aIdx).Z()); + aBndBox.Add (aPnt); + myPolyg.SetPnt (aIdx - aLowerIdx, thePoints.Value (aIdx)); + } + + myBndBox = aBndBox; + myCOG = aPntSum / myPolyg.Size(); + + if (theIsBVHEnabled) + { + const Standard_Integer aPntsNum = myPolyg.Size(); + mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2); + for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter) { - aProj->Project(aPnt.Transformed(Location().Transformation()), aPnt2d); + mySegmentIndexes->SetValue (aSegmIter, aSegmIter); } - else - { - aProj->Project(aPnt, aPnt2d); - } - mybox2d.Update(aPnt2d); - mypolyg.SetPnt2d(theIndex, aPnt2d); } } //================================================== -// Function: Areas +// Function: Select3D_SensitivePoly // Purpose : //================================================== -void Select3D_SensitivePoly -::Areas(SelectBasics_ListOfBox2d& aSeq) +Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints, + const Standard_Boolean theIsBVHEnabled) +: Select3D_SensitiveSet (theOwnerId), + myPolyg (thePoints->Upper() - thePoints->Lower() + 1) { - aSeq.Append(mybox2d); + Standard_Integer aLowerIdx = thePoints->Lower(); + Standard_Integer anUpperIdx = thePoints->Upper(); + gp_XYZ aPntSum (0.0, 0.0, 0.0); + + Select3D_BndBox3d aBndBox; + for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx) + { + aPntSum += thePoints->Value (aIdx).XYZ(); + const SelectMgr_Vec3 aPnt (thePoints->Value (aIdx).X(), + thePoints->Value (aIdx).Y(), + thePoints->Value (aIdx).Z()); + aBndBox.Add (aPnt); + myPolyg.SetPnt (aIdx - aLowerIdx, thePoints->Value (aIdx)); + } + + myBndBox = aBndBox; + myCOG = aPntSum / myPolyg.Size(); + + if (theIsBVHEnabled) + { + const Standard_Integer aPntsNum = myPolyg.Size(); + mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2); + for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter) + { + mySegmentIndexes->SetValue (aSegmIter, aSegmIter); + } + } } +//================================================== +// Function: Creation +// Purpose : +//================================================== +Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Boolean theIsBVHEnabled, + const Standard_Integer theNbPnts) +: Select3D_SensitiveSet (theOwnerId), + myPolyg (theNbPnts) +{ + if (theIsBVHEnabled) + { + mySegmentIndexes = new TColStd_HArray1OfInteger (0, theNbPnts - 2); + for (Standard_Integer aIdx = 0; aIdx < theNbPnts - 1; ++aIdx) + { + mySegmentIndexes->SetValue (aIdx, aIdx); + } + } + myCOG = gp_Pnt (RealLast(), RealLast(), RealLast()); +} + +//================================================== +// function : BoundingBox +// purpose : Returns bounding box of a polygon. If location +// transformation is set, it will be applied +//================================================== +Select3D_BndBox3d Select3D_SensitivePoly::BoundingBox() +{ + if (myBndBox.IsValid()) + return myBndBox; + + Select3D_BndBox3d aBndBox; + for (Standard_Integer aPntIter = 0; aPntIter < myPolyg.Size(); ++aPntIter) + { + SelectMgr_Vec3 aPnt (myPolyg.Pnt (aPntIter).x, + myPolyg.Pnt (aPntIter).y, + myPolyg.Pnt (aPntIter).z); + aBndBox.Add (aPnt); + } + + myBndBox = aBndBox; + + return myBndBox; +} + +//================================================== +// Function: Size +// Purpose : Returns the amount of segments of +// the poly +//================================================== +Standard_Integer Select3D_SensitivePoly::Size() const +{ + if (!mySegmentIndexes.IsNull()) + return mySegmentIndexes->Length(); + + return -1; +} + +//================================================== +// Function: Box +// Purpose : Returns bounding box of segment with +// index theIdx +//================================================== +Select3D_BndBox3d Select3D_SensitivePoly::Box (const Standard_Integer theIdx) const +{ + if (mySegmentIndexes.IsNull()) + return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast())); + + const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theIdx); + gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx); + gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1); + + const SelectMgr_Vec3 aMinPnt (Min (aPnt1.X(), aPnt2.X()), + Min (aPnt1.Y(), aPnt2.Y()), + Min (aPnt1.Z(), aPnt2.Z())); + const SelectMgr_Vec3 aMaxPnt (Max (aPnt1.X(), aPnt2.X()), + Max (aPnt1.Y(), aPnt2.Y()), + Max (aPnt1.Z(), aPnt2.Z())); + + return Select3D_BndBox3d (aMinPnt, aMaxPnt); +} + +//================================================== +// Function: Center +// Purpose : Returns geometry center of sensitive +// entity index theIdx in the vector along +// the given axis theAxis +//================================================== +Standard_Real Select3D_SensitivePoly::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + if (mySegmentIndexes.IsNull()) + return RealLast(); + + const Select3D_BndBox3d aBndBox = Box (theIdx); + const SelectMgr_Vec3& aCenter = (aBndBox.CornerMin() + aBndBox.CornerMax()) * 0.5; + return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z()); +} + +//================================================== +// Function: Swap +// Purpose : Swaps items with indexes theIdx1 and +// theIdx2 in the vector +//================================================== +void Select3D_SensitivePoly::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + if (mySegmentIndexes.IsNull()) + return; + + const Standard_Integer aSegmentIdx1 = mySegmentIndexes->Value (theIdx1); + const Standard_Integer aSegmentIdx2 = mySegmentIndexes->Value (theIdx2); + mySegmentIndexes->ChangeValue (theIdx1) = aSegmentIdx2; + mySegmentIndexes->ChangeValue (theIdx2) = aSegmentIdx1; + return; +} + +//================================================== +// Function: overlapsElement +// Purpose : Checks whether the segment with index +// theIdx overlaps the current selecting +// volume +//================================================== +Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) +{ + if (mySegmentIndexes.IsNull()) + return Standard_False; + + const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx); + gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx); + gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1); + + return theMgr.Overlaps (aPnt1, aPnt2, theMatchDepth); +} + +//================================================== +// Function: distanceToCOG +// Purpose : Calculates distance from the 3d +// projection of used-picked screen point +// to center of the geometry +//================================================== +Standard_Real Select3D_SensitivePoly::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) +{ + if (myCOG.X() == RealLast() && myCOG.Y() == RealLast() && myCOG.Z() == RealLast()) + { + gp_XYZ aCenter (0.0, 0.0, 0.0); + for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx) + { + aCenter += myPolyg.Pnt (aIdx); + } + myCOG = aCenter / myPolyg.Size(); + } + + return theMgr.DistToGeometryCenter (myCOG); +} + +//================================================== +// Function: NbSubElements +// Purpose : Returns the amount of segments in poly +//================================================== +Standard_Integer Select3D_SensitivePoly::NbSubElements() +{ + return myPolyg.Size(); +} + +//================================================== +// Function: CenterOfGeometry +// Purpose : Returns center of the point set. If +// location transformation is set, it will +// be applied +//================================================== +gp_Pnt Select3D_SensitivePoly::CenterOfGeometry() const +{ + return myCOG; +} diff --git a/src/Select3D/Select3D_SensitivePoly.hxx b/src/Select3D/Select3D_SensitivePoly.hxx new file mode 100644 index 0000000000..b92f9848ee --- /dev/null +++ b/src/Select3D/Select3D_SensitivePoly.hxx @@ -0,0 +1,125 @@ +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitivePoly_HeaderFile +#define _Select3D_SensitivePoly_HeaderFile + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +class Standard_ConstructionError; +class Standard_OutOfRange; +class SelectBasics_EntityOwner; +class TColgp_Array1OfPnt; +class TColgp_HArray1OfPnt; + +//! Sensitive Entity to make a face selectable. +//! In some cases this class can raise Standard_ConstructionError and +//! Standard_OutOfRange exceptions from its member Select3D_PointData +//! myPolyg. +class Select3D_SensitivePoly : public Select3D_SensitiveSet +{ +public: + + //! Constructs a sensitive face object defined by the + //! owner OwnerId, the array of points ThePoints, and + //! the sensitivity type Sensitivity. + //! The array of points is the outer polygon of the geometric face. + Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const TColgp_Array1OfPnt& thePoints, + const Standard_Boolean theIsBVHEnabled); + + //! Constructs a sensitive face object defined by the + //! owner OwnerId, the array of points ThePoints, and + //! the sensitivity type Sensitivity. + //! The array of points is the outer polygon of the geometric face. + Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(TColgp_HArray1OfPnt)& thePoints, + const Standard_Boolean theIsBVHEnabled); + + //! Constructs the sensitive circle object defined by the + //! owner OwnerId, the circle Circle, the Boolean + //! FilledCircle and the number of points NbOfPoints. + Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Boolean theIsBVHEnabled, + const Standard_Integer theNbPnts = 6); + + //! Returns the amount of segments in poly + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + //! Returns the 3D points of the array used at construction time. + Standard_EXPORT void Points3D (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt); + + //! Returns bounding box of a polygon. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of the point set. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Returns the amount of segments of the poly + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns bounding box of segment with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns geometry center of sensitive entity index theIdx in the vector along + //! the given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in the vector + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI (Select3D_SensitivePoly) + +private: + + //! Checks whether the segment with index theIdx overlaps the current selecting volume + virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) Standard_OVERRIDE; + + //! Calculates distance from the 3d projection of used-picked screen point + //! to center of the geometry + virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; + +protected: + + Select3D_PointData myPolyg; //!< Points of the poly + mutable gp_Pnt myCOG; //!< Center of the poly + Handle_TColStd_HArray1OfInteger mySegmentIndexes; //!< Segment indexes for BVH tree build + Select3D_BndBox3d myBndBox; //!< Bounding box of the poly +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitivePoly, Select3D_SensitiveSet) + +#include + +#endif // _Select3D_SensitivePoly_HeaderFile diff --git a/src/Select3D/Select3D_SensitivePoly.lxx b/src/Select3D/Select3D_SensitivePoly.lxx index 4acf436422..4cc28175ca 100644 --- a/src/Select3D/Select3D_SensitivePoly.lxx +++ b/src/Select3D/Select3D_SensitivePoly.lxx @@ -12,28 +12,19 @@ // commercial license or contractual agreement. #include -#include #include #include -inline void Select3D_SensitivePoly -::Points3D( Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt ) +//================================================== +// Function: Points3D +// Purpose : +//================================================== +inline void Select3D_SensitivePoly::Points3D (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) { - Standard_Integer aSize = mypolyg.Size(); - theHArrayOfPnt = new TColgp_HArray1OfPnt(1,aSize); + Standard_Integer aSize = myPolyg.Size(); + theHArrayOfPnt = new TColgp_HArray1OfPnt (1,aSize); for(Standard_Integer anIndex = 1; anIndex <= aSize; anIndex++) { - theHArrayOfPnt->SetValue(anIndex, mypolyg.Pnt(anIndex-1)); + theHArrayOfPnt->SetValue (anIndex, myPolyg.Pnt (anIndex-1)); } } - -inline void Select3D_SensitivePoly -::Points2D( TColgp_Array1OfPnt2d& aArrayOf2dPnt) -{ - for(Standard_Integer anIndex = 1; anIndex <= mypolyg.Size(); anIndex++) - { - aArrayOf2dPnt.SetValue(anIndex, mypolyg.Pnt2d(anIndex-1)); - } -} - - diff --git a/src/Select3D/Select3D_SensitiveSegment.cdl b/src/Select3D/Select3D_SensitiveSegment.cdl deleted file mode 100644 index 3f5c13d380..0000000000 --- a/src/Select3D/Select3D_SensitiveSegment.cdl +++ /dev/null @@ -1,162 +0,0 @@ --- Created on: 1995-01-24 --- Created by: Mister rmi --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveSegment from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define sensitive zones along a segment - -- One gives the 3D start and end point; - -- the maximum number of 2D boxes given - -- by this entity may be set by the user - -- if the projected segment is - -- vertical or horizontal, one needs only 1 box. - -- for a pi/4 angle -> MaxNumber 2D boxes - -uses - Pnt from gp, - Pnt2d from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt2d from TColgp, - Box2d from Bnd, - Location from TopLoc, - Pnt from Select3D, - Pnt2d from Select3D - - -is - - - Create (OwnerId : EntityOwner from SelectBasics; - FirstP,LastP : Pnt from gp; - MaxRect : Integer = 1) - returns SensitiveSegment; - ---Purpose: Constructs the sensitive segment object defined by - -- the owner OwnerId, the points FirstP, LastP and the - -- maximum number of sensitive bounding boxes MaxRect. - - Set (me:mutable; MaxRect : Integer) is static; - ---Purpose: Sets the maximum number of sensitive rectangles MaxRect. - ---C++: inline - - - - StartPoint (me : mutable ; aPt : Pnt from gp) is static; - ---Level: Public - ---Purpose: changes the start Point of the Segment; - ---C++: inline - - - - EndPoint (me : mutable ; aPt : Pnt from gp) is static; - ---Level: Public - ---Purpose: changes the end point of the segment - ---C++: inline - - - StartPoint (me) returns Pnt from gp is static; - ---Level: Public - ---Purpose: gives the 3D start Point of the Segment - ---C++: inline - - - EndPoint(me) returns Pnt from gp is static; - ---Level: Public - ---Purpose: gives the 3D End Point of the Segment - ---C++: inline - - StartPoint2d (me) returns Pnt2d from gp is static; - ---Level: Public - ---Purpose: gives the 3D start Point of the Segment - ---C++: inline - - - EndPoint2d(me) returns Pnt2d from gp is static; - ---Level: Public - ---Purpose: gives the 3D End Point of the Segment - ---C++: inline - - Project (me:mutable;aProjector : Projector from Select3D) - is redefined virtual; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) - is redefined static; - ---Level: Public - ---Purpose: gives the 2D boxes which represent the segment in the - -- selection process... - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard; - - MaxBoxes(me) returns Integer is redefined static; - ---Level: Public - ---Purpose:returns - ---C++: inline - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - -fields - - mymaxrect : Integer; - mystart : Pnt from Select3D; - myend : Pnt from Select3D; - - myprojstart : Pnt2d from Select3D; -- computed at convert time - myprojend : Pnt2d from Select3D; -- computed at convert time - -end SensitiveSegment; - - - - - - - - diff --git a/src/Select3D/Select3D_SensitiveSegment.cxx b/src/Select3D/Select3D_SensitiveSegment.cxx index 5c6ea76116..867985e575 100644 --- a/src/Select3D/Select3D_SensitiveSegment.cxx +++ b/src/Select3D/Select3D_SensitiveSegment.cxx @@ -14,248 +14,94 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveSegment, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSegment, Select3D_SensitiveEntity) //===================================================== // Function : Create -// Purpose :Constructor +// Purpose : Constructor //===================================================== - -Select3D_SensitiveSegment:: -Select3D_SensitiveSegment(const Handle(SelectBasics_EntityOwner)& OwnerId, - const gp_Pnt& FirstP, - const gp_Pnt& LastP, - const Standard_Integer MaxRect): -Select3D_SensitiveEntity(OwnerId), -mymaxrect(MaxRect) +Select3D_SensitiveSegment::Select3D_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const gp_Pnt& theFirstPnt, + const gp_Pnt& theLastPnt) +: Select3D_SensitiveEntity (theOwnerId) { - mystart = FirstP; - myend = LastP; + myStart = theFirstPnt; + myEnd = theLastPnt; } -//===================================================== -// Function : -// Purpose : -//===================================================== - -void Select3D_SensitiveSegment -::Project(const Handle(Select3D_Projector)& aProj) +// ======================================================================= +// function : Matches +// purpose : Checks whether the segment overlaps current selecting volume +// ======================================================================= +Standard_Boolean Select3D_SensitiveSegment::Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) { - gp_Pnt2d aPoint2dStart; - gp_Pnt2d aPoint2dEnd; + Standard_Real aDepth = RealLast(); + Standard_Real aDistToCOG = RealLast(); + Standard_Boolean isMatched = theMgr.Overlaps (myStart, + myEnd, + aDepth); - if(HasLocation()) + if (isMatched) { - gp_Pnt aStart(mystart.x, mystart.y, mystart.z); - gp_Pnt aEnd(myend.x, myend.y, myend.z); - aProj->Project(aStart.Transformed(Location().Transformation()),aPoint2dStart); - aProj->Project(aEnd.Transformed(Location().Transformation()),aPoint2dEnd); - } - else - { - aProj->Project(mystart,aPoint2dStart); - aProj->Project(myend,aPoint2dEnd); - } - myprojstart = aPoint2dStart; - myprojend = aPoint2dEnd; -} - -//===================================================== -// Function : Areas -// Purpose : -//===================================================== - -void Select3D_SensitiveSegment -::Areas(SelectBasics_ListOfBox2d& theareas) -{ -// gp_Dir2d dy (0.,1.); - gp_Pnt2d aPStart(myprojstart.x,myprojstart.y); - if(aPStart.Distance(myprojend)<=Precision::Confusion()) - { - Bnd_Box2d curbox; - curbox.Set(myprojstart); - theareas.Append(curbox); - } - else - { - gp_Vec2d MyVec(myprojstart,myprojend);//,VAxx(gp_Dir2d(0.,1.)); - Standard_Real theangle = Abs(gp_Dir2d(0.,1.).Angle(gp_Vec2d(myprojstart,myprojend))); - if(theangle>=M_PI/2.) theangle-=M_PI/2; - if(theangle>=M_PI/12. && theangle <=5*M_PI/12.) - { - TColgp_Array1OfPnt2d BoxPoint (1,mymaxrect+1); - BoxPoint (1) = myprojstart; - BoxPoint(mymaxrect+1)=myprojend; - gp_Vec2d Vtr = MyVec/mymaxrect; - Standard_Integer i; - for ( i=2;i<=mymaxrect;i++) - { - BoxPoint (i) = BoxPoint (i-1).Translated(Vtr); - } - for (i=2;i<=mymaxrect+1;i++) - { - Bnd_Box2d curbox; - curbox.Set(BoxPoint(i-1)); - curbox.Add(BoxPoint(i)); - theareas.Append(curbox); - } - } - else - { - Bnd_Box2d curbox; - curbox.Set(myprojstart); - curbox.Add(myprojend); - theareas.Append(curbox); - } - } -} - -//===================================================== -// Function : Matches -// Purpose : -//===================================================== - -Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - gp_Pnt2d aPStart (myprojstart.x,myprojstart.y); - gp_Pnt2d aPEnd (myprojend.x,myprojend.y); - if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd, - thePickArgs.X(), - thePickArgs.Y(), - thePickArgs.Tolerance(), - theMatchDMin)) - { - return Standard_False; + gp_Pnt aCenter = CenterOfGeometry(); + aDistToCOG = theMgr.DistToGeometryCenter (aCenter); } - theMatchDepth = ComputeDepth (thePickArgs.PickLine()); + thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); - return !thePickArgs.IsClipped (theMatchDepth); + return isMatched; } -//===================================================== -// Function : Matches -// Purpose : -//===================================================== - -Standard_Boolean Select3D_SensitiveSegment:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Bnd_Box2d BoundBox; - BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol); - if(BoundBox.IsOut(myprojstart)) return Standard_False; - if( BoundBox.IsOut(myprojend)) return Standard_False; - return Standard_True; -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveSegment:: -Matches (const TColgp_Array1OfPnt2d& aPoly, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Standard_Real Umin,Vmin,Umax,Vmax; - aBox.Get(Umin,Vmin,Umax,Vmax); - CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); - - Standard_Integer RES = aClassifier2d.SiDans(myprojstart); - if (RES!=1) return Standard_False; - - RES = aClassifier2d.SiDans(myprojend); - if (RES!=1) return Standard_False; - - return Standard_True; -} - - //======================================================================= //function : GetConnected //purpose : //======================================================================= - -Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment:: -GetConnected(const TopLoc_Location& aLoc) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::GetConnected() { - Handle(Select3D_SensitiveSegment) NiouEnt = - new Select3D_SensitiveSegment(myOwnerId,mystart,myend,mymaxrect); + Handle(Select3D_SensitiveSegment) aNewEntity = + new Select3D_SensitiveSegment (myOwnerId, myStart, myEnd); - if(HasLocation()) NiouEnt->SetLocation(Location()); - NiouEnt->UpdateLocation(aLoc); - return NiouEnt; + return aNewEntity; } //======================================================================= -//function : Dump -//purpose : +// function : CenterOfGeometry +// purpose : Returns center of the segment. If location transformation +// is set, it will be applied //======================================================================= - -void Select3D_SensitiveSegment::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const +gp_Pnt Select3D_SensitiveSegment::CenterOfGeometry() const { - S<<"\tSensitivePoint 3D :"<Precision::Confusion()) - prof =val1/val2; - - if (prof==Precision::Infinite()) - { - prof= ElCLib::Parameter(EyeLine,P1); - prof = Min (prof, ElCLib::Parameter(EyeLine,P2)); - prof = Min (prof, ElCLib::Parameter(EyeLine,P3)); - } - return prof; + aPnt1 = myPolyg.Pnt (0); + aPnt2 = myPolyg.Pnt (1); + aPnt3 = myPolyg.Pnt (2); + return gp_Pnt ((aPnt1 + aPnt2 + aPnt3) / 3.0); } //================================================== // Function: GetConnected // Purpose : //================================================== - -Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle:: -GetConnected(const TopLoc_Location &theLocation) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle::GetConnected() { // Create a copy of this Handle(Select3D_SensitiveEntity) aNewEntity = - new Select3D_SensitiveTriangle(myOwnerId, mypolyg.Pnt(0), mypolyg.Pnt(1), mypolyg.Pnt(2), mytype); - - if (HasLocation()) - aNewEntity->SetLocation(Location()); - - aNewEntity->UpdateLocation(theLocation); + new Select3D_SensitiveTriangle (myOwnerId, myPolyg.Pnt(0), myPolyg.Pnt(1), myPolyg.Pnt(2), mySensType); return aNewEntity; } + +//================================================== +// Function: BoundingBox +// Purpose : Returns bounding box of the triangle. +// If location transformation is set, it +// will be applied +//================================================== +Select3D_BndBox3d Select3D_SensitiveTriangle::BoundingBox() +{ + gp_Pnt aPnt1 = myPolyg.Pnt3d (0); + gp_Pnt aPnt2 = myPolyg.Pnt3d (1); + gp_Pnt aPnt3 = myPolyg.Pnt3d (2); + const SelectMgr_Vec3 aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())), + Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())), + Min (aPnt1.Z(), Min (aPnt2.Z(), aPnt3.Z()))); + const SelectMgr_Vec3 aMaxPnt = SelectMgr_Vec3 (Max (aPnt1.X(), Max (aPnt2.X(), aPnt3.X())), + Max (aPnt1.Y(), Max (aPnt2.Y(), aPnt3.Y())), + Max (aPnt1.Z(), Max (aPnt2.Z(), aPnt3.Z()))); + return Select3D_BndBox3d (aMinPnt, aMaxPnt); +} + +//================================================== +// Function: NbSubElements +// Purpose : Returns the amount of points +//================================================== +Standard_Integer Select3D_SensitiveTriangle::NbSubElements() +{ + return 3; +} diff --git a/src/Select3D/Select3D_SensitiveTriangle.hxx b/src/Select3D/Select3D_SensitiveTriangle.hxx new file mode 100644 index 0000000000..1f17b09a08 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveTriangle.hxx @@ -0,0 +1,86 @@ +// Created on: 1997-05-14 +// Created by: Robert COUBLANC +// Copyright (c) 1997-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitiveTriangle_HeaderFile +#define _Select3D_SensitiveTriangle_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +class Standard_ConstructionError; +class Standard_OutOfRange; +class SelectBasics_EntityOwner; +class gp_Pnt; +class TColgp_Array1OfPnt2d; +class Select3D_SensitiveEntity; +class TopLoc_Location; + + +//! A framework to define selection of triangles in a view. +//! This comes into play in the detection of meshing and triangulation in surfaces. +//! In some cases this class can raise Standard_ConstructionError and +//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly. +class Select3D_SensitiveTriangle : public Select3D_SensitivePoly +{ +public: + + //! Constructs a sensitive triangle object defined by the + //! owner theOwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity. + Standard_EXPORT Select3D_SensitiveTriangle (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const gp_Pnt& thePnt0, + const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR); + + //! Checks whether the triangle overlaps current selecting volume + Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, + SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; + + //! Returns the 3D points P1, P2, P3 used at the time of construction. + Standard_EXPORT void Points3D (gp_Pnt& thePnt0, gp_Pnt& thePnt1, gp_Pnt& thePnt2) const; + + //! Returns the center point of the sensitive triangle created at construction time. + Standard_EXPORT gp_Pnt Center3D() const; + + //! Returns the copy of this + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! Returns bounding box of the triangle. If location transformation is set, it + //! will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns the amount of points + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangle) + +private: + + Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior + gp_Pnt myCentroid; //!< Center of triangle +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangle, Select3D_SensitiveEntity) + +#endif diff --git a/src/Select3D/Select3D_SensitiveTriangulation.cdl b/src/Select3D/Select3D_SensitiveTriangulation.cdl deleted file mode 100644 index b6ae0457be..0000000000 --- a/src/Select3D/Select3D_SensitiveTriangulation.cdl +++ /dev/null @@ -1,201 +0,0 @@ --- Created on: 1997-05-15 --- Created by: Robert COUBLANC --- Copyright (c) 1997-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveTriangulation from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define selection of a sensitive entity made of a set of triangles. - -uses - EntityOwner from SelectBasics, - Projector from Select3D, - Lin from gp, - Trsf from gp, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt from TColgp, - Array1OfPnt2d from TColgp, - HArray1OfInteger from TColStd, - Box2d from Bnd, - SensitiveTriangle from Select3D, - ListOfSensitiveTriangle from Select3D, - XYZ from gp, - XY from gp, - Pnt from gp, - Pnt2d from gp, - Triangulation from Poly, - Location from TopLoc -is - - Create(OwnerId : EntityOwner from SelectBasics; - aTriangulation: Triangulation from Poly; - aLoc : Location from TopLoc; - InteriorFlag : Boolean from Standard = Standard_True) - returns SensitiveTriangulation from Select3D; - - ---Purpose: Constructs a sensitive triangulation object defined by - -- the owner OwnerId, the triangulation aTriangulation, - -- the location aLoc, and the flag InteriorFlag. - - Create(OwnerId : EntityOwner from SelectBasics; - aTriangulation: Triangulation from Poly; - aLoc : Location from TopLoc; - thefreeedges : HArray1OfInteger from TColStd; - theCDG : Pnt from gp; - InteriorFlag : Boolean from Standard) - returns SensitiveTriangulation from Select3D; - ---Purpose: Constructs a sensitive triangulation object defined by - -- the owner OwnerId, the triangulation aTriangulation, - -- the location aLoc, the array of free edges - -- thefreeedges, the center of gravity theCDG, and the flag InteriorFlag. - -- As free edges and the center of gravity do not have - -- to be computed later, this syntax reduces computation time. - - - Project (me:mutable;aProjector : Projector from Select3D) is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) is redefined static; - ---Level: Public - ---Purpose: stores in the 2D Boxes which represent the sensitive face - -- in the selection algorithm. - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - ComputeDepth (me; - thePickLine : Lin from gp; - theTriangle : Integer from Standard) - returns Real from Standard; - ---Level: Public - ---Purpose: Compute precise depth of detected triangle. - -- @param thePickLine [in] the picking line. - -- @param theTriangle [in] the index of detected triangle. - -- @return depth on the picking line. - - DetectedTriangle(me) returns Integer from Standard; - ---Purpose: Returns the detected three nodes P1, P2, P3 constituting a triangle. - -- This triangle is a component of the overall sensitive - -- triangulation created at construction time. - ---C++: inline - - Triangulation(me) returns any Triangulation from Poly; - ---Purpose: Returns the triangulation used at the time of construction. - ---C++: inline - ---C++: return const & - - CDG3D(me) returns Pnt from gp; - ---Purpose: Returns the 3D center of gravity used at the time of construction. - ---C++: inline - ---C++: return const & - - CDG2D(me) returns Pnt2d from gp; - ---Purpose: Returns the 2D center of gravity used at the time of construction. - ---C++: inline - ---C++: return const & - - - IsFree(me; - IndexOfTriangle : Integer from Standard; - IndexinFree : out Integer from Standard) - returns Boolean is static private; - - Status (me; - p0,p1,p2: XY from gp ; - aPoint : XY from gp ; - aTol : Real from Standard; - Dmin : out Real from Standard) returns Integer from Standard; - ---Purpose: Dmin gives the distance between the cdg and aPoint - - - ---Category: TheLocations.... - - HasInitLocation(me) returns Boolean from Standard; - ---C++: inline - - GetInitLocation(me) returns Location from TopLoc; - ---C++: inline - ---C++: return const & - - - ResetLocation(me:mutable) is redefined virtual; - - SetLocation(me:mutable;aLoc :Location from TopLoc) is redefined virtual; - - - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - - DetectedTriangle(me;P1,P2,P3 : out Pnt from gp) - returns Boolean from Standard; - ---Purpose: gives the vertices of detected triangle... - - - DetectedTriangle2d(me;P1,P2,P3 : out Pnt2d from gp) - returns Boolean from Standard; - ---Purpose: Gets 2D nodes computed by entity using 3D nodes and viewer - -- parameters (see Project() method) - - ComputeTotalTrsf(me:mutable) is static private; - - -fields - - - myTriangul : Triangulation from Poly; - myiniloc : Location from TopLoc; - myTrsf : Trsf from gp; - - myCDG3D : Pnt from gp; - myFreeEdges: HArray1OfInteger from TColStd; - myIntFlag : Boolean from Standard; - - myNodes2d : Array1OfPnt2d from TColgp; - myCDG2D : Pnt2d from gp; - mybox2d : Box2d from Bnd; - - - myDetectedTr: Integer from Standard; - -end SensitiveTriangulation; diff --git a/src/Select3D/Select3D_SensitiveTriangulation.cxx b/src/Select3D/Select3D_SensitiveTriangulation.cxx index 694fc71334..b552d92202 100644 --- a/src/Select3D/Select3D_SensitiveTriangulation.cxx +++ b/src/Select3D/Select3D_SensitiveTriangulation.cxx @@ -14,691 +14,382 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -//Modified Thur Apr 09 98 by rob : No more computation of free edges. -// fix bug on Compute Depth (don't forget -// Location...) +#include -#include -#include #include #include -#include #include #include #include -#include -#include +#include +#include -static Standard_Integer S3D_NumberOfFreeEdges(const Handle(Poly_Triangulation)& Trg) +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveTriangulation, Select3D_SensitiveSet) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveTriangulation, Select3D_SensitiveSet) + +static Standard_Integer NbOfFreeEdges (const Handle(Poly_Triangulation)& theTriangulation) { - Standard_Integer nFree = 0; - Poly_Connect pc(Trg); - Standard_Integer t[3]; - Standard_Integer i,j; - for (i = 1; i <= Trg->NbTriangles(); i++) { - pc.Triangles(i,t[0],t[1],t[2]); - for (j = 0; j < 3; j++) - if (t[j] == 0) nFree++; + Standard_Integer aNbFree = 0; + Poly_Connect aPoly (theTriangulation); + Standard_Integer aTriangleNodes[3]; + for (Standard_Integer aTrgIdx = 1; aTrgIdx <= theTriangulation->NbTriangles(); aTrgIdx++) + { + aPoly.Triangles (aTrgIdx, aTriangleNodes[0], aTriangleNodes[1], aTriangleNodes[2]); + for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3; aNodeIdx++) + if (aTriangleNodes[aNodeIdx] == 0) + aNbFree++; } - return nFree; -} -static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP, - const Standard_Real aTol, Standard_Real& aDMin) -{ - Bnd_Box2d B; - B.SetVoid(); - B.Set(p0); - B.Update(p1.X(),p1.Y()); - B.Enlarge(aTol*3); - if(B.IsOut(TheP)) return Standard_False; - - gp_XY V01(p1);V01-=p0; - gp_XY Vec(TheP);Vec -= p0; - - if (V01.SquareModulus() < Precision::SquareConfusion()) - return Standard_False; - - Standard_Real u = Vec*V01.Normalized(); - if(u<-aTol) return Standard_False; - Standard_Real u1 = u-aTol; - Standard_Real modmod = V01.SquareModulus(); - if(u1*u1> modmod) return Standard_False; - - gp_XY N01 (-V01.Y(),V01.X()); - N01.Normalize(); - aDMin = Abs (Vec * N01); - return aDMin <= aTol; -} - -// static Standard_Real S3D_SquareDistanceFromEdge(gp_Pnt2d PCur, -// gp_Pnt2d PEdg1, -// gp_Pnt2d PEdg2, -// const Standard_Real TolTol) -// { -// gp_XY VEdg (PEdg1.XY()); -// gp_XY VCur (PEdg1.XY()); -// VEdg-= PEdg2.XY(); -// VCur-=PCur.XY(); -// Standard_Real long1 = VEdg.SquareModulus(); - -// if(long1<=TolTol) -// return VCur.SquareModulus(); -// Standard_Real Val = VEdg^VCur; -// return Val*Val/long1; - -// } - -static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1, - const Standard_Integer e2, - const Standard_Integer N1, - const Standard_Integer N2, - const Standard_Integer N3) -{ - Standard_Integer bid1 = (e1 == N1) ? N1 : ((e1 == N2) ? N2 : ( e1==N3 ? N3 : 0)); - if(bid1==0) return Standard_False; - Standard_Integer bid2 = (e2 == N1) ? N1 : ((e2 == N2) ? N2 : ( e2==N3 ? N3 : 0)); - - if(bid2==0 || bid2 ==bid1) return Standard_False; - return Standard_True; + return aNbFree; } //======================================================================= //function : Select3D_SensitiveTriangulation //purpose : //======================================================================= - -Select3D_SensitiveTriangulation:: -Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Poly_Triangulation)& Trg, - const TopLoc_Location& Loc, - const Standard_Boolean InteriorFlag): -Select3D_SensitiveEntity(OwnerId), -myTriangul(Trg), -myiniloc(Loc), -myIntFlag(InteriorFlag), -myNodes2d(1,Trg->NbNodes()), -myDetectedTr(-1) +Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Poly_Triangulation)& theTrg, + const TopLoc_Location& theInitLoc, + const Standard_Boolean theIsInterior) +: Select3D_SensitiveSet (theOwnerId), + myTriangul (theTrg), + myInitLocation (theInitLoc), + myDetectedTr (-1) { - // calculate free edges and cdg 3d of the triangulation: - // This code should have been integrated in poly_triangulation... + mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles(); + const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes(); + Standard_Integer aNbTriangles (myTriangul->NbTriangles()); + gp_XYZ aCenter (0.0, 0.0, 0.0); - Standard_Integer fr = 1; - const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); - const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); - Standard_Integer nbTriangles (myTriangul->NbTriangles()); - gp_XYZ cdg(0,0,0); - Standard_Integer n[3]; + myPrimitivesNb = theIsInterior ? aNbTriangles : NbOfFreeEdges (theTrg); + myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1); + TColStd_Array1OfInteger& aBVHPrimIdxs = myBVHPrimIndexes->ChangeArray1(); - // to find connections in case when the border is not concerned... - if(!myIntFlag) + if (!theIsInterior) { - myFreeEdges = new TColStd_HArray1OfInteger(1,2*S3D_NumberOfFreeEdges(Trg)); - TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); - Poly_Connect pc(myTriangul); - Standard_Integer t[3]; - Standard_Integer i,j; - for ( i = 1; i <= nbTriangles; i++) + Standard_Integer anEdgeIdx = 1; + myFreeEdges = new TColStd_HArray1OfInteger (1, 2 * myPrimitivesNb); + TColStd_Array1OfInteger& aFreeEdges = myFreeEdges->ChangeArray1(); + Poly_Connect aPoly (myTriangul); + Standard_Integer aTriangle[3]; + Standard_Integer aTrNodeIdx[3]; + for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; aTriangleIdx++) { - pc.Triangles(i,t[0],t[1],t[2]); - triangles(i).Get(n[0],n[1],n[2]); - cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.; - for (j = 0; j < 3; j++) + aPoly.Triangles (aTriangleIdx, aTriangle[0], aTriangle[1], aTriangle[2]); + aTriangles (aTriangleIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]); + aCenter += (aNodes (aTrNodeIdx[0]).XYZ() + aNodes (aTrNodeIdx[1]).XYZ()+ aNodes (aTrNodeIdx[2]).XYZ()) / 3.0; + for (Standard_Integer aVertIdx = 0; aVertIdx < 3; aVertIdx++) { - Standard_Integer k = (j+1) % 3; - if (t[j] == 0) + Standard_Integer aNextVert = (aVertIdx + 1) % 3; + if (aTriangle[aVertIdx] == 0) { - FreeE(fr) = n[j]; - FreeE(fr+1)= n[k]; - fr += 2; + aFreeEdges (anEdgeIdx) = aTrNodeIdx[aVertIdx]; + aFreeEdges (anEdgeIdx+1) = aTrNodeIdx[aNextVert]; + anEdgeIdx += 2; } } } } - else{ - for (Standard_Integer i = 1; i <= nbTriangles; i++) - { - triangles(i).Get(n[0],n[1],n[2]); - cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.; - } - } - - if(nbTriangles!=0) cdg /= nbTriangles; - myCDG3D = gp_Pnt(cdg); - - ComputeTotalTrsf(); - - if(myTrsf.Form()!=gp_Identity) - myCDG3D.Transform(myTrsf); -} - - -//======================================================================= -//function : Select3D_SensitiveTriangulation -//purpose : -//======================================================================= - -Select3D_SensitiveTriangulation:: -Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Handle(Poly_Triangulation)& Trg, - const TopLoc_Location& Loc, - const Handle(TColStd_HArray1OfInteger)& FreeEdges, - const gp_Pnt& TheCDG, - const Standard_Boolean InteriorFlag): -Select3D_SensitiveEntity(OwnerId), -myTriangul(Trg), -myiniloc(Loc), -myCDG3D(TheCDG), -myFreeEdges(FreeEdges), -myIntFlag(InteriorFlag), -myNodes2d(1,Trg->NbNodes()), -myDetectedTr(-1) -{ -} - -//======================================================================= -//function : Project -//purpose : -//======================================================================= - -void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj) -{ - mybox2d.SetVoid(); - const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); - - gp_Pnt2d ProjPT; - - for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){ - if(myTrsf.Form()!=gp_Identity) - aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT); - else - aPrj->Project(Nodes(I),ProjPT); - - myNodes2d.SetValue(I,ProjPT); - mybox2d.Add(ProjPT); - } - - aPrj->Project(myCDG3D,myCDG2D); -} - -//======================================================================= -//function : Areas -//purpose : -//======================================================================= - -void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) -{ - boxes.Append(mybox2d); -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - theMatchDMin = Precision::Infinite(); - gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y()); - myDetectedTr = -1; - const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); - - // it is checked if we are inside the triangle 2d. - if(myIntFlag) - { - gp_Lin aPickingLine = thePickArgs.PickLine(); - - if (myTrsf.Form() != gp_Identity) - { - aPickingLine.Transform (myTrsf.Inverted()); - } - - Standard_Real aMinDepth = Precision::Infinite(); - const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); - for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++) - { - Standard_Integer n1,n2,n3; - triangles(itr).Get(n1,n2,n3); - const gp_XY& aPnt2d1 = myNodes2d(n1).XY(); - const gp_XY& aPnt2d2 = myNodes2d(n2).XY(); - const gp_XY& aPnt2d3 = myNodes2d(n3).XY(); - gp_XY aUV; - Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV); - if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance()) - continue; - - // get interpolated depth of the triangle nodes - Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1)); - Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2)); - Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3)); - Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) + - aUV.Y() * (aDepth3 - aDepth1); - - // accept triangle with lowest depth and within defined depth interval - if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth)) - { - aMinDepth = aDepth; - myDetectedTr = itr; - theMatchDMin = Sqrt (aDistSquare); - } - } - } - - // Case only Test on Border of the triangulation... - // else { - //Standard_Integer ifirst; - TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); - Standard_Integer nn = FreeE.Length(), Node1,Node2; - //Standard_Real LEdg; - //Standard_Real DMinDMin,TolTol = aTol*aTol; - - for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2) + Standard_Integer aTrNodeIdx[3]; + for (Standard_Integer aTrIdx = 1; aTrIdx <= aNbTriangles; aTrIdx++) { - Node1 = FreeE(ifri); - Node2 = FreeE(ifri+1); - if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(), - myNodes2d(Node2).XY(), - BidPoint, thePickArgs.Tolerance(), theMatchDMin)) - { - for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++) - { - Standard_Integer n1,n2,n3; - triangles(itr).Get(n1,n2,n3); - if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3)) - { - myDetectedTr = itr; - break; // return first found; selection of closest is not implemented yet - } - } - } + aTriangles (aTrIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]); + aCenter += (aNodes (aTrNodeIdx[0]).XYZ() + aNodes (aTrNodeIdx[1]).XYZ()+ aNodes (aTrNodeIdx[2]).XYZ()) / 3.0; } } - if ( myDetectedTr <= 0 ) - return Standard_False; + if (aNbTriangles != 0) + aCenter /= aNbTriangles; + myCDG3D = gp_Pnt (aCenter); - // get precise depth for the detected triangle - theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr); - - // this test should not fail if the topmost triangle is taken from the - // first if-case block (for other cases this test make sense?) - return !thePickArgs.IsClipped (theMatchDepth); -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation:: -Matches(const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) -{ - Bnd_Box2d B; - B.Update(Min(XMin,XMax)-aTol, - Min(YMin,YMax)-aTol, - Max(XMin,XMax)+aTol, - Max(YMin,YMax)+aTol); - - for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++) + myBndBox.Clear(); + for (Standard_Integer aNodeIdx = 1; aNodeIdx <= myTriangul->NbNodes(); ++aNodeIdx) { - if(B.IsOut(myNodes2d(i))) - return Standard_False; + myBndBox.Add (SelectMgr_Vec3 (aNodes (aNodeIdx).X(), + aNodes (aNodeIdx).Y(), + aNodes (aNodeIdx).Z())); } - return Standard_True; -} -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation:: -Matches (const TColgp_Array1OfPnt2d& aPoly, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Standard_Real Umin,Vmin,Umax,Vmax; - aBox.Get(Umin,Vmin,Umax,Vmax); - CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); - - for(Standard_Integer j=1;j<=myNodes2d.Length();j++) + if (theIsInterior) { - Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j)); - if(RES!=1) return Standard_False; + for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; ++aTriangleIdx) + { + aBVHPrimIdxs (aTriangleIdx - 1) = aTriangleIdx - 1; + } } - return Standard_True; -} - -//======================================================================= -//function : Status -//purpose : -//======================================================================= - -Standard_Integer Select3D_SensitiveTriangulation:: -Status (const gp_XY& TheP, - const gp_XY& Proj0, - const gp_XY& Proj1, - const gp_XY& Proj2, - const Standard_Real aTol, - Standard_Real& DD) const -{ - return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD); -} - -//======================================================================= -//function : IsFree -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle, - Standard_Integer& FoundIndex) const -{ - FoundIndex=-1; - Standard_Integer n[3]; - const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); - triangles(IndexOfTriangle).Get(n[0],n[1],n[2]); - TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1(); - - for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2) + else { - if(FreeE(I) == n[0]) + Standard_Integer aStartIdx = myFreeEdges->Lower(); + Standard_Integer anEndIdx = myFreeEdges->Upper(); + for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2) { - if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2]) - FoundIndex=I; - } - else if(FreeE(I) == n[1]) - { - if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2]) - FoundIndex=I; - } - else if(FreeE(I) == n[2]) - { - if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1]) - FoundIndex=I; + aBVHPrimIdxs ((aFreeEdgesIdx - aStartIdx) / 2) = (aFreeEdgesIdx - aStartIdx) / 2; } } - - return FoundIndex!=-1; } +//======================================================================= +//function : Select3D_SensitiveTriangulation +//purpose : +//======================================================================= +Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Poly_Triangulation)& theTrg, + const TopLoc_Location& theInitLoc, + const Handle(TColStd_HArray1OfInteger)& theFreeEdges, + const gp_Pnt& theCOG, + const Standard_Boolean theIsInterior) +: Select3D_SensitiveSet (theOwnerId), + myTriangul (theTrg), + myInitLocation (theInitLoc), + myCDG3D (theCOG), + myFreeEdges (theFreeEdges), + myDetectedTr (-1) +{ + mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; + myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2; + myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1); + if (theIsInterior) + { + for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= myPrimitivesNb; ++aTriangleIdx) + { + myBVHPrimIndexes->SetValue (aTriangleIdx - 1, aTriangleIdx - 1); + } + } + else + { + Standard_Integer aStartIdx = myFreeEdges->Lower(); + Standard_Integer anEndIdx = myFreeEdges->Upper(); + for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2) + { + myBVHPrimIndexes->SetValue ((aFreeEdgesIdx - aStartIdx) / 2, (aFreeEdgesIdx - aStartIdx) / 2); + } + } +} + +//======================================================================= +// function : Size +// purpose : Returns the length of array of triangles or edges +//======================================================================= +Standard_Integer Select3D_SensitiveTriangulation::Size() const +{ + return myPrimitivesNb; +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of triangle/edge with index theIdx +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer theIdx) const +{ + Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx); + SelectMgr_Vec3 aMinPnt (RealLast()); + SelectMgr_Vec3 aMaxPnt (RealFirst()); + Standard_Boolean hasInitLoc = HasInitLocation(); + + if (mySensType == Select3D_TOS_INTERIOR) + { + Standard_Integer aNode1, aNode2, aNode3; + myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3); + + gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode1); + gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode2); + gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode3); + + aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())), + Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())), + Min (aPnt1.Z(), Min (aPnt2.Z(), aPnt3.Z()))); + aMaxPnt = SelectMgr_Vec3 (Max (aPnt1.X(), Max (aPnt2.X(), aPnt3.X())), + Max (aPnt1.Y(), Max (aPnt2.Y(), aPnt3.Y())), + Max (aPnt1.Z(), Max (aPnt2.Z(), aPnt3.Z()))); + } + else + { + Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx); + Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1); + gp_Pnt aNode1 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx1).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNodeIdx1); + gp_Pnt aNode2 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx2).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNodeIdx2); + + aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()), + Min (aNode1.Y(), aNode2.Y()), + Min (aNode1.Z(), aNode2.Z())); + aMaxPnt = SelectMgr_Vec3 (Max (aNode1.X(), aNode2.X()), + Max (aNode1.Y(), aNode2.Y()), + Max (aNode1.Z(), aNode2.Z())); + } + + return Select3D_BndBox3d (aMinPnt, aMaxPnt); +} + +//======================================================================= +// function : Center +// purpose : Returns geometry center of triangle/edge with index theIdx +// in array along the given axis theAxis +//======================================================================= +Standard_Real Select3D_SensitiveTriangulation::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + const Select3D_BndBox3d& aBox = Box (theIdx); + SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5; + + return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z()); +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 in array +//======================================================================= +void Select3D_SensitiveTriangulation::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + Standard_Integer anElemIdx1 = myBVHPrimIndexes->Value (theIdx1); + Standard_Integer anElemIdx2 = myBVHPrimIndexes->Value (theIdx2); + + myBVHPrimIndexes->ChangeValue (theIdx1) = anElemIdx2; + myBVHPrimIndexes->ChangeValue (theIdx2) = anElemIdx1; +} + +//======================================================================= +// function : overlapsElement +// purpose : Checks whether the element with index theIdx overlaps the +// current selecting volume +//======================================================================= +Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) +{ + const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx); + Standard_Boolean hasInitLoc = HasInitLocation(); + + if (mySensType == Select3D_TOS_BOUNDARY) + { + Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1); + Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2); + Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2); + gp_Pnt aSegmStart = hasInitLoc ? myTriangul->Nodes().Value (aSegmStartIdx).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aSegmStartIdx); + gp_Pnt aSegmEnd = hasInitLoc ? myTriangul->Nodes().Value (aSegmEndIdx).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aSegmEndIdx); + anEdgePnts->SetValue (1, aSegmStart); + anEdgePnts->SetValue (2, aSegmEnd); + Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth); + anEdgePnts.Nullify(); + return isMatched; + } + else + { + const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles(); + Standard_Integer aNode1, aNode2, aNode3; + aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3); + gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode1); + gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode2); + gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation()) + : myTriangul->Nodes().Value (aNode3); + return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth); + } +} + +//======================================================================= +// function : distanceToCOG +// purpose : Calculates distance from the 3d projection of used-picked +// screen point to center of the geometry +//======================================================================= +Standard_Real Select3D_SensitiveTriangulation::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) +{ + return theMgr.DistToGeometryCenter (myCDG3D); +} + //======================================================================= //function : GetConnected //purpose : //======================================================================= - -Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation:: -GetConnected(const TopLoc_Location& aLoc) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::GetConnected() { - Handle(Select3D_SensitiveTriangulation) NiouEnt = - new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag); + Standard_Boolean isInterior = mySensType == Select3D_TOS_INTERIOR; + Handle(Select3D_SensitiveTriangulation) aNewEntity = + new Select3D_SensitiveTriangulation (myOwnerId, myTriangul, myInitLocation, myFreeEdges, myCDG3D, isInterior); - if(HasLocation()) - NiouEnt->SetLocation(Location()); -// TopLoc_Location TheLocToApply = HasLocation() ? Location()*aLoc : aLoc; -// if(!TheLocToApply.IsIdentity()) - NiouEnt->UpdateLocation(aLoc); - - return NiouEnt; + return aNewEntity; } //======================================================================= -//function : ResetLocation -//purpose : +// function : applyTransformation +// purpose : Inner function for transformation application to bounding +// box of the triangulation //======================================================================= - -void Select3D_SensitiveTriangulation::ResetLocation() +Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation() { - Select3D_SensitiveEntity::ResetLocation(); - ComputeTotalTrsf(); -} + if (!HasInitLocation()) + return myBndBox; -//======================================================================= -//function : SetLocation -//purpose : -//======================================================================= - -void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc) -{ - Select3D_SensitiveEntity::SetLocation(aLoc); - ComputeTotalTrsf(); -} - - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= -void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const -{ - S<<"\tSensitiveTriangulation 3D :"<NbTriangles()<NbNodes()<Length()/2<Triangles(); - const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); - - Standard_Integer n1,n2,n3; - triangles (theTriangle).Get (n1,n2,n3); - gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)}; - - if (myTrsf.Form() != gp_Identity) - { - for (Standard_Integer i =0; i<=2; i++) + for (Standard_Integer aY = 0; aY <=1; ++aY) { - P[i].Transform (myTrsf); + for (Standard_Integer aZ = 0; aZ <= 1; ++aZ) + { + gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(), + aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(), + aZ == 0 ? myBndBox.CornerMin().z() : myBndBox.CornerMax().z()); + aVertex.Transform (myInitLocation); + aBndBox.Add (Select3D_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z())); + } } } - // formula calculate the parameter of the point on the intersection - // t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir) - Standard_Real prof (Precision::Infinite()); - gp_Pnt Oye = thePickLine.Location(); // origin of the target line eye/point... - gp_Dir Dir = thePickLine.Direction(); - - gp_Vec Vtr[3]; - for (Standard_Integer i=0; i<=2; i++) - { - Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]); - } - - Vtr[2] = -Vtr[2]; - - // remove singular cases immediately... - Standard_Integer SingularCase (-1); - if (Vtr[0].SquareMagnitude() <= Precision::Confusion()) - { - SingularCase = 0; - } - - if (Vtr[1].SquareMagnitude() <= Precision::Confusion()) - { - SingularCase = (SingularCase == -1) ? 1 : 2; - } - - if (Vtr[2].SquareMagnitude() <= Precision::Confusion()) - { - if( SingularCase < 0 ) SingularCase = 1; - } - - // 3 pts mixed... - if (SingularCase ==2) - { - prof = ElCLib::Parameter (thePickLine, P[0]); - return prof; - } - - if (SingularCase!=0) - { - Vtr[0].Normalize(); - } - - if (SingularCase!=1 && SingularCase!=2) - { - Vtr[2].Normalize(); - } - - gp_Vec OPo (Oye, P[0]); - - // 2 points mixed... the intersection between the segment and the target line eye/point. - if (SingularCase!=-1) - { - gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0]; - gp_Vec Det = Dir^V; - gp_Vec VSM = OPo^V; - - if (Det.X() > Precision::Confusion()) - { - prof = VSM.X() / Det.X(); - } - else if (Det.Y() > Precision::Confusion()) - { - prof = VSM.Y() / Det.Y(); - } - else if (Det.Z() > Precision::Confusion()) - { - prof = VSM.Z() / Det.Z(); - } - } - else - { - Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]); - Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]); - - if (Abs (val2) > Precision::Confusion()) - { - prof = val1 / val2; - } - } - - if (prof == Precision::Infinite()) - { - prof= ElCLib::Parameter (thePickLine, P[0]); - prof = Min (prof, ElCLib::Parameter (thePickLine, P[1])); - prof = Min (prof, ElCLib::Parameter (thePickLine, P[2])); - } - - return prof; + return aBndBox; } //======================================================================= -//function : DetectedTriangle -//purpose : +// function : BoundingBox +// purpose : Returns bounding box of the triangulation. If location +// transformation is set, it will be applied //======================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation:: -DetectedTriangle(gp_Pnt& P1, - gp_Pnt& P2, - gp_Pnt& P3) const +Select3D_BndBox3d Select3D_SensitiveTriangulation::BoundingBox() { - if(myDetectedTr==-1) return Standard_False; // currently not implemented... - const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); - const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); - Standard_Integer n1,n2,n3; - triangles(myDetectedTr).Get(n1,n2,n3); + if (myBndBox.IsValid()) + return applyTransformation(); - P1 = Nodes(n1); - P2 = Nodes(n2); - P3 = Nodes(n3); - if(myTrsf.Form()!=gp_Identity) + const Standard_Integer aLower = myTriangul->Nodes().Lower(); + const Standard_Integer anUpper = myTriangul->Nodes().Upper(); + Select3D_BndBox3d aBndBox; + for (Standard_Integer aNodeIdx = aLower; aNodeIdx <= anUpper; ++aNodeIdx) { - P1.Transform(myTrsf); - P2.Transform(myTrsf); - P3.Transform(myTrsf); + const gp_Pnt& aNode = myTriangul->Nodes().Value (aNodeIdx); + const SelectMgr_Vec3 aNodeTransf = SelectMgr_Vec3 (aNode.X(), aNode.Y(), aNode.Z()); + aBndBox.Add (aNodeTransf); } - return Standard_True; + myBndBox = aBndBox; + + return applyTransformation(); } -//============================================================================= -// Function : DetectedTriangle2d -// Purpose : -//============================================================================= - -Standard_Boolean Select3D_SensitiveTriangulation:: -DetectedTriangle2d(gp_Pnt2d& P1, - gp_Pnt2d& P2, - gp_Pnt2d& P3) const +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of triangulation. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const { - if(myDetectedTr==-1) - return Standard_False; // currently not implemented... - const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); - Standard_Integer n1,n2,n3; - triangles( myDetectedTr ).Get(n1,n2,n3); - - int aLower = myNodes2d.Lower(); - int anUpper = myNodes2d.Upper(); - if ( n1 >= aLower && n1 <= anUpper && - n2 >= aLower && n2 <= anUpper && - n3 >= aLower && n3 <= anUpper ) - { - P1 = myNodes2d.Value( n1 ); - P2 = myNodes2d.Value( n2 ); - P3 = myNodes2d.Value( n3 ); - return Standard_True; - } - else - return Standard_False; + return HasInitLocation() ? myCDG3D.Transformed (myInitLocation) : myCDG3D; } -//============================================================================= -// Function : ComputeTotalTrsf -// Purpose : -//============================================================================= - -void Select3D_SensitiveTriangulation::ComputeTotalTrsf() +//======================================================================= +// function : NbSubElements +// purpose : Returns the amount of nodes in triangulation +//======================================================================= +Standard_Integer Select3D_SensitiveTriangulation::NbSubElements() { - Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity()); - - if(hasloc) - { - if(myiniloc.IsIdentity()) - myTrsf = Location().Transformation(); - else if(HasLocation()) - { - myTrsf = (Location()*myiniloc).Transformation(); - } - else - myTrsf = myiniloc.Transformation(); - } - else - { - gp_Trsf TheId; - myTrsf = TheId; - } + return myTriangul->Nodes().Length(); } diff --git a/src/Select3D/Select3D_SensitiveTriangulation.hxx b/src/Select3D/Select3D_SensitiveTriangulation.hxx new file mode 100644 index 0000000000..ae90d645f4 --- /dev/null +++ b/src/Select3D/Select3D_SensitiveTriangulation.hxx @@ -0,0 +1,154 @@ +// Created on: 1997-05-15 +// Created by: Robert COUBLANC +// Copyright (c) 1997-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +//Modified Thur Apr 09 98 by rob : No more computation of free edges. +// fix bug on Compute Depth (don't forget +// Location...) + +#ifndef _Select3D_SensitiveTriangulation_Header +#define _Select3D_SensitiveTriangulation_Header + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Poly_Triangulation; +class TColStd_HArray1OfInteger; +class SelectBasics_EntityOwner; +class TopLoc_Location; +class gp_Pnt; +class Select3D_SensitiveEntity; +class Handle(Select3D_SensitiveEntity); +class TColgp_Array1OfPnt2d; + +//! A framework to define selection of a sensitive entity made of a set of triangles. +class Select3D_SensitiveTriangulation : public Select3D_SensitiveSet +{ + +public: + + //! Constructs a sensitive triangulation object defined by + //! the owner theOwnerId, the triangulation theTrg, + //! the location theInitLoc, and the flag theIsInterior. + Standard_EXPORT Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Poly_Triangulation)& theTrg, + const TopLoc_Location& theInitLoc, + const Standard_Boolean theIsInterior = Standard_True); + + //! Constructs a sensitive triangulation object defined by + //! the owner theOwnerId, the triangulation theTrg, + //! the location theInitLoc, the array of free edges + //! theFreeEdges, the center of gravity theCOG, and the flag theIsInterior. + //! As free edges and the center of gravity do not have + //! to be computed later, this syntax reduces computation time. + Standard_EXPORT Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Handle(Poly_Triangulation)& theTrg, + const TopLoc_Location& theInitLoc, + const Handle(TColStd_HArray1OfInteger)& theFreeEdges, + const gp_Pnt& theCOG, + const Standard_Boolean theIsInterior); + + //! Returns the amount of nodes in triangulation + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT Handle_Select3D_SensitiveEntity GetConnected() Standard_OVERRIDE; + + const Handle_Poly_Triangulation& Triangulation() const; + + Standard_Boolean HasInitLocation() const; + + const TopLoc_Location& GetInitLocation() const; + + //! Returns the length of array of triangles or edges + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns bounding box of triangle/edge with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns geometry center of triangle/edge with index theIdx + //! in array along the given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in array + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + //! Returns bounding box of the triangulation. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of triangulation. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + +public: + DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation) + +protected: + + //! Inner function for transformation application to bounding + //! box of the triangulation + Select3D_BndBox3d applyTransformation(); + + +private: + + //! Checks whether the element with index theIdx overlaps the current selecting volume + virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) Standard_OVERRIDE; + + //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry + virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; + +public: + Standard_Real myBVHBuildTime; + +private: + + Handle_Poly_Triangulation myTriangul; + TopLoc_Location myInitLocation; + gp_Pnt myCDG3D; //!< Center of the whole triangulation + Handle_TColStd_HArray1OfInteger myFreeEdges; + Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior + Standard_Integer myDetectedTr; + Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type + Handle_TColStd_HArray1OfInteger myBVHPrimIndexes; //!< Indexes of edges or triangles for BVH build + mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangulation, Select3D_SensitiveSet) + +#include + + +#endif // _Select3D_SensitiveTriangulation_Header diff --git a/src/Select3D/Select3D_SensitiveTriangulation.lxx b/src/Select3D/Select3D_SensitiveTriangulation.lxx index f19ee25ed8..4da21970c6 100644 --- a/src/Select3D/Select3D_SensitiveTriangulation.lxx +++ b/src/Select3D/Select3D_SensitiveTriangulation.lxx @@ -14,29 +14,29 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +//======================================================================= +//function : Triangulation +//purpose : +//======================================================================= inline const Handle(Poly_Triangulation)& Select3D_SensitiveTriangulation::Triangulation() const { return myTriangul; } - -inline const gp_Pnt& Select3D_SensitiveTriangulation::CDG3D() const -{ - return myCDG3D; -} - - -inline const gp_Pnt2d& Select3D_SensitiveTriangulation::CDG2D() const -{ - return myCDG2D; -} - +//======================================================================= +//function : HasInitLocation +//purpose : +//======================================================================= inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const -{return !myiniloc.IsIdentity();} -inline const TopLoc_Location& Select3D_SensitiveTriangulation::GetInitLocation() const -{return myiniloc;} - -inline Standard_Integer Select3D_SensitiveTriangulation::DetectedTriangle() const { - return myDetectedTr; + return !myInitLocation.IsIdentity(); +} + +//======================================================================= +//function : GetInitLocation +//purpose : +//======================================================================= +inline const TopLoc_Location& Select3D_SensitiveTriangulation::GetInitLocation() const +{ + return myInitLocation; } diff --git a/src/Select3D/Select3D_SensitiveWire.cdl b/src/Select3D/Select3D_SensitiveWire.cdl deleted file mode 100644 index 7e33fe6ea6..0000000000 --- a/src/Select3D/Select3D_SensitiveWire.cdl +++ /dev/null @@ -1,124 +0,0 @@ --- Created on: 1996-10-17 --- Created by: Odile OLIVIER --- Copyright (c) 1996-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class SensitiveWire from Select3D -inherits SensitiveEntity from Select3D - - ---Purpose: A framework to define selection of a wire owner by an - -- elastic wire band. - -uses - Pnt from gp, - Projector from Select3D, - Lin from gp, - EntityOwner from SelectBasics, - SensitiveEntity from Select3D, - SensitiveEntitySequence from Select3D, - ListOfBox2d from SelectBasics, - PickArgs from SelectBasics, - Array1OfPnt2d from TColgp, - Box2d from Bnd, - Location from TopLoc - -is - - - Create (OwnerId : EntityOwner from SelectBasics; - MaxRect : Integer = 1) - returns SensitiveWire; - ---Purpose: Constructs a sensitive wire object defined by the - -- owner OwnerId, and the maximum number of - -- sensitive rectangles MaxRect. - Add (me :mutable;aSensitive : SensitiveEntity from Select3D) - is static; - ---Purpose: Adds the sensitive entity aSensitive to this framework. - Project (me:mutable;aProjector : Projector from Select3D) - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm - - Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) - is redefined static; - ---Level: Public - ---Purpose: gives the 2D boxes which represent the segment in the - -- selection process... - - GetConnected(me:mutable;aLocation: Location from TopLoc) - returns SensitiveEntity from Select3D is redefined static; - - GetEdges(me : mutable; - theEdges : in out SensitiveEntitySequence from Select3D); - ---Level: Public - ---Purpose: returns the sensitive edges stored in this wire - - - SetLocation(me:mutable;aLoc:Location from TopLoc) is redefined static; - ---Purpose: propagation of location on all the sensitive inside... - ResetLocation(me:mutable) is redefined static; - ---Purpose: propagation of location on all the sensitive inside... - - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin, theMatchDepth : out Real from Standard) - returns Boolean - is redefined static; - ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking - -- detection area (close to the picking line). - -- For details please refer to base class declaration. - - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is static; - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is redefined virtual; - ---Level: Public - - - MaxBoxes(me) returns Integer is redefined static; - ---Level: Public - ---Purpose:returns - - - Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; - - Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; - ---Purpose: Sets the owner for all entities in wire - - GetLastDetected(me) - returns SensitiveEntity from Select3D is static; - ---Purpose:returns - -fields - mysensitive : SensitiveEntitySequence from Select3D; - myDetectedIndex : Integer from Standard; -end SensitiveWire; - - - - - - - - diff --git a/src/Select3D/Select3D_SensitiveWire.cxx b/src/Select3D/Select3D_SensitiveWire.cxx index e95478f9ae..e7280b702c 100644 --- a/src/Select3D/Select3D_SensitiveWire.cxx +++ b/src/Select3D/Select3D_SensitiveWire.cxx @@ -14,206 +14,128 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include +#include #include -#include -#include -#include #include +#include -#include -#include +#include -//static Standard_Boolean debugmode=Standard_False; +IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveWire, Select3D_SensitiveEntity) +IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveWire, Select3D_SensitiveEntity) //===================================================== -// Function : Create -// Purpose :Constructor +// Function : Select3D_SensitiveWire +// Purpose : //===================================================== - -Select3D_SensitiveWire:: -Select3D_SensitiveWire(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Standard_Integer /*MaxRect*/): -Select3D_SensitiveEntity(OwnerId), -myDetectedIndex(-1) +Select3D_SensitiveWire::Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId) +: Select3D_SensitiveSet (theOwnerId), + myCenter (0.0, 0.0, 0.0) {} //===================================================== // Function : Add // Purpose : //===================================================== - -void Select3D_SensitiveWire -::Add(const Handle(Select3D_SensitiveEntity)& aSensitive) +void Select3D_SensitiveWire::Add (const Handle(Select3D_SensitiveEntity)& theSensitive) { - if(!aSensitive.IsNull()) - mysensitive.Append(aSensitive); + if (!theSensitive.IsNull()) + myEntities.Append (theSensitive); + + Select3D_BndBox3d aBndBox = theSensitive->BoundingBox(); + myBndBox.Combine (aBndBox); + myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ(); + if (myEntities.Length() != 1) + myCenter.ChangeCoord().Divide (2.0); + myEntityIndexes.Append (myEntities.Length() - 1); } //======================================================================= -//function : SetLocation -//purpose : +// function : NbSubElements +// purpose : Returns the amount of sub-entities //======================================================================= - -void Select3D_SensitiveWire::SetLocation(const TopLoc_Location& aLoc) +Standard_Integer Select3D_SensitiveWire::NbSubElements() { - - // evitons les problemes... - if(aLoc.IsIdentity()) return; - - if(HasLocation()) - if(aLoc == Location()) return; - - Select3D_SensitiveEntity::SetLocation(aLoc); - for(Standard_Integer i=1;i<=mysensitive.Length();i++){ - if(mysensitive(i)->HasLocation()){ - if(mysensitive(i)->Location()!=aLoc) - mysensitive(i)->SetLocation(mysensitive(i)->Location()*aLoc); - } - else - mysensitive(i)->SetLocation(aLoc); - - } + return myEntities.Length(); } //======================================================================= -//function : ResetLocation -//purpose : +// function : Size +// purpose : Returns the length of vector of sensitive entities //======================================================================= - -void Select3D_SensitiveWire::ResetLocation() +Standard_Integer Select3D_SensitiveWire::Size() const { - if(!HasLocation()) return; - for(Standard_Integer i=1;i<=mysensitive.Length();i++){ - if(mysensitive(i)->HasLocation() && mysensitive(i)->Location()!=Location()) - mysensitive(i)->SetLocation(mysensitive(i)->Location()*Location().Inverted()); - else - mysensitive(i)->ResetLocation(); - - } - Select3D_SensitiveEntity::ResetLocation(); + return myEntities.Length(); } -//===================================================== -// Function : Project -// Purpose : -//===================================================== -void Select3D_SensitiveWire::Project(const Handle(Select3D_Projector)& aProj) +//======================================================================= +// function : Box +// purpose : Returns bounding box of sensitive entity with index theIdx +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveWire::Box (const Standard_Integer theIdx) const { - for (Standard_Integer aSensIt = 1; aSensIt <= mysensitive.Length(); aSensIt++) + const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx); + return myEntities.Value (aSensitiveIdx)->BoundingBox(); +} + +//======================================================================= +// function : Center +// purpose : Returns geometry center of sensitive entity with index +// theIdx in the vector along the given axis theAxis +//======================================================================= +Standard_Real Select3D_SensitiveWire::Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const +{ + const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx); + const gp_Pnt& aCenter = myEntities.Value (aSensitiveIdx)->CenterOfGeometry(); + Standard_Real aCenterCoord = 0.0; + aCenterCoord = theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z()); + + return aCenterCoord; +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector +//======================================================================= +void Select3D_SensitiveWire::Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) +{ + const Standard_Integer aSensitiveIdx1 = myEntityIndexes.Value (theIdx1); + const Standard_Integer aSensitiveIdx2 = myEntityIndexes.Value (theIdx2); + myEntityIndexes.ChangeValue (theIdx1) = aSensitiveIdx2; + myEntityIndexes.ChangeValue (theIdx2) = aSensitiveIdx1; +} + +// ======================================================================= +// function : overlapsElement +// purpose : Checks whether the entity with index theIdx overlaps the +// current selecting volume +// ======================================================================= +Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) +{ + const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx); + const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx); + SelectBasics_PickResult aMatchResult; + if (aSeg->Matches (theMgr, aMatchResult)) { - mysensitive (aSensIt)->Project (aProj); - } -} - -//===================================================== -// Function : Areas -// Purpose : -//===================================================== - -void Select3D_SensitiveWire -::Areas(SelectBasics_ListOfBox2d& theareas) -{ - Bnd_Box2d BB; // en attendant un nouveau champ rob-18-jun-97 - SelectBasics_ListOfBox2d BidL; - Standard_Integer i; - for (i=1; i<=mysensitive.Length(); i++) - mysensitive.Value(i)->Areas(BidL); - - for(SelectBasics_ListIteratorOfListOfBox2d it(BidL);it.More();it.Next()) - BB.Add(it.Value()); - - theareas.Append(BB); -} - -//===================================================== -// Function : Matches -// Purpose : -//===================================================== - -Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs, - Standard_Real& theMatchDMin, - Standard_Real& theMatchDepth) -{ - theMatchDMin = RealLast(); - theMatchDepth = RealLast(); - Standard_Real aSegDMin, aSegDepth; - Standard_Boolean isMatched = Standard_False; - myDetectedIndex = -1; - - for (Standard_Integer aSegIt = 1; aSegIt <= mysensitive.Length(); aSegIt++) - { - const Handle(SelectBasics_SensitiveEntity)& aSeg = mysensitive.Value (aSegIt); - if (!aSeg->Matches (thePickArgs, aSegDMin, aSegDepth)) - { - continue; - } - - isMatched = Standard_True; - if (aSegDMin > theMatchDMin) - { - continue; - } - - myDetectedIndex = aSegIt; - theMatchDMin = aSegDMin; - theMatchDepth = aSegDepth; + theMatchDepth = aMatchResult.Depth(); + return Standard_True; } - return isMatched; + return Standard_False; } -//===================================================== -// Function : Matches -// Purpose : -//===================================================== - -Standard_Boolean Select3D_SensitiveWire:: -Matches (const Standard_Real XMin, - const Standard_Real YMin, - const Standard_Real XMax, - const Standard_Real YMax, - const Standard_Real aTol) +// ======================================================================= +// function : distanceToCOG +// purpose : Calculates distance from the 3d projection of used-picked +// screen point to center of the geometry +// ======================================================================= +Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) { - Standard_Integer i; - for (i=1; i<=mysensitive.Length(); i++) - { - if (!(mysensitive.Value(i)->Matches(XMin,YMin,XMax,YMax,aTol))) - return Standard_False; - } - return Standard_True; -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveWire:: -Matches (const TColgp_Array1OfPnt2d& aPoly, - const Bnd_Box2d& aBox, - const Standard_Real aTol) -{ - Standard_Integer i; - for (i=1; i<=mysensitive.Length(); i++) - { - if (!(mysensitive.Value(i)->Matches(aPoly, aBox, aTol))) - return Standard_False; - } - return Standard_True; -} - - -//===================================================== -// Function : MaxBoxes -// Purpose : -//===================================================== - -Standard_Integer Select3D_SensitiveWire:: -MaxBoxes () const -{ - return 1; + return theMgr.DistToGeometryCenter (myCenter); } //======================================================================= @@ -221,62 +143,37 @@ MaxBoxes () const //purpose : //======================================================================= -Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected(const TopLoc_Location& aLoc) +Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected() { - Handle(Select3D_SensitiveWire) SWIR = new Select3D_SensitiveWire(myOwnerId); - for(Standard_Integer i=1;i<=mysensitive.Length();i++) - SWIR->Add(mysensitive(i)->GetConnected(aLoc)); - - if(HasLocation()) - SWIR->SetLocation(Location()*aLoc); - else - SWIR->SetLocation(aLoc); - return SWIR; -} - - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= - -void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const -{ - S<<"\tSensitiveWire 3D :"<Dump(S,FullDump);} - - S<<"\tEnd Of Sensitive Wire"<Add (myEntities(anEntityIdx)->GetConnected()); + return aNewEntity; } //======================================================================= //function : GetEdges //purpose : returns the sensitive edges stored in this wire //======================================================================= - -void Select3D_SensitiveWire::GetEdges( Select3D_SensitiveEntitySequence& theEdges ) +const NCollection_Vector& Select3D_SensitiveWire::GetEdges() { - theEdges.Clear(); - theEdges.Append(mysensitive); + return myEntities; } //============================================================================= // Function : GetLastDetected // Purpose : //============================================================================= - Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const { Handle(Select3D_SensitiveEntity) aRes; - if ( myDetectedIndex >= 1 && myDetectedIndex <= mysensitive.Length() ) - aRes = mysensitive.Value( myDetectedIndex ); + if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length()) + { + const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx); + aRes = myEntities.Value (aSensitiveIdx); + } return aRes; } @@ -285,14 +182,41 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const //function : Set //purpose : //======================================================================= - -void Select3D_SensitiveWire::Set(const Handle(SelectBasics_EntityOwner) &TheOwnerId) +void Select3D_SensitiveWire::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId) { - Select3D_SensitiveEntity::Set(TheOwnerId); + Select3D_SensitiveEntity::Set (theOwnerId); // Set TheOwnerId for each element of sensitive wire - for (Standard_Integer i = 1; i <= mysensitive.Length(); ++i) + for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx) { - mysensitive.Value(i)->Set(TheOwnerId); + myEntities.Value (anEntityIdx)->Set (theOwnerId); } } + +//======================================================================= +// function : BoundingBox +// purpose : Returns bounding box of the wire. If location +// transformation is set, it will be applied +//======================================================================= +Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox() +{ + if (myBndBox.IsValid()) + return myBndBox; + + for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx) + { + myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox()); + } + + return myBndBox; +} + +//======================================================================= +// function : CenterOfGeometry +// purpose : Returns center of the wire. If location transformation +// is set, it will be applied +//======================================================================= +gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const +{ + return myCenter; +} diff --git a/src/Select3D/Select3D_SensitiveWire.hxx b/src/Select3D/Select3D_SensitiveWire.hxx new file mode 100644 index 0000000000..75137593df --- /dev/null +++ b/src/Select3D/Select3D_SensitiveWire.hxx @@ -0,0 +1,105 @@ +// Created on: 1996-10-17 +// Created by: Odile OLIVIER +// Copyright (c) 1996-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Select3D_SensitiveWire_HeaderFile +#define _Select3D_SensitiveWire_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include + +class SelectBasics_EntityOwner; +class TopLoc_Location; +class Select3D_SensitiveEntitySequence; + + +//! A framework to define selection of a wire owner by an +//! elastic wire band. +class Select3D_SensitiveWire : public Select3D_SensitiveSet +{ +public: + + //! Constructs a sensitive wire object defined by the + //! owner theOwnerId + Standard_EXPORT Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId); + + //! Adds the sensitive entity theSensitive to this framework. + Standard_EXPORT void Add (const Handle(Select3D_SensitiveEntity)& theSensitive); + + //! Returns the amount of sub-entities + Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE; + + Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; + + //! returns the sensitive edges stored in this wire + Standard_EXPORT const NCollection_Vector& GetEdges(); + + //! Sets the owner for all entities in wire + Standard_EXPORT void Set (const Handle(SelectBasics_EntityOwner)& theOwnerId); + + Standard_EXPORT Handle_Select3D_SensitiveEntity GetLastDetected() const; + + //! Returns bounding box of the wire. If location + //! transformation is set, it will be applied + Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; + + //! Returns center of the wire. If location transformation + //! is set, it will be applied + Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + + //! Returns the length of vector of sensitive entities + Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns bounding box of sensitive entity with index theIdx + Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; + + //! Returns geometry center of sensitive entity index theIdx in + //! the vector along the given axis theAxis + Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 in the vector + Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, + const Standard_Integer theIdx2) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(Select3D_SensitiveWire) + +protected: + + //! Checks whether the entity with index theIdx overlaps the current selecting volume + Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr, + Standard_Integer theElemIdx, + Standard_Real& theMatchDepth) Standard_OVERRIDE; + + //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry + Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; + +private: + + NCollection_Vector myEntities; //!< Vector of sub-entities + NCollection_Vector myEntityIndexes; //!< Indexes of entities for BVH build + gp_Pnt myCenter; //!< Center of the whole wire + mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole wire +}; + +DEFINE_STANDARD_HANDLE(Select3D_SensitiveWire, Select3D_SensitiveEntity) + +#endif // _Select3D_SensitiveWire_HeaderFile diff --git a/src/Select3D/Select3D_TypeOfSensitivity.hxx b/src/Select3D/Select3D_TypeOfSensitivity.hxx new file mode 100644 index 0000000000..25e476b1ca --- /dev/null +++ b/src/Select3D/Select3D_TypeOfSensitivity.hxx @@ -0,0 +1,15 @@ +#ifndef _Select3D_TypeOfSensitivity_HeaderFile +#define _Select3D_TypeOfSensitivity_HeaderFile + +#include + +//! Provides values for type of sensitivity in 3D. +//! These are used to specify whether it is the interior, +//! the boundary, or the exterior of a 3D sensitive entity which is sensitive. +enum Select3D_TypeOfSensitivity +{ +Select3D_TOS_INTERIOR, +Select3D_TOS_BOUNDARY +}; + +#endif // _Select3D_TypeOfSensitivity_HeaderFile diff --git a/src/SelectBasics/FILES b/src/SelectBasics/FILES index 3649dd9f50..d105e63adf 100644 --- a/src/SelectBasics/FILES +++ b/src/SelectBasics/FILES @@ -1 +1,2 @@ -SelectBasics_PickArgs.hxx \ No newline at end of file +SelectBasics_PickResult.hxx +SelectBasics_SelectingVolumeManager.hxx diff --git a/src/SelectBasics/SelectBasics.cdl b/src/SelectBasics/SelectBasics.cdl index 2845c0611e..afef21f2ca 100644 --- a/src/SelectBasics/SelectBasics.cdl +++ b/src/SelectBasics/SelectBasics.cdl @@ -16,12 +16,7 @@ package SelectBasics - ---Purpose: kernel of dynamic selection: - -- - contains the algorithm to sort the sensitive areas - -- before the selection action;->quick selection of - -- an item in a set of items... - -- - contains the entities able to give the algorithm - -- sensitive areas . + ---Purpose: interface class for dynamic selection uses Bnd, @@ -31,37 +26,22 @@ uses MMgt, gp, TColgp, - TopLoc - + TopLoc, + Select3D is deferred class EntityOwner; - - class SortAlgo; - - class BasicTool; - - class ListOfBox2d instantiates List from TCollection - (Box2d from Bnd); - - class SequenceOfOwner instantiates Sequence from TCollection - (EntityOwner); - - - deferred class SensitiveEntity; - - class ListOfSensitive instantiates List from TCollection - (SensitiveEntity); - - imported PickArgs; - ---Purpose: Structure to provide all-in-one information on picking arguments + imported PickResult; + ---Purpose: Structure to provide all-in-one result of selection of sensitive -- for "Matches" method of SelectBasics_SensitiveEntity. + imported SelectingVolumeManager; + MaxOwnerPriority returns Integer; MinOwnerPriority returns Integer; diff --git a/src/SelectBasics/SelectBasics_BasicTool.cdl b/src/SelectBasics/SelectBasics_BasicTool.cdl deleted file mode 100644 index e67525eebb..0000000000 --- a/src/SelectBasics/SelectBasics_BasicTool.cdl +++ /dev/null @@ -1,59 +0,0 @@ --- Created on: 1995-06-08 --- Created by: Robert COUBLANC --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class BasicTool from SelectBasics - - ---Purpose: give Tools for sorting Selection results - -- (example : sensitive entities matching) - -uses - Pnt2d from gp, - Array1OfPnt2d from TColgp -is - - MatchSegments(myclass; - P1,P2 : Pnt2d from gp; - P3,P4 : Pnt2d from gp) - returns Boolean; - ---Purpose: returns True if The Segment {P1P2} is - -- intersected by the segment {P3P4} - - MatchSegment(myclass; - pBegin,pEnd : Pnt2d from gp; - X,Y,aTol : Real; - DMin : in out Real) returns Boolean; - ---Level: Internal - ---Purpose: return True if Segment(pBegin, pEnd) is Selected - - AutoInter(myclass; aPolyg2d: Array1OfPnt2d from TColgp) - returns Boolean; - - MatchPolyg2d (myclass; - tabpoint: Array1OfPnt2d from TColgp; - X,Y,aTol: Real; - DMin : in out Real; - Rank : in out Integer) returns Boolean; - ---Level: Internal - ---Purpose: package method used to find if a point - -- is close enough to a polygon of 2D points - -- to be Used by Primitives like curves or faces... - -- Rank gives the index of the touched - -- segment - - - - -end BasicTool; diff --git a/src/SelectBasics/SelectBasics_BasicTool.cxx b/src/SelectBasics/SelectBasics_BasicTool.cxx deleted file mode 100644 index d2a87893db..0000000000 --- a/src/SelectBasics/SelectBasics_BasicTool.cxx +++ /dev/null @@ -1,151 +0,0 @@ -// Created on: 1995-06-08 -// Created by: Robert COUBLANC -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include - - -//================================================== -// Function: -// Purpose : -//================================================== - -Standard_Boolean SelectBasics_BasicTool:: -MatchSegments(const gp_Pnt2d & A, - const gp_Pnt2d & B, - const gp_Pnt2d & C, - const gp_Pnt2d & D) -{ - - Standard_Real d[6],det,deta,detb; - - if(Max(A.X(),B.X())Max(C.X(),D.X())) return Standard_False; - if(Max(A.Y(),B.Y())Max(C.Y(),D.Y())) return Standard_False; - - d[0] = B.X()-A.X();d[1]=C.X()-D.X();d[2]=C.X()-A.X(); - d[3] = B.Y()-A.Y();d[4]=C.Y()-D.Y();d[5]=C.Y()-A.Y(); - - det = d[0]*d[4]-d[3]*d[1]; - deta = d[4]*d[2]-d[5]*d[1]; - detb = d[0]*d[5]-d[3]*d[2]; - - if(Abs(det)<=Precision::Confusion()) return Standard_False; - if(deta/det1+Precision::Confusion()) return Standard_False; - if(detb/det1+Precision::Confusion()) return Standard_False; - - return Standard_True; -} - - - -//================================================== -// Function: MatchSegment -// Purpose : Return True if Segment(pBegin, pEnd) is Selected -//================================================== -Standard_Boolean SelectBasics_BasicTool::MatchSegment(const gp_Pnt2d& pBegin,const gp_Pnt2d& pEnd, - const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) -{ - const Standard_Real SqTol = aTol * aTol; - gp_Vec2d AB, AC, BC; - const gp_Pnt2d apoint(X,Y); - - AB.SetCoord(pEnd.X()-pBegin.X(),pEnd.Y()-pBegin.Y()); - AC.SetCoord(X-pBegin.X(),Y-pBegin.Y()); - BC.SetCoord(pEnd.X()-X,pEnd.Y()-Y); - - //1. Check the ends, do not estimate distance to the segment itself here - if((apoint.SquareDistance(pBegin)=0. && AB.Dot(BC)>=0.){ - //3. Estimate distance from the mouse point to the segment - // if length of segment exceeds tolerance - const Standard_Real aSegLen = AB.Magnitude(); - if (aSegLen>aTol){ - DMin=Abs(AB.Crossed(gp_Vec2d(pBegin,apoint))/aSegLen); - if (DMin -#include - -//! Structure to provide all-in-one information on picking arguments -//! for "Matches" method of SelectBasics_SensitiveEntity. -struct SelectBasics_PickArgs -{ -public: - - //! Constructor. - //! @param theX mouse picking coordinate on x-axis of selection coord space. - //! @param theY mouse picking coordinate on y-axis of selection coord space. - //! @param theTolerance x, y coordinate tolerance. - //! @param theDepthMin minimum picking depth in selection coord space. - //! @param theDepthMax maximum picking depth in selection coord space. - //! @param thePickingLine line going through picking point. - SelectBasics_PickArgs (const Standard_Real theX, - const Standard_Real theY, - const Standard_Real theTolerance, - const Standard_Real theDepthMin, - const Standard_Real theDepthMax, - const gp_Lin& thePickingLine) - : myX (theX), myY (theY), myTolerance (theTolerance), - myDepthMin (theDepthMin), myDepthMax (theDepthMax), - myPickingLine (thePickingLine) {} - -public: - - inline Standard_Real X() const { return myX; } - - inline Standard_Real Y() const { return myY; } - - inline Standard_Real Tolerance() const { return myTolerance; } - - inline Standard_Real DepthMin() const { return myDepthMin; } - - inline Standard_Real DepthMax() const { return myDepthMax; } - - inline const gp_Lin& PickLine() const { return myPickingLine; } - - //! @return True if passed depth lies outside valid depth range. - inline Standard_Boolean IsClipped(const Standard_Real theDepth) const - { - return (theDepth <= myDepthMin || theDepth >= myDepthMax); - } - -private: - - Standard_Real myX; //!< mouse picking coordinate on x-axis of selection coord space. - Standard_Real myY; //!< mouse picking coordinate on y-axis of selection coord space. - Standard_Real myTolerance; //!< x, y coordinate tolerance - Standard_Real myDepthMin; //!< minimum picking depth in selection coord space. - Standard_Real myDepthMax; //!< maximum picking depth in selection coord space. - gp_Lin myPickingLine; //!< line going through picking point -}; - -#endif diff --git a/src/SelectBasics/SelectBasics_PickResult.hxx b/src/SelectBasics/SelectBasics_PickResult.hxx new file mode 100644 index 0000000000..9088525de2 --- /dev/null +++ b/src/SelectBasics/SelectBasics_PickResult.hxx @@ -0,0 +1,55 @@ +// Created on: 2014-11-14 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectBasics_PickResult_HeaderFile +#define _SelectBasics_PickResult_HeaderFile + +#include +#include + +//! This structure provides unified access to the results of +//! Matches() method in all sensitive entities. +struct SelectBasics_PickResult +{ +public: + + SelectBasics_PickResult() + : myDepth (DBL_MAX), + myDistToCenter (DBL_MAX) {} + + SelectBasics_PickResult (const Standard_Real theDepth, + const Standard_Real theDistToCenter) + : myDepth (theDepth), + myDistToCenter (theDistToCenter) {} + +public: + inline const Standard_Real Depth() const + { + return myDepth; + } + + inline const Standard_Real DistToGeomCenter() const + { + return myDistToCenter; + } + +private: + //!< Depth to detected point + Standard_Real myDepth; + //!< Distance from 3d projection user-picked selection point to entity's geometry center + Standard_Real myDistToCenter; +}; + +#endif // _SelectBasics_PickResult_HeaderFile diff --git a/src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx b/src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx new file mode 100644 index 0000000000..0596813bfd --- /dev/null +++ b/src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx @@ -0,0 +1,89 @@ +// Created on: 2014-08-21 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectBasics_SelectingVolumeManager_HeaderFile +#define _SelectBasics_SelectingVolumeManager_HeaderFile + +#include +#include +#include + +class Bnd_Box; +class gp_Pnt; +class TColgp_Array1OfPnt; + +//! This class provides an interface for selecting volume manager, +//! which is responsible for all overlap detection methods and +//! calculation of minimum depth, distance to center of geometry +//! and detected closest point on entity. +class SelectBasics_SelectingVolumeManager +{ +public: + + //! Available selection types + enum SelectionType { Point, Box, Polyline, Unknown }; + +public: + + SelectBasics_SelectingVolumeManager() {}; + + virtual ~SelectBasics_SelectingVolumeManager() {}; + + virtual const Standard_Integer GetActiveSelectionType() const = 0; + + //! Returns true if selecting volume is overlapped by box theBox + virtual const Standard_Boolean Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) = 0; + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box with minimum + //! corner at point theMinPt and maximum at point theMaxPt + virtual const Standard_Boolean Overlaps (const NCollection_Vec3& theMinPt, + const NCollection_Vec3& theMaxPt) = 0; + + //! Returns true if selecting volume is overlapped by point thePt + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt, + Standard_Real& theDepth) = 0; + + //! Returns true if selecting volume is overlapped by planar convex polygon, which points + //! are stored in theArrayOfPts, taking into account sensitivity type theSensType + virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Standard_Integer theSensType, + Standard_Real& theDepth) = 0; + + //! Returns true if selecting volume is overlapped by line segment with start point at thePt1 + //! and end point at thePt2 + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + Standard_Real& theDepth) = 0; + + //! Returns true if selecting volume is overlapped by triangle with vertices thePt1, + //! thePt2 and thePt3, taking into account sensitivity type theSensType + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + const gp_Pnt& thePt3, + Standard_Integer theSensType, + Standard_Real& theDepth) = 0; + + //! Calculates distance from 3d projection of user-defined selection point + //! to the given point theCOG + virtual const Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) = 0; + + virtual NCollection_Vec3 DetectedPoint (const Standard_Real theDepth) const = 0; + +protected: + SelectionType myActiveSelectionType; //!< Active selection type: point, box or polyline +}; + +#endif // _SelectBasics_SelectingVolumeManager_HeaderFile diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.cdl b/src/SelectBasics/SelectBasics_SensitiveEntity.cdl index 7be63b14a5..02d7d0fbcb 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.cdl +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.cdl @@ -16,131 +16,76 @@ deferred class SensitiveEntity from SelectBasics inherits TShared from MMgt - ---Purpose: root class ; the inheriting classes will be able to give - -- sensitive Areas for the dynamic selection algorithms + ---Purpose: root class; the inheriting classes will be able to give + -- sensitive Areas for the dynamic selection algorithms uses EntityOwner, - ListOfBox2d, - PickArgs, - Array1OfPnt2d from TColgp, - Box2d from Bnd + BndBox3d from Select3D, + PickResult, + SelectingVolumeManager is - Initialize (OwnerId : EntityOwner; - aSensitivityFactor : ShortReal from Standard =1); - - - Set (me:mutable ; TheOwnerId : EntityOwner) is virtual; - ---Level: Public - + Initialize (theOwnerId : EntityOwner; + theSensFactor : Real from Standard = 2.0); - OwnerId(me) returns any EntityOwner is static; + Set (me : mutable; + theOwnerId : EntityOwner) + is virtual; + ---Level: Public + ---Purpose: Sets owner of the entity + + + OwnerId (me) + returns any EntityOwner + is static; ---Level: Public ---C++: return const& - - - Areas(me:mutable; aresult : in out ListOfBox2d ) is deferred; - ---Level: Public - ---Purpose: to be implemented specifically by each type of - -- sensitive primitive . - -- + ---Purpose: Returns pointer to owner of the entity - Matches (me : mutable; - thePickArgs : PickArgs from SelectBasics; - theMatchDMin : out Real from Standard; - theMatchDepth : out Real from Standard) returns Boolean is deferred; + + Matches (me : mutable; + theMgr : out SelectingVolumeManager from SelectBasics; + thePickResult : out PickResult from SelectBasics) + returns Boolean is deferred; ---Level: Public - ---Purpose: Checks whether the sensitive entity matches the picking detection - -- area (close to the picking line). This method takes into account depth - -- limits produced by abstract view: far/near planes, clippings. - -- Please port existing implementations of your picking detection, which - -- were done at Matches (X, Y, Tol, DMin) method to this one, introducing - -- the depth checks. Please note that the previous method is suppressed - -- and the virtual implementations are not used by OCC selection framework. - -- The porting procedure for simple sensitives (or if you are not interested - -- in implementing full scale depth checks) can be simplified to writing the - -- following code snippet: - -- @code - -- { // example code for porting descendants of Select3D_SensitiveEntity - -- - -- // invoke implementation of obsolete matches method (if implemented)... - -- if (!Matches (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin)) - -- return Standard_False; - -- - -- // invoke your implementation of computing depth (if implemented)... - -- Standard_Real aDetectDepth = ComputeDepth (thePickArgs.PickLine()); - -- - -- return !thePickArgs.IsClipped(aDetectDepth); - -- } - -- @endcode - -- @param thePickArgs [in] the picking arguments. - -- @param theMatchDMin [out] the minimum distance on xy plane from point - -- of picking to center of gravity of the detected sub-part of sensitive - -- entity or the whole sensitive (e.g. used for resolving selection of - -- coinciding circles, selection will be set to the one whose center is - -- closest to the picking point). - -- @param theMatchDepth [out] the minimum detected depth: depth of the - -- closest detected sub-part of sensitive entity (or the whole sensitive). - -- @return True if the sensitive matches the detection area. - -- This method is an entry point for picking detection framework. - -- The method is triggered when it is required to compose list of - -- detected sensitive entities. The sensitives are filtered out from - -- detection result if returned value is False. The passed entities are - -- then can be sorted by "theDetectDist", "theDetectDepth" parameters. + ---Purpose: Checks whether the sensitive entity is overlapped by + -- current selecting volume - Matches (me :mutable; - XMin,YMin,XMax,YMax : Real from Standard; - aTol: Real from Standard) - returns Boolean - is deferred; - ---Level: Public - ---Purpose: returns True if the box (Xmin,YMin)------(Xmax,Ymax) - -- contains the SensitiveEntity. - -- Necessary for selection using elastic boxes,or segments. - - - Matches (me :mutable; - Polyline:Array1OfPnt2d from TColgp; - aBox:Box2d from Bnd; - aTol: Real from Standard) - returns Boolean - is deferred; - ---Level: Public - ---Purpose: returns True if the polyline xi,yi - -- contains the SensitiveEntity. - -- Necessary for selection using polyline selection - - NeedsConversion(me) returns Boolean is deferred ; - - Is3D(me) returns Boolean from Standard is deferred; - ---Purpose: returns True if able to give 3D information - -- (Depth,...). See Select3D - - MaxBoxes(me) returns Integer is deferred; - ---Purpose: returns the max number of boxes the entity is able to give - -- at a time - - - SetSensitivityFactor(me:mutable; aFactor:ShortReal from Standard); + SetSensitivityFactor (me : mutable; + theSensFactor :Real from Standard); ---C++: inline + ---Purpose: Allows to manage the sensitivity of the entity - SensitivityFactor(me) returns ShortReal from Standard; + SensitivityFactor (me) + returns Real from Standard; ---C++: inline ---Purpose: allows a better sensitivity for -- a specific entity in selection algorithms -- useful for small sized entities. + NbSubElements (me : mutable) returns Integer from Standard + is deferred; + ---Purpose: Returns the number of sub-entities or elements in + -- sensitive entity. Is used to determine if entity is + -- complex and needs to pre-build BVH at the creation of + -- sensitive entity step or is light-weighted so the tree + -- can be build on demand with unnoticeable delay + + BoundingBox (me : mutable) returns BndBox3d from Select3D is deferred; + ---Purpose: Returns bounding box of sensitive entity + + BVH (me : mutable) is deferred; + ---Purpose: Builds BVH tree for sensitive if it is needed + + Clear (me : mutable) is deferred; + ---Purpose: Clears up all the resources and memory allocated + fields myOwnerId : EntityOwner from SelectBasics is protected; - mySFactor : ShortReal from Standard; + mySFactor : Real from Standard; end SensitiveEntity; - - - - - diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx index e047985485..d69189c957 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx @@ -15,23 +15,31 @@ // commercial license or contractual agreement. #include +#include +//======================================================================= +// function : SelectBasics_SensitiveEntity +// purpose : Creates new empty sensitive entity instance +//======================================================================= +SelectBasics_SensitiveEntity::SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId, + const Standard_Real theSensFactor) +: myOwnerId (theOwnerId), + mySFactor (theSensFactor) {} +//======================================================================= +// function : Set +// purpose : Sets owner of the entity +//======================================================================= +void SelectBasics_SensitiveEntity::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId) +{ + myOwnerId = theOwnerId; +} -//================================== -//function : Initialize -//purpose : -//================================== -SelectBasics_SensitiveEntity -::SelectBasics_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId, - const Standard_ShortReal aFactor): -myOwnerId(OwnerId), -mySFactor(aFactor) -{} - - -void SelectBasics_SensitiveEntity -::Set (const Handle(SelectBasics_EntityOwner)& TheOwnerId) { myOwnerId = TheOwnerId;} - -const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity -::OwnerId() const {return myOwnerId;} +//======================================================================= +// function : OwnerId +// purpose : Returns pointer to owner of the entity +//======================================================================= +const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity::OwnerId() const +{ + return myOwnerId; +} diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.lxx b/src/SelectBasics/SelectBasics_SensitiveEntity.lxx index 23a6a9bc0a..54df66f6ce 100644 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.lxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.lxx @@ -12,10 +12,20 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline void SelectBasics_SensitiveEntity:: -SetSensitivityFactor(const Standard_ShortReal F) -{mySFactor = F;} +//======================================================================= +// function : SetSensitivityFactor +// purpose : Allows to manage the sensitivity of the entity +//======================================================================= +inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Real theSensFactor) +{ + mySFactor = theSensFactor; +} -inline Standard_ShortReal SelectBasics_SensitiveEntity:: -SensitivityFactor() const -{return mySFactor;} +//======================================================================= +// function : SensitivityFactor +// purpose : Gets sensitivity factor for the entity +//======================================================================= +inline Standard_Real SelectBasics_SensitiveEntity::SensitivityFactor() const +{ + return mySFactor; +} diff --git a/src/SelectBasics/SelectBasics_SortAlgo.cdl b/src/SelectBasics/SelectBasics_SortAlgo.cdl deleted file mode 100644 index a21c176f9a..0000000000 --- a/src/SelectBasics/SelectBasics_SortAlgo.cdl +++ /dev/null @@ -1,89 +0,0 @@ --- Created on: 1995-01-23 --- Created by: Didier Piffault --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - --- Full Copy of Select_Rectangle (Didier Piffault 94) - - -class SortAlgo from SelectBasics - - ---Purpose: Quickly selection of a rectangle in a set of rectangles - -- Sort algorithm for 2D rectangles. - - -uses Integer from Standard, - Real from Standard, - MapIteratorOfMapOfInteger from TColStd, - MapOfInteger from TColStd, - ListIteratorOfListOfInteger from TColStd, - Box2d from Bnd, - HArray1OfBox2d from Bnd, - BoundSortBox2d from Bnd - - -is Create - ---Purpose: Empty rectangle selector. - returns SortAlgo from SelectBasics; - - Create (ClippingRectangle : Box2d from Bnd; - sizeOfSensitiveArea : Real from Standard; - theRectangles : HArray1OfBox2d from Bnd) - ---Purpose: Creates a initialized selector. - returns SortAlgo from SelectBasics; - - Initialize (me : in out; - ClippingRectangle : Box2d from Bnd; - sizeOfSensitiveArea : Real from Standard; - theRectangles : HArray1OfBox2d from Bnd) - ---Purpose: Clears and initializes the selector. - is static; - - - InitSelect (me : in out; - x, y : Real from Standard) - ---Purpose: Searchs the items on this position. - is static; - - - InitSelect (me : in out; - rect : Box2d from Bnd) - ---Purpose: Searchs the items in this rectangle. - is static; - - - - More(me) - ---Purpose: Returns true if there is something selected. - returns Boolean from Standard is static; - - Next(me : in out) - ---Purpose: Sets value on the next selected item. - is static; - - Value(me) - ---Purpose: Returns the index of the selected rectangle. - returns Integer from Standard is static; - - -fields clipRect : Box2d from Bnd; - sizeArea : Real from Standard; - sortedRect : BoundSortBox2d from Bnd; - myMap : MapOfInteger from TColStd; - curResult : MapIteratorOfMapOfInteger from TColStd; - -end SortAlgo; - - - diff --git a/src/SelectBasics/SelectBasics_SortAlgo.cxx b/src/SelectBasics/SelectBasics_SortAlgo.cxx deleted file mode 100644 index a6883bf6bd..0000000000 --- a/src/SelectBasics/SelectBasics_SortAlgo.cxx +++ /dev/null @@ -1,116 +0,0 @@ -// Created on: 1994-04-18 -// Created by: Didier PIFFAULT -// Copyright (c) 1994-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include - -//======================================================================= -//function : SelectBasics_SortAlgo -//purpose : -//======================================================================= -SelectBasics_SortAlgo::SelectBasics_SortAlgo() - : sizeArea(0.) -{} - -//======================================================================= -//function : SelectBasics_SortAlgo -//purpose : -//======================================================================= -SelectBasics_SortAlgo::SelectBasics_SortAlgo - (const Bnd_Box2d& ClippingRectangle, - const Standard_Real sizeOfSensitiveArea, - const Handle(Bnd_HArray1OfBox2d)& theRectangles) -: clipRect(ClippingRectangle), sizeArea(sizeOfSensitiveArea) -{ - sortedRect.Initialize(clipRect, theRectangles); -} - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= -void SelectBasics_SortAlgo::Initialize(const Bnd_Box2d& ClippingRectangle, - const Standard_Real sizeOfSensitiveArea, - const Handle(Bnd_HArray1OfBox2d)& theRectangles) -{ - clipRect=ClippingRectangle; - sizeArea=sizeOfSensitiveArea; - sortedRect.Initialize(clipRect, theRectangles); -} - -//======================================================================= -//function : Select -//purpose : -//======================================================================= -void SelectBasics_SortAlgo::InitSelect(const Standard_Real x, - const Standard_Real y) -{ - Bnd_Box2d rep; - rep.Set(gp_Pnt2d(x, y)); - rep.Enlarge(sizeArea); - myMap.Clear() ; - TColStd_ListIteratorOfListOfInteger It(sortedRect.Compare(rep)); - for(;It.More();It.Next()){ - myMap.Add(It.Value()); - } - curResult.Initialize(myMap); -} - -//======================================================================= -//function : Select -//purpose : -//======================================================================= -void SelectBasics_SortAlgo::InitSelect(const Bnd_Box2d& rect) -{ - myMap.Clear() ; - TColStd_ListIteratorOfListOfInteger It(sortedRect.Compare(rect)); - for(;It.More();It.Next()){ - myMap.Add(It.Value()); - } - curResult.Initialize(myMap); - -} - -//======================================================================= -//function : More -//purpose : -//======================================================================= -Standard_Boolean SelectBasics_SortAlgo::More() const -{ - return curResult.More(); -} - -//======================================================================= -//function : Next -//purpose : -//======================================================================= -void SelectBasics_SortAlgo::Next() -{ - curResult.Next(); -} - - -//======================================================================= -//function : Value -//purpose : -//======================================================================= -Standard_Integer SelectBasics_SortAlgo::Value() const -{ - return curResult.Key(); -} - diff --git a/src/SelectMgr/FILES b/src/SelectMgr/FILES index 076e4ef840..9bf32bac46 100755 --- a/src/SelectMgr/FILES +++ b/src/SelectMgr/FILES @@ -1 +1,29 @@ SelectMgr_CompareResults.hxx +SelectMgr_FrustumBuilder.hxx +SelectMgr_FrustumBuilder.cxx +SelectMgr_SelectableObjectSet.hxx +SelectMgr_SelectableObjectSet.cxx +SelectMgr_BaseFrustum.hxx +SelectMgr_BaseFrustum.cxx +SelectMgr_Frustum.hxx +SelectMgr_Frustum.lxx +SelectMgr_RectangularFrustum.hxx +SelectMgr_RectangularFrustum.cxx +SelectMgr_TriangularFrustum.hxx +SelectMgr_TriangularFrustum.cxx +SelectMgr_TriangularFrustumSet.hxx +SelectMgr_TriangularFrustumSet.cxx +SelectMgr_VectorTypes.hxx +SelectMgr_SelectingVolumeManager.hxx +SelectMgr_SelectingVolumeManager.cxx +SelectMgr_Selection.hxx +SelectMgr_Selection.cxx +SelectMgr_Selection.lxx +SelectMgr_SequenceOfSelection.hxx +SelectMgr_SensitiveEntity.hxx +SelectMgr_SensitiveEntity.cxx +SelectMgr_SensitiveEntitySet.hxx +SelectMgr_SensitiveEntitySet.cxx +SelectMgr_ViewerSelector.hxx +SelectMgr_ViewerSelector.cxx +SelectMgr_ViewerSelector.lxx diff --git a/src/SelectMgr/SelectMgr.cdl b/src/SelectMgr/SelectMgr.cdl index 805bc79b73..954487e457 100644 --- a/src/SelectMgr/SelectMgr.cdl +++ b/src/SelectMgr/SelectMgr.cdl @@ -192,9 +192,21 @@ is -- - full -- - partial -- - none. - deferred class SelectableObject; - deferred class ViewerSelector; + enumeration TypeOfBVHUpdate is TBU_Add, + TBU_Remove, + TBU_Renew, + TBU_Invalidate, + TBU_None; + ---Purpose: Keeps track for BVH update state for each SelectMgr_Selection entity in a following way: + -- - Add : 2nd level BVH does not contain any of the selection's sensitive entities and they must be + -- added; + -- - Remove : all sensitive entities of the selection must be removed from 2nd level BVH; + -- - Renew : 2nd level BVH already contains sensitives of the selection, but the its complete update + -- and removal is required. Therefore, sensitives of the selection with this type of update + -- must be removed from 2nd level BVH and added after recomputation. + -- - Invalidate : the 2nd level BVH needs to be rebuilt; + -- - None : entities of the selection are up to date. deferred class Filter; @@ -209,7 +221,7 @@ is class EntityOwner; - class Selection; + deferred class SelectableObject; class SelectionManager; @@ -227,22 +239,11 @@ is class IndexedMapOfOwner instantiates IndexedMap from TCollection (EntityOwner from SelectMgr,MapTransientHasher from TColStd); - class DataMapOfIntegerSensitive instantiates DataMap from TCollection - (Integer, SensitiveEntity from SelectBasics, - MapIntegerHasher from TColStd); - class SequenceOfSelector instantiates Sequence from TCollection - (ViewerSelector); - - class SequenceOfSelection instantiates Sequence from TCollection - (Selection); - - - class DataMapOfSelectionActivation instantiates DataMap from TCollection - (Selection,Integer,MapTransientHasher from TColStd); + (ViewerSelector from SelectMgr); class DataMapOfObjectSelectors instantiates DataMap from TCollection - (SelectableObject,SequenceOfSelector,MapTransientHasher from TColStd); + (SelectableObject from SelectMgr,SequenceOfSelector,MapTransientHasher from TColStd); private class IndexedDataMapOfOwnerCriterion instantiates IndexedDataMap from TCollection @@ -256,4 +257,18 @@ is imported CompareResults; + imported SelectableObjectSet; + imported FrustumBuilder; + imported BaseFrustum; + imported Frustum; + imported RectangularFrustum; + imported TriangularFrustum; + imported TriangularFrustumSet; + imported SelectingVolumeManager; + imported transient class Selection; + imported SequenceOfSelection; + imported SensitiveEntity; + imported SensitiveEntitySet; + imported transient class ViewerSelector; + end SelectMgr; diff --git a/src/SelectMgr/SelectMgr_BaseFrustum.cxx b/src/SelectMgr/SelectMgr_BaseFrustum.cxx new file mode 100644 index 0000000000..cf64c83661 --- /dev/null +++ b/src/SelectMgr/SelectMgr_BaseFrustum.cxx @@ -0,0 +1,191 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +// function : SelectMgr_SelectingVolume +// purpose : Creates new selecting volume with pixel toletance set to 2, +// orthographic camera and empty frustum builder +//======================================================================= +SelectMgr_BaseFrustum::SelectMgr_BaseFrustum() +: myPixelTolerance (2), + myIsOrthographic (Standard_True) +{ + myBuilder = new SelectMgr_FrustumBuilder(); +} + +//======================================================================= +// function : SetCamera +// purpose : Passes camera projection and orientation matrices to builder +//======================================================================= +void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera) +{ + myBuilder->SetOrientation (theCamera->OrientationMatrix()); + myBuilder->SetProjection (theCamera->ProjectionMatrix()); + myIsOrthographic = theCamera->IsOrthographic(); + myBuilder->InvalidateViewport(); +} + +//======================================================================= +// function : SetCamera +// purpose : Passes camera projection and orientation matrices to builder +//======================================================================= +void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection, + const Graphic3d_Mat4d& theOrientation, + const Standard_Integer theIsOrthographic) +{ + myBuilder->SetOrientation (theOrientation); + myBuilder->SetProjection (theProjection); + myIsOrthographic = theIsOrthographic; +} + +//======================================================================= +// function : SetViewport +// purpose : Passes viewport parameters to builder +//======================================================================= +void SelectMgr_BaseFrustum::SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight) +{ + myBuilder->SetViewport (theX, theY, theWidth, theHeight); +} + +//======================================================================= +// function : SetPixelTolerance +// purpose : +//======================================================================= +void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Real theTol) +{ + myPixelTolerance = theTol; +} + +//======================================================================= +// function : SetWindowSize +// purpose : +//======================================================================= +void SelectMgr_BaseFrustum::SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight) +{ + myBuilder->SetWindowSize (theWidth, theHeight); +} + +//======================================================================= +// function : SetBuilder +// purpose : +//======================================================================= +void SelectMgr_BaseFrustum::SetBuilder (const NCollection_Handle& theBuilder) +{ + myBuilder.Nullify(); + myBuilder = theBuilder; +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and +// given axis-aligned box +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const BVH_Box& /*theBndBox*/, + Standard_Real& /*theDepth*/) +{ + return Standard_False; +} + +//======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const SelectMgr_Vec3& /*theMinPt*/, + const SelectMgr_Vec3& /*theMaxPt*/) +{ + return Standard_False; +} + +//======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt*/, + Standard_Real& /*theDepth*/) +{ + return Standard_False; +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// ordered set of points, representing line segments. The test +// may be considered of interior part or boundary line defined +// by segments depending on given sensitivity type +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& /*theArrayOfPts*/, + Select3D_TypeOfSensitivity /*theSensType*/, + Standard_Real& /*theDepth*/) +{ + return Standard_False; +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// triangle. The test may be considered of interior part or +// boundary line defined by triangle vertices depending on +// given sensitivity type +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/, + const gp_Pnt& /*thePt2*/, + const gp_Pnt& /*thePt3*/, + Select3D_TypeOfSensitivity /*theSensType*/, + Standard_Real& /*theDepth*/) +{ + return Standard_False; +} + +//======================================================================= +// function : Overlaps +// purpose : Checks if line segment overlaps selecting volume +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/, + const gp_Pnt& /*thePt2*/, + Standard_Real& /*theDepth*/) +{ + return Standard_False; +} + +//======================================================================= +// function : DistToGeometryCenter +// purpose : Measures distance between 3d projection of user-picked +// screen point and given point theCOG +//======================================================================= +const Standard_Real SelectMgr_BaseFrustum::DistToGeometryCenter (const gp_Pnt& /*theCOG*/) +{ + return DBL_MAX; +} + +SelectMgr_Vec3 SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const +{ + return SelectMgr_Vec3 (RealLast()); +} + +//======================================================================= +// function : IsClipped +// purpose : Checks if the point of sensitive in which selection was +// detected belongs to the region defined by clipping planes +//======================================================================= +const Standard_Boolean SelectMgr_BaseFrustum::IsClipped (const Graphic3d_SequenceOfHClipPlane& /*thePlanes*/, + const Standard_Real /*theDepth*/) +{ + return Standard_True; +} diff --git a/src/SelectMgr/SelectMgr_BaseFrustum.hxx b/src/SelectMgr/SelectMgr_BaseFrustum.hxx new file mode 100644 index 0000000000..32fb41ae54 --- /dev/null +++ b/src/SelectMgr/SelectMgr_BaseFrustum.hxx @@ -0,0 +1,143 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_BaseFrustum_HeaderFile +#define _SelectMgr_BaseFrustum_HeaderFile + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +//! This class is an interface for different types of selecting frustums, +//! defining different selection types, like point, box or polyline +//! selection. It contains signatures of functions for detection of +//! overlap by sensitive entity and initializes some data for building +//! the selecting frustum +class SelectMgr_BaseFrustum +{ +public: + + //! Creates new selecting volume with pixel toletance set to 2, + //! orthographic camera and empty frustum builder + SelectMgr_BaseFrustum(); + + virtual ~SelectMgr_BaseFrustum() {}; + + //! Passes camera projection and orientation matrices to builder + void SetCamera (const Handle(Graphic3d_Camera)& theCamera); + + //! Passes camera projection and orientation matrices to builder + void SetCamera (const Graphic3d_Mat4d& theProjection, + const Graphic3d_Mat4d& theOrientation, + const Standard_Integer theIsOrthographic); + + void SetPixelTolerance (const Standard_Real theTol); + + void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight); + + //! Passes viewport parameters to builder + void SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight); + + //! Nullifies the builder created in the constructor and copies the pointer given + void SetBuilder (const NCollection_Handle& theBuilder); + + + //! Builds volume according to the point and given pixel tolerance + virtual void Build (const gp_Pnt2d& /*thePoint*/) {}; + + //! Builds volume according to the selected rectangle + virtual void Build (const gp_Pnt2d& /*theMinPt*/, + const gp_Pnt2d& /*theMaxPt*/) {}; + + //! Builds volume according to the triangle given + virtual void Build (const gp_Pnt2d& /*theP1*/, + const gp_Pnt2d& /*theP2*/, + const gp_Pnt2d& /*theP3*/) {}; + + //! Builds selecting volumes set according to polyline points + virtual void Build (const TColgp_Array1OfPnt2d& /*thePoints*/) {}; + + virtual NCollection_Handle Transform (const gp_Trsf& /*theTrsf*/) { return NULL; } + + //! SAT intersection test between defined volume and given axis-aligned box + virtual const Standard_Boolean Overlaps (const BVH_Box& theBndBox, + Standard_Real& theDepth); + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box + //! with minimum corner at point theMinPt and maximum at point theMaxPt + virtual const Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPt, + const SelectMgr_Vec3& theMaxPt); + + //! Intersection test between defined volume and given point + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt, + Standard_Real& theDepth); + + //! SAT intersection test between defined volume and given ordered set of points, + //! representing line segments. The test may be considered of interior part or + //! boundary line defined by segments depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth); + + //! Checks if line segment overlaps selecting frustum + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + Standard_Real& theDepth); + + //! SAT intersection test between defined volume and given triangle. The test may + //! be considered of interior part or boundary line defined by triangle vertices + //! depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + const gp_Pnt& thePt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth); + + //! Measures distance between 3d projection of user-picked + //! screen point and given point theCOG + virtual const Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG); + + virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const; + + //! Checks if the point of sensitive in which selection was detected belongs + //! to the region defined by clipping planes + virtual const Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, + const Standard_Real theDepth); + +protected: + Standard_Real myPixelTolerance; //!< Pixel tolerance + Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic + + NCollection_Handle myBuilder; //!< A tool implementing methods for volume build +}; + +#endif // _SelectMgr_BaseFrustum_HeaderFile diff --git a/src/SelectMgr/SelectMgr_EntityOwner.cxx b/src/SelectMgr/SelectMgr_EntityOwner.cxx index de07861a84..8a0b522ca1 100644 --- a/src/SelectMgr/SelectMgr_EntityOwner.cxx +++ b/src/SelectMgr/SelectMgr_EntityOwner.cxx @@ -55,11 +55,8 @@ void SelectMgr_EntityOwner::Set(const Handle(SelectMgr_SelectableObject)& aSO) } Standard_Boolean SelectMgr_EntityOwner::HasSelectable() const -{ - Handle(Standard_Transient) aNull; - if(mySelectable != aNull.operator->()){ - if(!Selectable().IsNull()) return Standard_True;} - return Standard_False; +{ + return mySelectable != NULL; } Handle(SelectMgr_SelectableObject) SelectMgr_EntityOwner::Selectable() const diff --git a/src/SelectMgr/SelectMgr_Frustum.hxx b/src/SelectMgr/SelectMgr_Frustum.hxx new file mode 100644 index 0000000000..84f42907de --- /dev/null +++ b/src/SelectMgr/SelectMgr_Frustum.hxx @@ -0,0 +1,114 @@ +// Created on: 2015-03-16 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_Frustum_HeaderFile +#define _SelectMgr_Frustum_HeaderFile + +#include +#include +#include +#include +#include +#include + +//! This is an internal class containing representation of rectangular selecting frustum, created in case +//! of point and box selection, and algorithms for overlap detection between selecting +//! frustum and sensitive entities. The principle of frustum calculation: +//! - for point selection: on a near view frustum plane rectangular neighborhood of +//! user-picked point is created according to the pixel tolerance +//! given and then this rectangle is projected onto far view frustum +//! plane. This rectangles define the parallel bases of selecting frustum; +//! - for box selection: box points are projected onto near and far view frustum planes. +//! These 2 projected rectangles define parallel bases of selecting frustum. +//! Overlap detection tests are implemented according to the terms of separating axis +//! theorem (SAT). +//! Vertex order: +//! - for triangular frustum: V0_Near, V1_Near, V2_Near, +//! V0_Far, V1_Far, V2_Far; +//! - for rectangular frustum: LeftTopNear, LeftTopFar, +//! LeftBottomNear,LeftBottomFar, +//! RightTopNear, RightTopFar, +//! RightBottomNear, RightBottomFar. +//! Plane order in array: +//! - for triangular frustum: V0V1, V1V2, V0V2, Near, Far; +//! - for rectangular frustum: Top, Bottom, Left, Right, Near, Far. +//! Uncollinear edge directions order: +//! - for rectangular frustum: Horizontal, Vertical, +//! LeftLower, RightLower, +//! LeftUpper, RightUpper; +//! - for triangular frustum: V0_Near - V0_Far, V1_Near - V1_Far, V2_Near - V2_Far, +//! V1_Near - V0_Near, V2_Near - V1_Near, V2_Near - V0_Near. +template +class SelectMgr_Frustum : public SelectMgr_BaseFrustum +{ +public: + + SelectMgr_Frustum() : SelectMgr_BaseFrustum() {}; + +protected: + + // SAT Tests for different objects + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box + //! with minimum corner at point theMinPt and maximum at point theMaxPt + const Standard_Boolean hasOverlap (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt); + + //! SAT intersection test between defined volume and given point + const Standard_Boolean hasOverlap (const gp_Pnt& thePnt); + + //! SAT intersection test between defined volume and given segment + const Standard_Boolean hasOverlap (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2); + + //! SAT intersection test between frustum given and planar convex polygon represented as ordered point set + const Standard_Boolean hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + SelectMgr_Vec3& theNormal); + + //! SAT intersection test between defined volume and given triangle + const Standard_Boolean hasOverlap (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + SelectMgr_Vec3& theNormal); + +private: + + //! Checks if AABB and frustum are separated along the given axis + Standard_Boolean isSeparated (const SelectMgr_Vec3& theBoxMin, + const SelectMgr_Vec3& theBoxMax, + const SelectMgr_Vec3& theAxis) const; + + //! Checks if triangle and frustum are separated along the given axis + Standard_Boolean isSeparated (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + const SelectMgr_Vec3& theAxis) const; + +protected: + + SelectMgr_Vec3 myPlanes[N + 2]; //!< Plane equations + SelectMgr_Vec3 myVertices[N * 2]; //!< Vertices coordinates + + Standard_Real myMaxVertsProjections[N + 2]; //!< Cached projections of vertices onto frustum plane directions + Standard_Real myMinVertsProjections[N + 2]; //!< Cached projections of vertices onto frustum plane directions + Standard_Real myMaxOrthoVertsProjections[3]; //!< Cached projections of vertices onto directions of ortho unit vectors + Standard_Real myMinOrthoVertsProjections[3]; //!< Cached projections of vertices onto directions of ortho unit vectors + + SelectMgr_Vec3 myEdgeDirs[6]; //!< Cached edge directions +}; + +#include + +#endif // _SelectMgr_Frustum_HeaderFile diff --git a/src/SelectMgr/SelectMgr_Frustum.lxx b/src/SelectMgr/SelectMgr_Frustum.lxx new file mode 100644 index 0000000000..5480089f0b --- /dev/null +++ b/src/SelectMgr/SelectMgr_Frustum.lxx @@ -0,0 +1,501 @@ +// Created on: 2015-03-16 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z()) +#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z()) + +// ======================================================================= +// function : isSeparated +// purpose : Checks if AABB and frustum are separated along the given axis. +// ======================================================================= +template +Standard_Boolean SelectMgr_Frustum::isSeparated (const SelectMgr_Vec3& theBoxMin, + const SelectMgr_Vec3& theBoxMax, + const SelectMgr_Vec3& theAxis) const +{ + // frustum projection + Standard_Real aMinF = DBL_MAX; + Standard_Real aMaxF = -DBL_MAX; + + // box projection + Standard_Real aMinB = DBL_MAX; + Standard_Real aMaxB = -DBL_MAX; + + const Standard_Real aBoxProj1 = + theAxis.x() * (theAxis.x() < 0.0 ? theBoxMax.x() : theBoxMin.x()) + + theAxis.y() * (theAxis.y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) + + theAxis.z() * (theAxis.z() < 0.0 ? theBoxMax.z() : theBoxMin.z()); + + const Standard_Real aBoxProj2 = + theAxis.x() * (theAxis.x() < 0.0 ? theBoxMin.x() : theBoxMax.x()) + + theAxis.y() * (theAxis.y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) + + theAxis.z() * (theAxis.z() < 0.0 ? theBoxMin.z() : theBoxMax.z()); + + aMinB = Min (aBoxProj1, aBoxProj2); + aMaxB = Max (aBoxProj1, aBoxProj2); + + for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) + { + const Standard_Real aProj = DOT (myVertices[aVertIdx], theAxis); + + aMinF = Min (aMinF, aProj); + aMaxF = Max (aMaxF, aProj); + + if (aMinF <= aMaxB && aMaxF >= aMinB) + { + return Standard_False; + } + } + + return aMinF > aMaxB || aMaxF < aMinB; +} + +// ======================================================================= +// function : isSeparated +// purpose : Checks if triangle and frustum are separated along the +// given axis +// ======================================================================= +template +Standard_Boolean SelectMgr_Frustum::isSeparated (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + const SelectMgr_Vec3& theAxis) const +{ + // frustum projection + Standard_Real aMinF = RealLast(); + Standard_Real aMaxF = RealFirst(); + + // triangle projection + Standard_Real aMinTr = RealLast(); + Standard_Real aMaxTr = RealFirst(); + + Standard_Real aTriangleProj; + + aTriangleProj = DOTp (theAxis, thePnt1); + aMinTr = Min (aMinTr, aTriangleProj); + aMaxTr = Max (aMaxTr, aTriangleProj); + + aTriangleProj = DOTp (theAxis, thePnt2); + aMinTr = Min (aMinTr, aTriangleProj); + aMaxTr = Max (aMaxTr, aTriangleProj); + + aTriangleProj = DOTp (theAxis, thePnt3); + aMinTr = Min (aMinTr, aTriangleProj); + aMaxTr = Max (aMaxTr, aTriangleProj); + + for (Standard_Integer aVertIter = 0; aVertIter < N * 2; ++aVertIter) + { + const Standard_Real aProj = DOT (myVertices[aVertIter], theAxis); + + aMinF = Min (aMinF, aProj); + aMaxF = Max (aMaxF, aProj); + + if (aMinF <= aMaxTr && aMaxF >= aMinTr) + { + return Standard_False; + } + } + + return aMinF > aMaxTr || aMaxF < aMinTr; +} + +// ======================================================================= +// function : hasOverlap +// purpose : Returns true if selecting volume is overlapped by +// axis-aligned bounding box with minimum corner at point +// theMinPnt and maximum at point theMaxPnt +// ======================================================================= +template +const Standard_Boolean SelectMgr_Frustum::hasOverlap (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt) +{ + // E0 test + if (theMinPnt.x() > myMaxOrthoVertsProjections[0] + || theMaxPnt.x() < myMinOrthoVertsProjections[0]) + { + return Standard_False; + } + + // E1 test + if (theMinPnt.y() > myMaxOrthoVertsProjections[1] + || theMaxPnt.y() < myMinOrthoVertsProjections[1]) + { + return Standard_False; + } + + // E2 test + if (theMinPnt.z() > myMaxOrthoVertsProjections[2] + || theMaxPnt.z() < myMinOrthoVertsProjections[2]) + { + return Standard_False; + } + + const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) + { + Standard_Real aBoxProjMax = RealFirst(); + Standard_Real aBoxProjMin = RealLast(); + Standard_Real aFrustumProjMax = RealFirst(); + Standard_Real aFrustumProjMin = RealLast(); + SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + + aFrustumProjMax = myMaxVertsProjections[aPlaneIdx]; + aFrustumProjMin = myMinVertsProjections[aPlaneIdx]; + + const Standard_Real aBoxProj1 = + aPlane.x() * (aPlane.x() < 0.f ? theMaxPnt.x() : theMinPnt.x()) + + aPlane.y() * (aPlane.y() < 0.f ? theMaxPnt.y() : theMinPnt.y()) + + aPlane.z() * (aPlane.z() < 0.f ? theMaxPnt.z() : theMinPnt.z()); + + const Standard_Real aBoxProj2 = + aPlane.x() * (aPlane.x() < 0.f ? theMinPnt.x() : theMaxPnt.x()) + + aPlane.y() * (aPlane.y() < 0.f ? theMinPnt.y() : theMaxPnt.y()) + + aPlane.z() * (aPlane.z() < 0.f ? theMinPnt.z() : theMaxPnt.z()); + + aBoxProjMin = Min (aBoxProj1, aBoxProj2); + aBoxProjMax = Max (aBoxProj1, aBoxProj2); + + if (aBoxProjMin > aFrustumProjMax + || aBoxProjMax < aFrustumProjMin) + { + return Standard_False; + } + } + + SelectMgr_Vec3 aBndBoxDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6; + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir) + { + SelectMgr_Vec3 anEdge1 = aBndBoxDimensions[aDim]; + SelectMgr_Vec3 anEdge2 = myEdgeDirs[aVolDir]; + SelectMgr_Vec3 aTestDirection = SelectMgr_Vec3 (anEdge1.y() * anEdge2.z() - anEdge1.z() * anEdge2.y(), + anEdge1.z() * anEdge2.x() - anEdge1.x() * anEdge2.z(), + anEdge1.x() * anEdge2.y() - anEdge1.y() * anEdge2.x()); + + if (isSeparated (theMinPnt, theMaxPnt, aTestDirection)) + { + return Standard_False; + } + } + } + + return Standard_True; +} + +// ======================================================================= +// function : hasOverlap +// purpose : SAT intersection test between defined volume and given point +// ======================================================================= +template +const Standard_Boolean SelectMgr_Frustum::hasOverlap (const gp_Pnt& thePnt) +{ + SelectMgr_Vec3 aPnt (thePnt.X(), thePnt.Y(), thePnt.Z()); + + const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) + { + Standard_Real aPointProj = RealLast(); + Standard_Real aFrustumProjMax = RealFirst(); + Standard_Real aFrustumProjMin = RealLast(); + SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + + aPointProj = DOT (aPlane, aPnt); + + aFrustumProjMax = myMaxVertsProjections[aPlaneIdx]; + aFrustumProjMin = myMinVertsProjections[aPlaneIdx]; + + if (aPointProj > aFrustumProjMax + || aPointProj < aFrustumProjMin) + { + return Standard_False; + } + } + + return Standard_True; +} + +// ======================================================================= +// function : hasOverlap +// purpose : SAT intersection test between defined volume and given segment +// ======================================================================= +template +const Standard_Boolean SelectMgr_Frustum::hasOverlap (const gp_Pnt& theStartPnt, + const gp_Pnt& theEndPnt) +{ + const SelectMgr_Vec3& aDir = SelectMgr_Vec3 (theEndPnt.X() - theStartPnt.X(), + theEndPnt.Y() - theStartPnt.Y(), + theEndPnt.Z() - theStartPnt.Z()); + if (std::sqrt (aDir.x() * aDir.x() + aDir.y() * aDir.y() + aDir.z () * aDir.z()) < Precision::Confusion()) + return Standard_True; + + const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) + { + Standard_Real aMinSegm = RealLast(), aMaxSegm = RealFirst(); + Standard_Real aMinF = RealLast(), aMaxF = RealFirst(); + SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + + Standard_Real aProj1 = DOTp (aPlane, theStartPnt); + Standard_Real aProj2 = DOTp (aPlane, theEndPnt); + aMinSegm = Min (aProj1, aProj2); + aMaxSegm = Max (aProj1, aProj2); + + aMaxF = myMaxVertsProjections[aPlaneIdx]; + aMinF = myMinVertsProjections[aPlaneIdx]; + + if (aMinSegm > aMaxF + || aMaxSegm < aMinF) + { + return Standard_False; + } + } + + Standard_Real aMin1 = DBL_MAX, aMax1 = -DBL_MAX; + Standard_Real aMin2 = DBL_MAX, aMax2 = -DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDir, myVertices[aVertIdx]); + aMax2 = Max (aMax2, aProjection); + aMin2 = Min (aMin2, aProjection); + } + Standard_Real aProj1 = DOTp (aDir, theStartPnt); + Standard_Real aProj2 = DOTp (aDir, theEndPnt); + aMin1 = Min (aProj1, aProj2); + aMax1 = Max (aProj1, aProj2); + if (aMin1 > aMax2 + || aMax1 < aMin2) + { + return Standard_False; + } + + Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6; + for (Standard_Integer aEdgeDirIdx = 0; aEdgeDirIdx < aDirectionsNb; ++aEdgeDirIdx) + { + Standard_Real aMinSegm = DBL_MAX, aMaxSegm = -DBL_MAX; + Standard_Real aMinF = DBL_MAX, aMaxF = -DBL_MAX; + + SelectMgr_Vec3 aTestDir = SelectMgr_Vec3 (aDir.y() * myEdgeDirs[aEdgeDirIdx].z() - aDir.z() * myEdgeDirs[aEdgeDirIdx].y(), + aDir.z() * myEdgeDirs[aEdgeDirIdx].x() - aDir.x() * myEdgeDirs[aEdgeDirIdx].z(), + aDir.x() * myEdgeDirs[aEdgeDirIdx].y() - aDir.y() * myEdgeDirs[aEdgeDirIdx].x()); + + Standard_Real Proj1 = DOTp (aTestDir, theStartPnt); + Standard_Real Proj2 = DOTp (aTestDir, theEndPnt); + aMinSegm = Min (Proj1, Proj2); + aMaxSegm = Max (Proj1, Proj2); + + for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) + { + Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]); + aMaxF = Max (aMaxF, aProjection); + aMinF = Min (aMinF, aProjection); + } + + if (aMinSegm > aMaxF + || aMaxSegm < aMinF) + { + return Standard_False; + } + } + + return Standard_True; +} + +// ======================================================================= +// function : hasOverlap +// purpose : SAT intersection test between frustum given and planar convex +// polygon represented as ordered point set +// ======================================================================= +template +const Standard_Boolean SelectMgr_Frustum::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + SelectMgr_Vec3& theNormal) +{ + Standard_Integer aStartIdx = theArrayOfPnts->Lower(); + Standard_Integer anEndIdx = theArrayOfPnts->Upper(); + + const gp_Pnt& aPnt1 = theArrayOfPnts->Value (aStartIdx); + const gp_Pnt& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1); + const gp_Pnt& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2); + const gp_XYZ aVec1 = aPnt1.XYZ() - aPnt2.XYZ(); + const gp_XYZ aVec2 = aPnt3.XYZ() - aPnt2.XYZ(); + theNormal = SelectMgr_Vec3 (aVec2.Y() * aVec1.Z() - aVec2.Z() * aVec1.Y(), + aVec2.Z() * aVec1.X() - aVec2.X() * aVec1.Z(), + aVec2.X() * aVec1.Y() - aVec2.Y() * aVec1.X()); + Standard_Real aPolygProjection = DOTp (theNormal, aPnt1); + + Standard_Real aMax = RealFirst(); + Standard_Real aMin = RealLast(); + for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) + { + Standard_Real aProjection = DOT (theNormal, myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + if (aPolygProjection > aMax + || aPolygProjection < aMin) + { + return Standard_False; + } + + Standard_Integer aPlanesNb = N == 4 ? N + 2 : N + 1; + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < aPlanesNb; ++aPlaneIdx) + { + Standard_Real aMaxF = RealFirst(); + Standard_Real aMinF = RealLast(); + Standard_Real aMaxPolyg = RealFirst(); + Standard_Real aMinPolyg = RealLast(); + SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter) + { + Standard_Real aProjection = DOTp (aPlane, theArrayOfPnts->Value (aPntIter)); + aMaxPolyg = Max (aMaxPolyg, aProjection); + aMinPolyg = Min (aMinPolyg, aProjection); + } + aMaxF = myMaxVertsProjections[aPlaneIdx]; + aMinF = myMinVertsProjections[aPlaneIdx]; + if (aMinPolyg > aMaxF + || aMaxPolyg < aMinF) + { + return Standard_False; + } + } + + Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6; + for (Standard_Integer aPntsIter = aStartIdx; aPntsIter <= anEndIdx; ++aPntsIter) + { + const gp_XYZ aSegmDir = aPntsIter == anEndIdx ? theArrayOfPnts->Value (aStartIdx).XYZ() - theArrayOfPnts->Value (anEndIdx).XYZ() + : theArrayOfPnts->Value (aPntsIter + 1).XYZ() - theArrayOfPnts->Value (aPntsIter).XYZ(); + for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir) + { + Standard_Real aMaxPolyg = RealFirst(); + Standard_Real aMinPolyg = RealLast(); + Standard_Real aMaxF = RealFirst(); + Standard_Real aMinF = RealLast(); + SelectMgr_Vec3 aTestDir = SelectMgr_Vec3 (aSegmDir.Y() * myEdgeDirs[aVolDir].z() - aSegmDir.Z() * myEdgeDirs[aVolDir].y(), + aSegmDir.Z() * myEdgeDirs[aVolDir].x() - aSegmDir.X() * myEdgeDirs[aVolDir].z(), + aSegmDir.X() * myEdgeDirs[aVolDir].y() - aSegmDir.Y() * myEdgeDirs[aVolDir].x()); + + for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter) + { + Standard_Real aProjection = DOTp (aTestDir, theArrayOfPnts->Value (aPntIter)); + aMaxPolyg = Max (aMaxPolyg, aProjection); + aMinPolyg = Min (aMinPolyg, aProjection); + } + + for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) + { + Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]); + aMaxF = Max (aMaxF, aProjection); + aMinF = Min (aMinF, aProjection); + } + + if (aMinPolyg > aMaxF + || aMaxPolyg < aMinF) + { + return Standard_False; + } + } + } + + return Standard_True; +} + +// ======================================================================= +// function : hasOverlap +// purpose : SAT intersection test between defined volume and given triangle +// ======================================================================= +template +const Standard_Boolean SelectMgr_Frustum::hasOverlap (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + SelectMgr_Vec3& theNormal) +{ + + SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z()); + SelectMgr_Vec3 aPnt2 (thePnt2.X(), thePnt2.Y(), thePnt2.Z()); + SelectMgr_Vec3 aPnt3 (thePnt3.X(), thePnt3.Y(), thePnt3.Z()); + SelectMgr_Vec3 aTrEdges[3] = { aPnt2 - aPnt1, + aPnt3 - aPnt2, + aPnt1 - aPnt3 }; + + const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) + { + SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + Standard_Real aTriangleProj; + + aTriangleProj = DOT (aPlane, aPnt1); + Standard_Real aTriangleProjMin = aTriangleProj; + Standard_Real aTriangleProjMax = aTriangleProj; + + aTriangleProj = DOT (aPlane, aPnt2); + aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj); + aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj); + + aTriangleProj = DOT (aPlane, aPnt3); + aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj); + aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj); + + Standard_Real aFrustumProjMax = myMaxVertsProjections[aPlaneIdx]; + Standard_Real aFrustumProjMin = myMinVertsProjections[aPlaneIdx]; + if (aTriangleProjMin > aFrustumProjMax + || aTriangleProjMax < aFrustumProjMin) + { + return Standard_False; + } + } + + theNormal = SelectMgr_Vec3 (aTrEdges[2].y() * aTrEdges[0].z() - aTrEdges[2].z() * aTrEdges[0].y(), + aTrEdges[2].z() * aTrEdges[0].x() - aTrEdges[2].x() * aTrEdges[0].z(), + aTrEdges[2].x() * aTrEdges[0].y() - aTrEdges[2].y() * aTrEdges[0].x()); + if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal)) + { + return Standard_False; + } + + Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6; + for (Standard_Integer aTriangleEdgeIdx = 0; aTriangleEdgeIdx < 3; ++aTriangleEdgeIdx) + { + for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir) + { + SelectMgr_Vec3 anEdge1 = myEdgeDirs[aVolDir]; + SelectMgr_Vec3 anEdge2 = aTrEdges[aTriangleEdgeIdx]; + SelectMgr_Vec3 aTestDirection = SelectMgr_Vec3 ( + anEdge1.y() * anEdge2.z() - anEdge1.z() * anEdge2.y(), + anEdge1.z() * anEdge2.x() - anEdge1.x() * anEdge2.z(), + anEdge1.x() * anEdge2.y() - anEdge1.y() * anEdge2.x()); + + if (isSeparated (thePnt1, thePnt2, thePnt3, aTestDirection)) + { + return Standard_False; + } + } + } + + return Standard_True; +} + +#undef DOT +#undef DOTp diff --git a/src/SelectMgr/SelectMgr_FrustumBuilder.cxx b/src/SelectMgr/SelectMgr_FrustumBuilder.cxx new file mode 100644 index 0000000000..f57fc47efc --- /dev/null +++ b/src/SelectMgr/SelectMgr_FrustumBuilder.cxx @@ -0,0 +1,221 @@ +// Created on: 2014-11-24 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z()) +#define LENGTH(A) (std::sqrt (A.x() * A.x() + A.y() * A.y() + A.z() * A.z())) + +//======================================================================= +// function : SelectMgr_FrustumBuilder +// purpose : Creates new frustum builder with empty matrices +//======================================================================= +SelectMgr_FrustumBuilder::SelectMgr_FrustumBuilder() +: myOrientation(), + myProjection(), + myWidth (INT_MAX), + myHeight (INT_MAX), + myIsViewportSet (Standard_False) {} + +//======================================================================= +// function : SetOrientation +// purpose : Stores current orientation matrix +//======================================================================= +void SelectMgr_FrustumBuilder::SetOrientation (const Graphic3d_Mat4d& theOrientation) +{ + myOrientation = theOrientation; +} + +//======================================================================= +// function : SetProjection +// purpose : Stores current projection matrix +//======================================================================= +void SelectMgr_FrustumBuilder::SetProjection (const Graphic3d_Mat4d& theProjection) +{ + myProjection = theProjection; +} + +//======================================================================= +// function : SetWindowSize +// purpose : Stores current window width and height +//======================================================================= +void SelectMgr_FrustumBuilder::SetWindowSize (const Standard_Integer theWidth, + const Standard_Integer theHeight) +{ + myWidth = theWidth; + myHeight = theHeight; +} + +//======================================================================= +// function : SetViewport +// purpose : Stores current viewport coordinates +//======================================================================= +void SelectMgr_FrustumBuilder::SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight) +{ + myViewport = NCollection_Vec4 (theX, theY, theWidth, theHeight); + myIsViewportSet = Standard_True; +} + +//======================================================================= +// function : InvalidateViewport +// purpose : +//======================================================================= +void SelectMgr_FrustumBuilder::InvalidateViewport() +{ + myIsViewportSet = Standard_False; +} + +//======================================================================= +// function : SignedPlanePntDist +// purpose : Calculates signed distance between plane with equation +// theEq and point thePnt +//======================================================================= +Standard_Real SelectMgr_FrustumBuilder::SignedPlanePntDist (const SelectMgr_Vec3& theEq, + const SelectMgr_Vec3& thePnt) const +{ + const Standard_Real aNormLength = LENGTH (theEq); + const Standard_Real anInvNormLength = aNormLength < Precision::Confusion() ? 0.0 : 1.0 / aNormLength; + const Standard_Real anA = theEq.x() * anInvNormLength; + const Standard_Real aB = theEq.y() * anInvNormLength; + const Standard_Real aC = theEq.z() * anInvNormLength; + return anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z(); +} + +// ======================================================================= +// function : PlaneEquation +// purpose : Creates plane equation from 3 points: thePntA, thePntB and +// thePntC containing point theInnerPnt +// ======================================================================= +SelectMgr_Vec3 SelectMgr_FrustumBuilder::PlaneEquation (const SelectMgr_Vec3& thePntA, + const SelectMgr_Vec3& thePntB, + const SelectMgr_Vec3& thePntC, + const SelectMgr_Vec3& theInnerPnt) const +{ + NCollection_Vec4 aPlaneEquation (0.0); + + const SelectMgr_Vec3& aDirVecAB = thePntB - thePntA; + const SelectMgr_Vec3& aDirVecAC = thePntC - thePntA; + SelectMgr_Vec3 aPlaneNormal = SelectMgr_Vec3 (aDirVecAB.y() * aDirVecAC.z() - aDirVecAB.z() * aDirVecAC.y(), + aDirVecAB.z() * aDirVecAC.x() - aDirVecAB.x() * aDirVecAC.z(), + aDirVecAB.x() * aDirVecAC.y() - aDirVecAB.y() * aDirVecAC.x()); + + if (SignedPlanePntDist (aPlaneNormal, theInnerPnt) > 0) + { + aPlaneNormal *= -1.0; + } + + return aPlaneNormal; +} + +//======================================================================= +// function : PlaneEquation +// purpose : Calculates plane equation from 3 points +//======================================================================= +SelectMgr_Vec3 SelectMgr_FrustumBuilder::PlaneEquation (const SelectMgr_Vec3& thePntA, + const SelectMgr_Vec3& thePntB, + const SelectMgr_Vec3& thePntC) const +{ + const SelectMgr_Vec3& aVec1 = thePntB - thePntA; + const SelectMgr_Vec3& aVec2 = thePntC - thePntA; + SelectMgr_Vec3 aPlaneEquation = SelectMgr_Vec3 (aVec1.y() * aVec2.z() - aVec1.z() * aVec2.y(), + aVec1.z() * aVec2.x() - aVec1.x() * aVec2.z(), + aVec1.x() * aVec2.y() - aVec1.y() * aVec2.x()); + + return aPlaneEquation; +} + +//======================================================================= +// function : safePointCast +// purpose : +//======================================================================= +static NCollection_Vec4 safePointCast (const gp_Pnt& thePnt) +{ + Standard_Real aLim = 1e15f; + + // have to deal with values greater then max float + gp_Pnt aSafePoint = thePnt; + const Standard_Real aBigFloat = aLim * 0.1f; + if (Abs (aSafePoint.X()) > aLim) + aSafePoint.SetX (aSafePoint.X() >= 0 ? aBigFloat : -aBigFloat); + if (Abs (aSafePoint.Y()) > aLim) + aSafePoint.SetY (aSafePoint.Y() >= 0 ? aBigFloat : -aBigFloat); + if (Abs (aSafePoint.Z()) > aLim) + aSafePoint.SetZ (aSafePoint.Z() >= 0 ? aBigFloat : -aBigFloat); + + // convert point + NCollection_Vec4 aPnt (aSafePoint.X(), aSafePoint.Y(), aSafePoint.Z(), 1.0); + + return aPnt; +} + +//======================================================================= +// function : unProject +// purpose : Unprojects point from NDC coords to 3d world space +//======================================================================= +SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const +{ + Graphic3d_Mat4d aInvView; + Graphic3d_Mat4d aInvProj; + + // this case should never happen + if (!myOrientation.Inverted (aInvView) || !myProjection.Inverted (aInvProj)) + { + return SelectMgr_Vec3 (0.0, 0.0, 0.0); + } + + // use compatible type of point + NCollection_Vec4 aPnt = safePointCast (thePnt); + + aPnt = aInvProj * aPnt; // convert to view coordinate space + aPnt = aInvView * aPnt; // convert to world coordinate space + + const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w()); + + return SelectMgr_Vec3 (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW); +} + +// ======================================================================= +// function : ProjectPntOnViewPlane +// purpose : Projects 2d screen point onto view frustum plane: +// theZ = 0 - near plane, +// theZ = 1 - far plane +// ======================================================================= +SelectMgr_Vec3 SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX, + const Standard_Real& theY, + const Standard_Real& theZ) const +{ + Standard_Real aX, anY, aZ; + + // map coords to NDC + if (!myIsViewportSet) + { + aX = 2.0 * theX / myWidth - 1.0; + anY = (myHeight - 1 - theY) / myHeight * 2.0 - 1.0; + aZ = 2.0 * theZ - 1.0; + } + else + { + aX = 2.0 * (theX - myWidth * myViewport.x()) / + (myWidth * (myViewport.z() - myViewport.x())) - 1.0; + anY = 2.0 * (theY - myHeight * myViewport.y()) / + (myHeight * (myViewport.w() - myViewport.y())) - 1.0; + aZ = theZ; + } + + return unProject (gp_Pnt (aX, anY, aZ)); +} diff --git a/src/SelectMgr/SelectMgr_FrustumBuilder.hxx b/src/SelectMgr/SelectMgr_FrustumBuilder.hxx new file mode 100644 index 0000000000..419b3551d9 --- /dev/null +++ b/src/SelectMgr/SelectMgr_FrustumBuilder.hxx @@ -0,0 +1,92 @@ +// Created on: 2014-11-24 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_FrustumBuilder_HeaderFile +#define _SelectMgr_FrustumBuilder_HeaderFile + +#include +#include +#include +#include + +//! The purpose of this class is to provide unified interface for building +//! selecting frustum depending on current camera projection and orientation +//! matrices, window size and viewport parameters. +class SelectMgr_FrustumBuilder +{ +public: + //! Creates new frustum builder with empty matrices + SelectMgr_FrustumBuilder(); + + ~SelectMgr_FrustumBuilder() {}; + + //! Stores current orientation matrix + void SetOrientation (const Graphic3d_Mat4d& theOrientation); + + //! Stores current projection matrix + void SetProjection (const Graphic3d_Mat4d& theProjection); + + //! Stores current window width and height + void SetWindowSize (const Standard_Integer theWidth, + const Standard_Integer theHeight); + + //! Stores current viewport coordinates + void SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight); + + void InvalidateViewport(); + + //! Calculates signed distance between plane with equation + //! theEq and point thePnt + Standard_Real SignedPlanePntDist (const SelectMgr_Vec3& theEq, + const SelectMgr_Vec3& thePnt) const; + + //! Creates plane equation from 3 points: thePntA, thePntB and + //! thePntC containing point theInnerPnt + SelectMgr_Vec3 PlaneEquation (const SelectMgr_Vec3& thePntA, + const SelectMgr_Vec3& thePntB, + const SelectMgr_Vec3& thePntC, + const SelectMgr_Vec3& theInnerPnt) const; + + //! Calculates plane equation from 3 points + SelectMgr_Vec3 PlaneEquation (const SelectMgr_Vec3& thePntA, + const SelectMgr_Vec3& thePntB, + const SelectMgr_Vec3& thePntC) const; + + //! Projects 2d screen point onto view frustum plane: + //! theZ = 0 - near plane, + //! theZ = 1 - far plane + SelectMgr_Vec3 ProjectPntOnViewPlane (const Standard_Real& theX, + const Standard_Real& theY, + const Standard_Real& theZ) const; + +private: + + //! Unprojects point from NDC coords to 3d world space + SelectMgr_Vec3 unProject (const gp_Pnt& thePnt) const; + +private: + + Graphic3d_Mat4d myOrientation; + Graphic3d_Mat4d myProjection; + Standard_Integer myWidth; + Standard_Integer myHeight; + NCollection_Vec4 myViewport; + Standard_Boolean myIsViewportSet; +}; + +#endif // _SelectMgr_FrustumBuilder_HeaderFile diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx new file mode 100644 index 0000000000..a59892e30c --- /dev/null +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx @@ -0,0 +1,792 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#include + +#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z()) +#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z()) +#define DISTANCE(A, B) (std::sqrt ((A.x() - B.x()) * (A.x() - B.x()) + (A.y() - B.y()) * (A.y() - B.y()) + (A.z() - B.z()) * (A.z() - B.z()))) +#define DISTANCEp(A, B) (std::sqrt ((A.x() - B.X()) * (A.x() - B.X()) + (A.y() - B.Y()) * (A.y() - B.Y()) + (A.z() - B.Z()) * (A.z() - B.Z()))) + +// ======================================================================= +// function : segmentSegmentDistance +// purpose : +// ======================================================================= +void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegPnt1, + const gp_Pnt& theSegPnt2, + Standard_Real& theDepth) +{ + SelectMgr_Vec3 anU = SelectMgr_Vec3 (theSegPnt2.X() - theSegPnt1.X(), + theSegPnt2.Y() - theSegPnt1.Y(), + theSegPnt2.Z() - theSegPnt1.Z()); + SelectMgr_Vec3 aV = myViewRayDir; + SelectMgr_Vec3 aW = SelectMgr_Vec3 (theSegPnt1.X() - myNearPickedPnt.x(), + theSegPnt1.Y() - myNearPickedPnt.y(), + theSegPnt1.Z() - myNearPickedPnt.z()); + Standard_Real anA = DOT (anU, anU); + Standard_Real aB = DOT (anU, aV); + Standard_Real aC = DOT (aV, aV); + Standard_Real aD = DOT (anU, aW); + Standard_Real anE = DOT (aV, aW); + Standard_Real aCoef = anA * aC - aB * aB; + Standard_Real aSc, aSn, aSd = aCoef; + Standard_Real aTc, aTn, aTd = aCoef; + + if (aCoef < Precision::Confusion()) + { + aSn = 0.0; + aSd = 1.0; + aTn = anE; + aTd = aC; + } + else + { + aSn = (aB * anE - aC * aD); + aTn = (anA * anE - aB * aD); + if (aSn < 0.0) + { + aSn = 0.0; + aTn = anE; + aTd = aC; + } + else if (aSn > aSd) + { + aSn = aSd; + aTn = anE + aB; + aTd = aC; + } + } + + if (aTn < 0.0) + { + aTn = 0.0; + if (-aD < 0.0) + aSn = 0.0; + else if (-aD > anA) + aSn = aSd; + else { + aSn = -aD; + aSd = anA; + } + } + else if (aTn > aTd) + { + aTn = aTd; + if ((-aD + aB) < 0.0) + aSn = 0; + else if ((-aD + aB) > anA) + aSn = aSd; + else { + aSn = (-aD + aB); + aSd = anA; + } + } + aSc = (Abs (aSn) < Precision::Confusion() ? 0.0 : aSn / aSd); + aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd); + + SelectMgr_Vec3 aDiff = aW + (anU * aSc) - (aV * aTc); + SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + myViewRayDir * aTc; + theDepth = DISTANCE (myNearPickedPnt, aClosestPnt); +} + +// ======================================================================= +// function : segmentPlaneIntersection +// purpose : +// ======================================================================= +void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec3& thePlane, + const gp_Pnt& thePntOnPlane, + Standard_Real& theDepth) +{ + SelectMgr_Vec3 anU = myViewRayDir; + SelectMgr_Vec3 aW = SelectMgr_Vec3 (myNearPickedPnt.x() - thePntOnPlane.X(), + myNearPickedPnt.y() - thePntOnPlane.Y(), + myNearPickedPnt.z() - thePntOnPlane.Z()); + Standard_Real aD = DOT (thePlane, anU); + Standard_Real aN = -DOT (thePlane, aW); + + if (Abs (aD) < Precision::Confusion()) + { + if (Abs (aN) < Precision::Angular()) + { + theDepth = DBL_MAX; + return; + } + else + { + theDepth = DBL_MAX; + return; + } + } + + Standard_Real aParam = aN / aD; + if (aParam < 0.0 || aParam > 1.0) + { + theDepth = DBL_MAX; + return; + } + + SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + anU * aParam; + theDepth = DISTANCE (myNearPickedPnt, aClosestPnt); +} + +// ======================================================================= +// function : Build +// purpose : Build volume according to the point and given pixel +// tolerance +// ======================================================================= +void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint) +{ + myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0); + myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0); + myViewRayDir = myFarPickedPnt - myNearPickedPnt; + + // LeftTopNear + myVertices[0] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, + thePoint.Y() + myPixelTolerance / 2.0, + 0.0); + // LeftTopFar + myVertices[1] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, + thePoint.Y() + myPixelTolerance / 2.0, + 1.0); + // LeftBottomNear + myVertices[2] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, + thePoint.Y() - myPixelTolerance / 2.0, + 0.0); + // LeftBottomFar + myVertices[3] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, + thePoint.Y() - myPixelTolerance / 2.0, + 1.0); + // RightTopNear + myVertices[4] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0, + thePoint.Y() + myPixelTolerance / 2.0, + 0.0); + // RightTopFar + myVertices[5] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0, + thePoint.Y() + myPixelTolerance / 2.0, + 1.0); + // RightBottomNear + myVertices[6] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0, + thePoint.Y() - myPixelTolerance / 2.0, + 0.0); + // RightBottomFar + myVertices[7] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0, + thePoint.Y() - myPixelTolerance / 2.0, + 1.0); + // Top + myPlanes[0] = myBuilder->PlaneEquation (myVertices[1], + myVertices[0], + myVertices[5], + myVertices[6]); + // Bottom + myPlanes[1] = myBuilder->PlaneEquation (myVertices[3], + myVertices[2], + myVertices[7], + myVertices[4]); + // Left + myPlanes[2] = myBuilder->PlaneEquation (myVertices[1], + myVertices[0], + myVertices[2], + myVertices[6]); + // Right + myPlanes[3] = myBuilder->PlaneEquation (myVertices[5], + myVertices[4], + myVertices[6], + myVertices[2]); + // Near + myPlanes[4] = myBuilder->PlaneEquation (myVertices[4], + myVertices[6], + myVertices[2], + myVertices[3]); + // Far + myPlanes[5] = myBuilder->PlaneEquation (myVertices[5], + myVertices[7], + myVertices[3], + myVertices[2]); + + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + myMaxVertsProjections[aPlaneIdx] = aMax; + myMinVertsProjections[aPlaneIdx] = aMin; + } + + SelectMgr_Vec3 aDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]); + aMax = Max (aProjection, aMax); + aMin = Min (aProjection, aMin); + } + myMaxOrthoVertsProjections[aDim] = aMax; + myMinOrthoVertsProjections[aDim] = aMin; + } + + // Horizontal + myEdgeDirs[0] = myVertices[4] - myVertices[0]; + // Vertical + myEdgeDirs[1] = myVertices[2] - myVertices[0]; + // LeftLower + myEdgeDirs[2] = myVertices[2] - myVertices[3]; + // RightLower + myEdgeDirs[3] = myVertices[6] - myVertices[7]; + // LeftUpper + myEdgeDirs[4] = myVertices[0] - myVertices[1]; + // RightUpper + myEdgeDirs[5] = myVertices[4] - myVertices[5]; +} + +// ======================================================================= +// function : Build +// purpose : Build volume according to the selected rectangle +// ======================================================================= +void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d& theMinPnt, + const gp_Pnt2d& theMaxPnt) +{ + myNearPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5, + (theMinPnt.Y() + theMaxPnt.Y()) * 0.5, + 0.0); + myFarPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5, + (theMinPnt.Y() + theMaxPnt.Y()) * 0.5, + 1.0); + myViewRayDir = myFarPickedPnt - myNearPickedPnt; + + // LeftTopNear + myVertices[0] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(), + theMaxPnt.Y(), + 0.0); + // LeftTopFar + myVertices[1] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(), + theMaxPnt.Y(), + 1.0); + // LeftBottomNear + myVertices[2] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(), + theMinPnt.Y(), + 0.0); + // LeftBottomFar + myVertices[3] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(), + theMinPnt.Y(), + 1.0); + // RightTopNear + myVertices[4] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(), + theMaxPnt.Y(), + 0.0); + // RightTopFar + myVertices[5] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(), + theMaxPnt.Y(), + 1.0); + // RightBottomNear + myVertices[6] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(), + theMinPnt.Y(), + 0.0); + // RightBottomFar + myVertices[7] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X() , + theMinPnt.Y(), + 1.0); + + // Top + myPlanes[0] = myBuilder->PlaneEquation (myVertices[1], + myVertices[0], + myVertices[5], + myVertices[6]); + // Bottom + myPlanes[1] = myBuilder->PlaneEquation (myVertices[3], + myVertices[2], + myVertices[7], + myVertices[4]); + // Left + myPlanes[2] = myBuilder->PlaneEquation (myVertices[1], + myVertices[0], + myVertices[2], + myVertices[6]); + // Right + myPlanes[3] = myBuilder->PlaneEquation (myVertices[5], + myVertices[4], + myVertices[6], + myVertices[2]); + // Near + myPlanes[4] = myBuilder->PlaneEquation (myVertices[4], + myVertices[6], + myVertices[2], + myVertices[3]); + // Far + myPlanes[5] = myBuilder->PlaneEquation (myVertices[5], + myVertices[7], + myVertices[3], + myVertices[2]); + + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + myMaxVertsProjections[aPlaneIdx] = aMax; + myMinVertsProjections[aPlaneIdx] = aMin; + } + + SelectMgr_Vec3 aDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + myMaxOrthoVertsProjections[aDim] = aMax; + myMinOrthoVertsProjections[aDim] = aMin; + } + + // Horizontal + myEdgeDirs[0] = myVertices[4] - myVertices[0]; + // Vertical + myEdgeDirs[1] = myVertices[2] - myVertices[0]; + // LeftLower + myEdgeDirs[2] = myVertices[2] - myVertices[3]; + // RightLower + myEdgeDirs[3] = myVertices[6] - myVertices[7]; + // LeftUpper + myEdgeDirs[4] = myVertices[0] - myVertices[1]; + // RightUpper + myEdgeDirs[5] = myVertices[4] - myVertices[5]; +} + +// ======================================================================= +// function : Transform +// purpose : Returns a copy of the frustum transformed according to the matrix given +// ======================================================================= +NCollection_Handle SelectMgr_RectangularFrustum::Transform (const gp_Trsf& theTrsf) +{ + SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum(); + + aRes->myNearPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myNearPickedPnt); + aRes->myFarPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myFarPickedPnt); + aRes->myViewRayDir = aRes->myFarPickedPnt - aRes->myNearPickedPnt; + + aRes->myIsOrthographic = myIsOrthographic; + + // LeftTopNear + aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]); + // LeftTopFar + aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]); + // LeftBottomNear + aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]); + // LeftBottomFar + aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]); + // RightTopNear + aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]); + // RightTopFar + aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]); + // RightBottomNear + aRes->myVertices[6] = SelectMgr_MatOp::Transform (theTrsf, myVertices[6]); + // RightBottomFar + aRes->myVertices[7] = SelectMgr_MatOp::Transform (theTrsf, myVertices[7]); + + // Top + aRes->myPlanes[0] = myBuilder->PlaneEquation (aRes->myVertices[1], + aRes->myVertices[0], + aRes->myVertices[5], + aRes->myVertices[6]); + // Bottom + aRes->myPlanes[1] = myBuilder->PlaneEquation (aRes->myVertices[3], + aRes->myVertices[2], + aRes->myVertices[7], + aRes->myVertices[4]); + // Left + aRes->myPlanes[2] = myBuilder->PlaneEquation (aRes->myVertices[1], + aRes->myVertices[0], + aRes->myVertices[2], + aRes->myVertices[6]); + // Right + aRes->myPlanes[3] = myBuilder->PlaneEquation (aRes->myVertices[5], + aRes->myVertices[4], + aRes->myVertices[6], + aRes->myVertices[2]); + // Near + aRes->myPlanes[4] = myBuilder->PlaneEquation (aRes->myVertices[4], + aRes->myVertices[6], + aRes->myVertices[2], + aRes->myVertices[3]); + // Far + aRes->myPlanes[5] = myBuilder->PlaneEquation (aRes->myVertices[5], + aRes->myVertices[7], + aRes->myVertices[3], + aRes->myVertices[2]); + + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + aRes->myMaxVertsProjections[aPlaneIdx] = aMax; + aRes->myMinVertsProjections[aPlaneIdx] = aMin; + } + + SelectMgr_Vec3 aDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + aRes->myMaxOrthoVertsProjections[aDim] = aMax; + aRes->myMinOrthoVertsProjections[aDim] = aMin; + } + + // Horizontal + aRes->myEdgeDirs[0] = aRes->myVertices[4] - aRes->myVertices[0]; + // Vertical + aRes->myEdgeDirs[1] = aRes->myVertices[2] - aRes->myVertices[0]; + // LeftLower + aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[3]; + // RightLower + aRes->myEdgeDirs[3] = aRes->myVertices[6] - aRes->myVertices[7]; + // LeftUpper + aRes->myEdgeDirs[4] = aRes->myVertices[0] - aRes->myVertices[1]; + // RightUpper + aRes->myEdgeDirs[5] = aRes->myVertices[4] - aRes->myVertices[5]; + + return NCollection_Handle (aRes); +} + +// ======================================================================= +// function : Overlaps +// purpose : Returns true if selecting volume is overlapped by +// axis-aligned bounding box with minimum corner at point +// theMinPnt and maximum at point theMaxPnt +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt) +{ + return hasOverlap (theMinPnt, theMaxPnt); +} + +// ======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and +// given axis-aligned box +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) +{ + const SelectMgr_Vec3& aMinPnt = theBox.CornerMin(); + const SelectMgr_Vec3& aMaxPnt = theBox.CornerMax(); + if (!hasOverlap (aMinPnt, aMaxPnt)) + return Standard_False; + + SelectMgr_Vec3 aNearestPnt = SelectMgr_Vec3 (RealLast(), RealLast(), RealLast()); + aNearestPnt.x() = Max (Min (myNearPickedPnt.x(), aMaxPnt.x()), aMinPnt.x()); + aNearestPnt.y() = Max (Min (myNearPickedPnt.y(), aMaxPnt.y()), aMinPnt.y()); + aNearestPnt.z() = Max (Min (myNearPickedPnt.z(), aMaxPnt.z()), aMinPnt.z()); + + theDepth = DISTANCE (aNearestPnt, myNearPickedPnt); + + return Standard_True; +} + +// ======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt, + Standard_Real& theDepth) +{ + if (!hasOverlap (thePnt)) + return Standard_False; + + SelectMgr_Vec3 aPnt (thePnt.X(), thePnt.Y(), thePnt.Z()); + SelectMgr_Vec3 aV = aPnt - myNearPickedPnt; + SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * (DOT (aV, myViewRayDir) / DOT (myViewRayDir, myViewRayDir)); + + theDepth = DISTANCE (aDetectedPnt, myNearPickedPnt); + + return Standard_True; +} + +// ======================================================================= +// function : Overlaps +// purpose : Checks if line segment overlaps selecting frustum +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + Standard_Real& theDepth) +{ + theDepth = -DBL_MAX; + if (!hasOverlap (thePnt1, thePnt2)) + return Standard_False; + + segmentSegmentDistance (thePnt1, thePnt2, theDepth); + return Standard_True; +} + +// ======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// ordered set of points, representing line segments. The test +// may be considered of interior part or boundary line defined +// by segments depending on given sensitivity type +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) +{ + if (theSensType == Select3D_TOS_BOUNDARY) + { + Standard_Integer aMatchingSegmentsNb = -1; + theDepth = DBL_MAX; + Standard_Integer aLower = theArrayOfPnts->Lower(); + Standard_Integer anUpper = theArrayOfPnts->Upper(); + + for (Standard_Integer aPntIter = aLower; aPntIter <= anUpper; ++aPntIter) + { + const gp_Pnt& aStartPnt = theArrayOfPnts->Value (aPntIter); + const gp_Pnt& aEndPnt = aPntIter == anUpper ? theArrayOfPnts->Value (aLower) + : theArrayOfPnts->Value (aPntIter + 1); + + if (hasOverlap (aStartPnt, aEndPnt)) + { + aMatchingSegmentsNb++; + Standard_Real aSegmentDepth = RealLast(); + segmentSegmentDistance (aStartPnt, aEndPnt, aSegmentDepth); + theDepth = Min (theDepth, aSegmentDepth); + } + } + + if (aMatchingSegmentsNb == -1) + return Standard_False; + } + else if (theSensType == Select3D_TOS_INTERIOR) + { + SelectMgr_Vec3 aPolyNorm (RealLast()); + if (!hasOverlap (theArrayOfPnts, aPolyNorm)) + return Standard_False; + + segmentPlaneIntersection (aPolyNorm, + theArrayOfPnts->Value (theArrayOfPnts->Lower()), + theDepth); + } + + return Standard_True; +} + +// ======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// triangle. The test may be considered of interior part or +// boundary line defined by triangle vertices depending on +// given sensitivity type +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) +{ + if (theSensType == Select3D_TOS_BOUNDARY) + { + Handle(TColgp_HArray1OfPnt) aPntsArray = new TColgp_HArray1OfPnt(1, 4); + aPntsArray->SetValue (1, thePnt1); + aPntsArray->SetValue (2, thePnt2); + aPntsArray->SetValue (3, thePnt3); + aPntsArray->SetValue (4, thePnt1); + return Overlaps (aPntsArray, Select3D_TOS_BOUNDARY, theDepth); + } + else if (theSensType == Select3D_TOS_INTERIOR) + { + SelectMgr_Vec3 aTriangleNormal (RealLast()); + if (!hasOverlap (thePnt1, thePnt2, thePnt3, aTriangleNormal)) + return Standard_False; + + // check if intersection point belongs to triangle's interior part + SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z()); + SelectMgr_Vec3 aTrEdges[3] = { SelectMgr_Vec3 (thePnt2.X() - thePnt1.X(), thePnt2.Y() - thePnt1.Y(), thePnt2.Z() - thePnt1.Z()), + SelectMgr_Vec3 (thePnt3.X() - thePnt2.X(), thePnt3.Y() - thePnt2.Y(), thePnt3.Z() - thePnt2.Z()), + SelectMgr_Vec3 (thePnt1.X() - thePnt3.X(), thePnt1.Y() - thePnt3.Y(), thePnt1.Z() - thePnt3.Z()) }; + SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / DOT (aTriangleNormal, myViewRayDir)); + + Standard_Real aTime = DOT (aTriangleNormal, anEdge); + + SelectMgr_Vec3 aVec = SelectMgr_Vec3 (myViewRayDir.y() * anEdge.z() - myViewRayDir.z() * anEdge.y(), + myViewRayDir.z() * anEdge.x() - myViewRayDir.x() * anEdge.z(), + myViewRayDir.x() * anEdge.y() - myViewRayDir.y() * anEdge.x()); + + Standard_Real anU = DOT (aVec, aTrEdges[2]); + Standard_Real aV = DOT (aVec, aTrEdges[0]); + + Standard_Boolean isInterior = (aTime >= 0.0) && (anU >= 0.0) && (aV >= 0.0) && (anU + aV <= 1.0); + + if (isInterior) + { + SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * aTime; + theDepth = DISTANCE (myNearPickedPnt, aDetectedPnt); + return Standard_True; + } + + gp_Pnt aPnts[3] = {thePnt1, thePnt2, thePnt3}; + Standard_Real aMinDist = RealLast(); + Standard_Integer aNearestEdgeIdx = -1; + SelectMgr_Vec3 aPtOnPlane = myNearPickedPnt + myViewRayDir * aTime; + for (Standard_Integer anEdgeIdx = 0; anEdgeIdx < 3; ++anEdgeIdx) + { + SelectMgr_Vec3 aW = SelectMgr_Vec3 (aPtOnPlane.x() - aPnts[anEdgeIdx].X(), + aPtOnPlane.y() - aPnts[anEdgeIdx].Y(), + aPtOnPlane.z() - aPnts[anEdgeIdx].Z()); + Standard_Real aCoef = DOT (aTrEdges[anEdgeIdx], aW) / DOT (aTrEdges[anEdgeIdx], aTrEdges[anEdgeIdx]); + Standard_Real aDist = DISTANCE (aPtOnPlane, SelectMgr_Vec3 (aPnts[anEdgeIdx].X() + aCoef * aTrEdges[anEdgeIdx].x(), + aPnts[anEdgeIdx].Y() + aCoef * aTrEdges[anEdgeIdx].y(), + aPnts[anEdgeIdx].Z() + aCoef * aTrEdges[anEdgeIdx].z())); + if (aMinDist > aDist) + { + aMinDist = aDist; + aNearestEdgeIdx = anEdgeIdx; + } + } + segmentSegmentDistance (aPnts[aNearestEdgeIdx], aPnts[(aNearestEdgeIdx + 1) % 3], theDepth); + } + + return Standard_True; +} + +// ======================================================================= +// function : DistToGeometryCenter +// purpose : Measures distance between 3d projection of user-picked +// screen point and given point theCOG +// ======================================================================= +const Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt& theCOG) +{ + const SelectMgr_Vec3& aCOG = SelectMgr_Vec3 (theCOG.X(), theCOG.Y(), theCOG.Z()); + return DISTANCE (aCOG, myNearPickedPnt); +} + +// ======================================================================= +// function : DetectedPoint +// purpose : Calculates the point on a view ray that was detected during +// the run of selection algo by given depth +// ======================================================================= +SelectMgr_Vec3 SelectMgr_RectangularFrustum::DetectedPoint (const Standard_Real theDepth) const +{ + return myNearPickedPnt + myViewRayDir * theDepth; +} + +// ======================================================================= +// function : IsClipped +// purpose : Checks if the point of sensitive in which selection was +// detected belongs to the region defined by clipping planes +// ======================================================================= +const Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, + const Standard_Real theDepth) +{ + Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); + Standard_Real aMaxDepth = DBL_MAX; + Standard_Real aMinDepth = -DBL_MAX; + Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD; + for ( ; aPlaneIt.More(); aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value(); + if (!aClipPlane->IsOn()) + continue; + + gp_Pln aGeomPlane = aClipPlane->ToPlane(); + + aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD); + + const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ(); + + Standard_Real aDotProduct = DOTp (myViewRayDir, aPlaneDirXYZ); + Standard_Real aDistance = - (DOTp (myNearPickedPnt, aPlaneDirXYZ) + aPlaneD); + + // check whether the pick line is parallel to clip plane + if (Abs (aDotProduct) < Precision::Angular()) + { + // line lies below the plane and is not clipped, skip + continue; + } + + // compute distance to point of pick line intersection with the plane + Standard_Real aParam = aDistance / aDotProduct; + + // check if ray intersects the plane, in case aIntDist < 0 + // the plane is "behind" the ray + if (aParam < 0.0) + { + continue; + } + + const SelectMgr_Vec3 anIntersectionPt = myNearPickedPnt + myViewRayDir * aParam; + const Standard_Real aDistToPln = DISTANCE (anIntersectionPt, myNearPickedPnt); + + // change depth limits for case of opposite and directed planes + if (aDotProduct < 0.0) + { + aMaxDepth = Min (aDistToPln, aMaxDepth); + } + else if (aDistToPln > aMinDepth) + { + aMinDepth = Max (aDistToPln, aMinDepth); + } + } + + return (theDepth <= aMinDepth || theDepth >= aMaxDepth); +} diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.hxx b/src/SelectMgr/SelectMgr_RectangularFrustum.hxx new file mode 100644 index 0000000000..4ec8fc9bed --- /dev/null +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.hxx @@ -0,0 +1,114 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_RectangularFrustum_HeaderFile +#define _SelectMgr_RectangularFrustum_HeaderFile + +#include + +//! This class contains representation of rectangular selecting frustum, created in case +//! of point and box selection, and algorithms for overlap detection between selecting +//! frustum and sensitive entities. The principle of frustum calculation: +//! - for point selection: on a near view frustum plane rectangular neighborhood of +//! user-picked point is created according to the pixel tolerance +//! given and then this rectangle is projected onto far view frustum +//! plane. This rectangles define the parallel bases of selecting frustum; +//! - for box selection: box points are projected onto near and far view frustum planes. +//! These 2 projected rectangles define parallel bases of selecting frustum. +//! Overlap detection tests are implemented according to the terms of separating axis +//! theorem (SAT). +class SelectMgr_RectangularFrustum : public SelectMgr_Frustum<4> +{ +public: + + SelectMgr_RectangularFrustum() {}; + + //! Builds volume according to the point and given pixel tolerance + virtual void Build (const gp_Pnt2d& thePoint) Standard_OVERRIDE; + + //! Builds volume according to the selected rectangle + virtual void Build (const gp_Pnt2d& theMinPnt, + const gp_Pnt2d& theMaxPnt) Standard_OVERRIDE; + + //! Returns a copy of the frustum transformed according to the matrix given + virtual NCollection_Handle Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; + + + // SAT Tests for different objects + + //! SAT intersection test between defined volume and given axis-aligned box + virtual const Standard_Boolean Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box + //! with minimum corner at point theMinPt and maximum at point theMaxPt + virtual const Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt) Standard_OVERRIDE; + + //! Intersection test between defined volume and given point + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given ordered set of points, + //! representing line segments. The test may be considered of interior part or + //! boundary line defined by segments depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Checks if line segment overlaps selecting frustum + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given triangle. The test may + //! be considered of interior part or boundary line defined by triangle vertices + //! depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Measures distance between 3d projection of user-picked + //! screen point and given point theCOG + virtual const Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) Standard_OVERRIDE; + + //! Calculates the point on a view ray that was detected during the run of selection algo by given depth + virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE; + + //! Checks if the point of sensitive in which selection was detected belongs + //! to the region defined by clipping planes + virtual const Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, + const Standard_Real theDepth) Standard_OVERRIDE; + +protected: + + void segmentSegmentDistance (const gp_Pnt& theSegPnt1, + const gp_Pnt& theSegPnt2, + Standard_Real& theDepth); + + void segmentPlaneIntersection (const SelectMgr_Vec3& thePlane, + const gp_Pnt& thePntOnPlane, + Standard_Real& theDepth); + +private: + + SelectMgr_Vec3 myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane + SelectMgr_Vec3 myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane + SelectMgr_Vec3 myViewRayDir; +}; + +#endif // _SelectMgr_RectangularFrustum_HeaderFile diff --git a/src/SelectMgr/SelectMgr_SelectableObject.cdl b/src/SelectMgr/SelectMgr_SelectableObject.cdl index 1c889c0468..6231ea3b32 100644 --- a/src/SelectMgr/SelectMgr_SelectableObject.cdl +++ b/src/SelectMgr/SelectMgr_SelectableObject.cdl @@ -29,6 +29,7 @@ deferred class SelectableObject from SelectMgr inherits PresentableObject from uses + Box from Bnd, SelectionManager from SelectMgr, Selection from SelectMgr, SequenceOfSelection from SelectMgr, @@ -57,34 +58,36 @@ is ComputeSelection(me:mutable; aSelection : Selection from SelectMgr; aMode : Integer) is deferred; ---Purpose: Recovers and calculates any sensitive primitive, - -- aSelection, available in Shape mode, specified by - -- aMode. As a rule, these are sensitive faces. - -- This method is defined as virtual. This enables you to - -- implement it in the creation of a new class of AIS - -- Interactive Object. You need to do this and in so - -- doing, redefine this method, if you create a class - -- which enriches the list of signatures and types. - - NbPossibleSelection(me) returns Integer from Standard is virtual; - ---Level: Public - ---Purpose: defines the number of different modes of selection - -- (or decomposition) for an Object. - + -- aSelection, available in Shape mode, specified by + -- aMode. As a rule, these are sensitive faces. + -- This method is defined as virtual. This enables you to + -- implement it in the creation of a new class of AIS + -- Interactive Object. You need to do this and in so + -- doing, redefine this method, if you create a class + -- which enriches the list of signatures and types. ---Category: - UpdateSelection (me:mutable) is static; - ---Purpose: re-computes the sensitive primitives for all modes + RecomputePrimitives (me : mutable) + is static; + ---Purpose: Re-computes the sensitive primitives for all modes. IMPORTANT: Do not use + -- this method to update selection primitives except implementing custom selection manager! + -- This method does not take into account necessary BVH updates, but may invalidate the pointers + -- it refers to. TO UPDATE SELECTION properly from outside classes, use method UpdateSelection. - UpdateSelection (me:mutable; aMode: Integer from Standard) is static; - ---Purpose: re-computes the sensitive primitives which correspond to - -- the th selection mode. + RecomputePrimitives (me : mutable; + theMode : Integer from Standard) + is static; + ---Purpose: Re-computes the sensitive primitives which correspond to the th selection mode. + -- IMPORTANT: Do not use this method to update selection primitives except implementing custom selection manager! + -- selection manager! This method does not take into account necessary BVH updates, but may invalidate + -- the pointers it refers to. TO UPDATE SELECTION properly from outside classes, use method UpdateSelection. - AddSelection(me:mutable ;aSelection: Selection from SelectMgr; - aMode : Integer) + AddSelection(me:mutable; aSelection : Selection from SelectMgr; + aMode : Integer) is static; ---Purpose: Adds the selection aSelection with the selection mode -- index aMode to this framework. @@ -100,7 +103,7 @@ is -- completely) when some selection mode is activated not for the first time. Selection(me;aMode : Integer) - returns any Selection from SelectMgr + returns any Selection from SelectMgr is static; ---C++: return const& ---Purpose: Returns the selection Selection having the selection mode aMode. @@ -187,40 +190,68 @@ is ---Purpose: Set Z layer ID and update all presentations of the selectable object. -- The layers mechanism allows drawing objects in higher layers in overlay of objects in lower layers. + UpdateSelection ( me : mutable; + theMode : Integer from Standard = -1) + is static; + ---Purpose: Sets update status FULL to selections of the object. Must be used as the only method of UpdateSelection + -- from outer classes to prevent BVH structures from being outdated. + + BoundingBox (me : mutable; + theBndBox : out Box from Bnd) + is deferred; + ---Purpose: Returns bounding box of selectable object + -- by storing its minimum and maximum 3d coordinates + -- to output parameters + SetAttributes(me:mutable; theDrawer: Drawer from Prs3d) is virtual; - ---Purpose: Initializes the drawing tool theDrawer. - + ---Purpose: Initializes the drawing tool theDrawer. + Attributes(me) returns any Drawer from Prs3d; - ---C++: return const& - ---C++: inline - ---Purpose: Returns the attributes settings. - + ---C++: return const& + ---C++: inline + ---Purpose: Returns the attributes settings. + UnsetAttributes(me:mutable) is virtual; - ---Purpose: Clears settings provided by the drawing tool theDrawer. + ---Purpose: Clears settings provided by the drawing tool theDrawer. SetHilightAttributes(me:mutable; theDrawer: Drawer from Prs3d) is virtual; - ---Purpose: Initializes the hilight drawing tool theDrawer. + ---Purpose: Initializes the hilight drawing tool theDrawer. HilightAttributes(me) returns any Drawer from Prs3d; - ---C++: return const& - ---C++: inline - ---Purpose: Returns the hilight attributes settings. + ---C++: return const& + ---C++: inline + ---Purpose: Returns the hilight attributes settings. UnsetHilightAttributes(me:mutable) is virtual; - ---Purpose: Clears settings provided by the hilight drawing tool theDrawer. + ---Purpose: Clears settings provided by the hilight drawing tool theDrawer. InitDefaultHilightAttributes(myclass; theDrawer : Drawer from Prs3d); - ---Purpose: Initializes theDrawer by default hilight settings. + ---Purpose: Initializes theDrawer by default hilight settings. + + SetAssemblyOwner (me : mutable; + theOwner : EntityOwner from SelectMgr; + theMode : Integer from Standard = -1); + ---Purpose: Sets common entity owner for assembly sensitive object entities + + GetAssemblyOwner (me) + returns EntityOwner from SelectMgr + is static; + ---C++: return const& + ---Purpose: Returns common entity owner if the object is an assembly fields myselections : SequenceOfSelection is protected; myDrawer : Drawer from Prs3d is protected; myHilightDrawer : Drawer from Prs3d is protected; + myAssemblyOwner : EntityOwner from SelectMgr is protected; mycurrent : Integer; myAutoHilight : Boolean from Standard; mySelectionPrs : Presentation from Prs3d; myHilightPrs : Presentation from Prs3d; + +friends + class SelectionManager from SelectMgr end SelectableObject; diff --git a/src/SelectMgr/SelectMgr_SelectableObject.cxx b/src/SelectMgr/SelectMgr_SelectableObject.cxx index 4a0d3a75d7..3985350d93 100644 --- a/src/SelectMgr/SelectMgr_SelectableObject.cxx +++ b/src/SelectMgr/SelectMgr_SelectableObject.cxx @@ -54,6 +54,7 @@ SelectMgr_SelectableObject::SelectMgr_SelectableObject( const PrsMgr_TypeOfPrese PrsMgr_PresentableObject (aTypeOfPresentation3d), myDrawer (new Prs3d_Drawer()), myHilightDrawer (new Prs3d_Drawer()), + myAssemblyOwner (NULL), myAutoHilight (Standard_True) { InitDefaultHilightAttributes (myHilightDrawer); @@ -78,40 +79,63 @@ Standard_Boolean SelectMgr_SelectableObject } //================================================== -// Function: UpdateSelection -// Purpose : +// Function: RecomputePrimitives +// Purpose : IMPORTANT: Do not use this method to update +// selection primitives except implementing custom +// selection manager! This method does not take +// into account necessary BVH updates, but may +// invalidate the pointers it refers to. +// TO UPDATE SELECTION properly from outside classes, +// use method UpdateSelection. //================================================== -void SelectMgr_SelectableObject::UpdateSelection() +void SelectMgr_SelectableObject::RecomputePrimitives() { - for (Standard_Integer I=1;I<=myselections.Length();I++) + for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); aSelIdx++) { - UpdateSelection(myselections.ChangeValue(I)->Mode()); + RecomputePrimitives (myselections.ChangeValue (aSelIdx)->Mode()); } } -Standard_Integer SelectMgr_SelectableObject::NbPossibleSelection() const -{return 0;} - //================================================== -// Function: UpdateSelection -// Purpose : +// Function: RecomputePrimitives +// Purpose : IMPORTANT: Do not use this method to update +// selection primitives except implementing custom +// selection manager! This method does not take +// into account necessary BVH updates, but may +// invalidate the pointers it refers to. +// TO UPDATE SELECTION properly from outside classes, +// use method UpdateSelection. //================================================== -void SelectMgr_SelectableObject::UpdateSelection(const Standard_Integer aMode) +void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode) { - for (Standard_Integer i =1; i<= myselections.Length(); i++ ) { - if (myselections.Value(i)->Mode() == aMode) { - myselections(i)->Clear(); - ComputeSelection(myselections(i),aMode); - myselections(i)->UpdateStatus(SelectMgr_TOU_Partial); + for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ ) + { + if (myselections.Value (aSelIdx)->Mode() == theMode) + { + myselections (aSelIdx)->Clear(); + ComputeSelection (myselections (aSelIdx), theMode); + myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial); + myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew); + if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0) + { + SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode); + } return; } } - Handle(SelectMgr_Selection) S = new SelectMgr_Selection(aMode); - ComputeSelection(S,aMode); - S->UpdateStatus(SelectMgr_TOU_Partial); - - myselections.Append(S); - + + Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode); + ComputeSelection (aNewSel, theMode); + + if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0) + { + SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode); + } + + aNewSel->UpdateStatus (SelectMgr_TOU_Partial); + aNewSel->UpdateBVHStatus (SelectMgr_TBU_Add); + + myselections.Append (aNewSel); } //================================================== @@ -122,8 +146,11 @@ void SelectMgr_SelectableObject::ClearSelections(const Standard_Boolean update) { for (Standard_Integer i =1; i<= myselections.Length(); i++ ) { myselections.Value(i)->Clear(); + myselections.Value (i)->UpdateBVHStatus (SelectMgr_TBU_Remove); if(update) + { myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Full); + } } } @@ -156,18 +183,34 @@ void SelectMgr_SelectableObject ::AddSelection(const Handle(SelectMgr_Selection)& aSel, const Standard_Integer aMode) { - if(aSel->IsEmpty()){ - ComputeSelection(aSel,aMode); + Standard_Boolean isReplaced = Standard_False; + if(aSel->IsEmpty()) + { + ComputeSelection(aSel, aMode); aSel->UpdateStatus(SelectMgr_TOU_Partial); + aSel->UpdateBVHStatus (SelectMgr_TBU_Add); } - if(HasSelection(aMode)) + if (HasSelection(aMode)) + { + const Handle(SelectMgr_Selection)& temp= Selection(aMode); + Standard_Integer I = Search(myselections,temp); + if(I!=0) { - const Handle(SelectMgr_Selection)& temp= Selection(aMode); - Standard_Integer I = Search(myselections,temp); - if(I!=0) myselections.Remove(I); + myselections.Remove(I); + isReplaced = Standard_True; } + } + myselections.Append(aSel); - + if (isReplaced) + { + myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew); + } + + if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && aMode == 0) + { + SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), aMode); + } } @@ -178,31 +221,14 @@ void SelectMgr_SelectableObject //======================================================================= void SelectMgr_SelectableObject::ResetTransformation() { - TopLoc_Location aLoc; - - TopLoc_Location aSelfLocation (Transformation()); - - // les selections - Handle(Select3D_SensitiveEntity) SE; - for(Init();More();Next()){ - const Handle(SelectMgr_Selection) & Sel = CurrentSelection(); - for(Sel->Init();Sel->More();Sel->Next()){ - SE = *((Handle(Select3D_SensitiveEntity)*) &(Sel->Sensitive())); - if(!SE.IsNull()){ - if(SE->HasLocation()) { - if( SE->Location()==aSelfLocation){ - SE->ResetLocation(); - const Handle(SelectBasics_EntityOwner)& EO = SE->OwnerId(); - (*((Handle(SelectMgr_EntityOwner)*)&EO))->ResetLocation();} - else{ - const TopLoc_Location& iniloc =SE->Location(); - SE->SetLocation(iniloc*aSelfLocation.Inverted()); - const Handle(SelectBasics_EntityOwner)& EO = SE->OwnerId(); - (*((Handle(SelectMgr_EntityOwner)*)&EO))->SetLocation(SE->Location());} - } - } + for (Init(); More(); Next()) + { + const Handle(SelectMgr_Selection) & aSel = CurrentSelection(); + for (aSel->Init(); aSel->More(); aSel->Next()) + { + aSel->UpdateStatus(SelectMgr_TOU_Partial); + aSel->UpdateBVHStatus (SelectMgr_TBU_None); } - Sel->UpdateStatus(SelectMgr_TOU_None); } PrsMgr_PresentableObject::ResetTransformation(); @@ -220,6 +246,7 @@ void SelectMgr_SelectableObject::UpdateTransformation() for(Init();More();Next()){ const Handle(SelectMgr_Selection) & Sel = CurrentSelection(); Sel->UpdateStatus(SelectMgr_TOU_Partial); + Sel->UpdateBVHStatus (SelectMgr_TBU_Invalidate); } PrsMgr_PresentableObject::UpdateTransformation(); @@ -236,9 +263,8 @@ void SelectMgr_SelectableObject::UpdateTransformations(const Handle(SelectMgr_Se Handle(Select3D_SensitiveEntity) SE; if(aSelfLocation.IsIdentity()) return; for(Sel->Init();Sel->More();Sel->Next()){ - SE = Handle(Select3D_SensitiveEntity)::DownCast(Sel->Sensitive()); + SE = Handle(Select3D_SensitiveEntity)::DownCast (Sel->Sensitive()->BaseSensitive()); if(!SE.IsNull()){ - SE->UpdateLocation(aSelfLocation); const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId(); Handle(SelectMgr_EntityOwner) aMgrEO = Handle(SelectMgr_EntityOwner)::DownCast (aEOwner); @@ -353,7 +379,7 @@ void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId) for (aSel->Init (); aSel->More (); aSel->Next ()) { Handle(Select3D_SensitiveEntity) aEntity = - Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()); + Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive()); if (!aEntity.IsNull()) { Handle(SelectMgr_EntityOwner) aOwner = @@ -365,6 +391,35 @@ void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId) } } +//======================================================================= +//function : UpdateSelection +//purpose : Sets update status FULL to selections of the object. Must be +// used as the only method of UpdateSelection from outer classes +// to prevent BVH structures from being outdated. +//======================================================================= +void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode) +{ + if (theMode == -1) + { + for (Init(); More(); Next()) + { + const Handle(SelectMgr_Selection)& aSel = CurrentSelection(); + aSel->UpdateStatus (SelectMgr_TOU_Full); + } + + return; + } + + for (Init(); More(); Next()) + { + if (CurrentSelection()->Mode() == theMode) + { + CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full); + return; + } + } +} + //======================================================================= //function : SetAttributes //purpose : @@ -478,3 +533,50 @@ void SelectMgr_SelectableObject::InitDefaultHilightAttributes (const Handle(Prs3 // computed in ::Compute() call for whole shape and stored in base drawer. theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE); } + +//======================================================================= +//function : SetAssemblyOwner +//purpose : Sets common entity owner for assembly sensitive object entities +//======================================================================= +void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner, + const Standard_Integer theMode) +{ + if (theMode == -1) + { + for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter) + { + Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter); + for (aSel->Init(); aSel->More(); aSel->Next()) + { + aSel->Sensitive()->BaseSensitive()->Set (theOwner); + } + } + + return; + } + + if (!HasSelection (theMode)) + return; + + for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter) + { + if (myselections.Value (aModeIter)->Mode() == theMode) + { + Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter); + for (aSel->Init(); aSel->More(); aSel->Next()) + { + aSel->Sensitive()->BaseSensitive()->Set (theOwner); + } + return; + } + } +} + +//======================================================================= +//function : GetAssemblyOwner +//purpose : Returns common entity owner if it is an assembly +//======================================================================= +const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const +{ + return myAssemblyOwner; +} diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx new file mode 100644 index 0000000000..9148657f04 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx @@ -0,0 +1,141 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#include + +//======================================================================= +// function : SelectMgr_SelectableObjectSet +// purpose : Creates new empty objects set and initializes BVH tree +// builder to Binned builder with 1 element per list +//======================================================================= +SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet() +{ + myBuilder = new BVH_BinnedBuilder (1, 32, Standard_False); +} + +//======================================================================= +// function : Append +// purpose : Adds new object to the set and marks BVH tree for rebuild +//======================================================================= +void SelectMgr_SelectableObjectSet::Append (const Handle(SelectMgr_SelectableObject)& theObject) +{ + myObjects.Append (theObject); + myObjectIdxs.Append (myObjects.Size()); + + MarkDirty(); +} + +//======================================================================= +// function : Remove +// purpose : Removes object theObject from set and marks BVH tree for +// rebuild +//======================================================================= +void SelectMgr_SelectableObjectSet::Remove (const Handle(SelectMgr_SelectableObject)& theObject) +{ + for (Standard_Integer anObjectIdx = 1; anObjectIdx <= myObjects.Size(); ++anObjectIdx) + { + if (myObjects.Value (anObjectIdx) == theObject) + { + myObjects.Remove (anObjectIdx); + myObjectIdxs.Clear(); + for (Standard_Integer anObjIdxsIter = 1; anObjIdxsIter <= myObjects.Size(); ++anObjIdxsIter) + { + myObjectIdxs.Append (anObjIdxsIter); + } + MarkDirty(); + break; + } + } +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of object with index theIndex +//======================================================================= +Select3D_BndBox3d SelectMgr_SelectableObjectSet::Box (const Standard_Integer theIndex) const +{ + const Handle(SelectMgr_SelectableObject)& anObject = GetObjectById (theIndex); + Bnd_Box aBox; + anObject->BoundingBox (aBox); + return Select3D_BndBox3d (SelectMgr_Vec3 (aBox.CornerMin().X(), aBox.CornerMin().Y(), aBox.CornerMin().Z()), + SelectMgr_Vec3 (aBox.CornerMax().X(), aBox.CornerMax().Y(), aBox.CornerMax().Z())); +} + +//======================================================================= +// function : Center +// purpose : Returns center of object with index theIndex in the set +// along the given axis theAxis +//======================================================================= +Standard_Real SelectMgr_SelectableObjectSet::Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const +{ + Select3D_BndBox3d aBndBox = Box (theIndex); + Standard_Real aCenter = theAxis == 0 ? (aBndBox.CornerMin().x() + aBndBox.CornerMax().x()) * 0.5 : + (theAxis == 1 ? (aBndBox.CornerMin().y() + aBndBox.CornerMax().y()) * 0.5 : + (aBndBox.CornerMin().z() + aBndBox.CornerMax().z()) * 0.5); + + return aCenter; +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIndex1 and theIndex2 in the set +//======================================================================= +void SelectMgr_SelectableObjectSet::Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) +{ + Standard_Integer anObjectIdx1 = myObjectIdxs.Value (theIndex1 + 1); + Standard_Integer anObjectIdx2 = myObjectIdxs.Value (theIndex2 + 1); + myObjectIdxs.ChangeValue (theIndex1 + 1) = anObjectIdx2; + myObjectIdxs.ChangeValue (theIndex2 + 1) = anObjectIdx1; +} + +//======================================================================= +// function : Size +// purpose : Returns size of objects set +//======================================================================= +Standard_Integer SelectMgr_SelectableObjectSet::Size() const +{ + return myObjectIdxs.Size(); +} + +//======================================================================= +// function : GetObjectById +// purpose : Returns object from set by theIndex given +//======================================================================= +const Handle(SelectMgr_SelectableObject)& SelectMgr_SelectableObjectSet::GetObjectById + (const Standard_Integer theIndex) const +{ + Standard_Integer anIdx = myObjectIdxs.Value (theIndex + 1); + return myObjects.Value (anIdx); +} + +//======================================================================= +// function : Contains +// purpose : Returns true if this objects set contains theObject given +//======================================================================= +const Standard_Boolean SelectMgr_SelectableObjectSet::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const +{ + for (Standard_Integer anObjectIdx = 1; anObjectIdx <= myObjects.Size(); ++anObjectIdx) + { + if (myObjects.Value (anObjectIdx) == theObject) + return Standard_True; + } + + return Standard_False; +} diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx new file mode 100644 index 0000000000..59ac5a4296 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx @@ -0,0 +1,72 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_SelectableObjectSet_HeaderFile +#define _SelectMgr_SelectableObjectSet_HeaderFile + +#include + +#include +#include +#include +#include + +//! The purpose of this class is to organize all selectable objects into +//! data structure, allowing to build BVH tree. For selectable objects +//! binned BVH builder is used with 32 bins and 1 element per leaf. +class SelectMgr_SelectableObjectSet : public BVH_PrimitiveSet +{ +public: + + //! Creates new empty objects set and initializes BVH tree + //! builder to Binned builder with 1 element per list + SelectMgr_SelectableObjectSet(); + + virtual ~SelectMgr_SelectableObjectSet() {}; + + //! Adds new object to the set and marks BVH tree for rebuild + void Append (const Handle(SelectMgr_SelectableObject)& theObject); + + //! Removes object theObject from set and marks BVH tree for rebuild + void Remove (const Handle(SelectMgr_SelectableObject)& theObject); + + //! Returns bounding box of object with index theIndex + virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE; + + //! Returns center of object with index theIndex in the set + //! along the given axis theAxis + virtual Standard_Real Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIndex1 and theIndex2 in the set + virtual void Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) Standard_OVERRIDE; + + //! Returns size of objects set + virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns object from set by theIndex given + const Handle(SelectMgr_SelectableObject)& GetObjectById (const Standard_Integer theIndex) const; + + //! Returns true if this objects set contains theObject given + const Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const; + +private: + + NCollection_Sequence myObjects; + NCollection_Sequence myObjectIdxs; +}; + +#endif // _SelectMgr_SelectableObjectSet_HeaderFile diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx new file mode 100644 index 0000000000..6e5b483576 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx @@ -0,0 +1,312 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +// function : SelectMgr_SelectingVolumeManager +// purpose : Creates instances of all available selecting volume types +//======================================================================= +SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boolean theToAllocateFrustums) +{ + myActiveSelectionType = Unknown; + + if (theToAllocateFrustums) + { + mySelectingVolumes[Frustum] = new SelectMgr_RectangularFrustum(); + mySelectingVolumes[FrustumSet] = new SelectMgr_TriangularFrustumSet(); + } +} + +//======================================================================= +// function : Transform +// purpose : Returns a copy of active frustum transformed according to the matrix given +//======================================================================= +SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (const gp_Trsf& theTrsf) +{ + SelectMgr_SelectingVolumeManager aMgr (Standard_False); + + if (myActiveSelectionType == Unknown) + return aMgr; + + aMgr.myActiveSelectionType = myActiveSelectionType; + + aMgr.mySelectingVolumes[myActiveSelectionType / 2] = mySelectingVolumes[myActiveSelectionType / 2]->Transform (theTrsf); + + return aMgr; +} + +//======================================================================= +// function : GetActiveSelectionType +// purpose : +//======================================================================= +const Standard_Integer SelectMgr_SelectingVolumeManager::GetActiveSelectionType() const +{ + return myActiveSelectionType; +} + +//======================================================================= +// function : SetActiveSelectionType +// purpose : +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetActiveSelectionType (const SelectionType& theType) +{ + myActiveSelectionType = theType; +} + +//======================================================================= +// function : SetCamera +// purpose : Updates camera projection and orientation matrices in all +// selecting volumes +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetCamera (const Handle(Graphic3d_Camera) theCamera) +{ + for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) + { + mySelectingVolumes[anIdx]->SetCamera (theCamera); + } +} + +//======================================================================= +// function : SetCamera +// purpose : Updates camera projection and orientation matrices in all +// selecting volumes +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetCamera (const Graphic3d_Mat4d& theProjection, + const Graphic3d_Mat4d& theOrientation, + const Standard_Boolean theIsOrthographic) +{ + for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) + { + mySelectingVolumes[anIdx]->SetCamera (theProjection, theOrientation, theIsOrthographic); + } +} + +//======================================================================= +// function : SetCamera +// purpose : Updates viewport in all selecting volumes +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight) +{ + for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) + { + mySelectingVolumes[anIdx]->SetViewport (theX, theY, theWidth, theHeight); + } +} + +//======================================================================= +// function : SetWindowSize +// purpose : Updates window size in all selecting volumes +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer theWidth, + const Standard_Integer theHeight) +{ + for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) + { + mySelectingVolumes[anIdx]->SetWindowSize (theWidth, theHeight); + } +} + +//======================================================================= +// function : SetPixelTolerance +// purpose : Updates pixel tolerance in all selecting volumes +//======================================================================= +void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Real theTolerance) +{ + for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx) + { + mySelectingVolumes[anIdx]->SetPixelTolerance (theTolerance); + } +} + +//======================================================================= +// function : BuildSelectingVolume +// purpose : Builds rectangular selecting frustum for point selection +//======================================================================= +void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& thePoint) +{ + if (myActiveSelectionType != Point) + return; + + mySelectingVolumes[Frustum]->Build (thePoint); +} + +//======================================================================= +// function : BuildSelectingVolume +// purpose : Builds rectangular selecting frustum for box selection +//======================================================================= +void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const gp_Pnt2d& theMinPt, + const gp_Pnt2d& theMaxPt) +{ + if (myActiveSelectionType != Box) + return; + + mySelectingVolumes[Frustum]->Build (theMinPt, theMaxPt); +} + +//======================================================================= +// function : BuildSelectingVolume +// purpose : Builds set of triangular selecting frustums for polyline +// selection +//======================================================================= +void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints) +{ + if (myActiveSelectionType != Polyline) + return; + + mySelectingVolumes[FrustumSet]->Build (thePoints); +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and +// given axis-aligned box +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const BVH_Box& theBndBox, + Standard_Real& theDepth) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBndBox, + theDepth); +} + +//======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theMinPt, + const SelectMgr_Vec3& theMaxPt) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theMinPt, theMaxPt); +} + +//======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt, + Standard_Real& theDepth) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt, + theDepth); +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// ordered set of points, representing line segments. The test +// may be considered of interior part or boundary line defined +// by segments depending on given sensitivity type +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Standard_Integer theSensType, + Standard_Real& theDepth) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPts, + (Select3D_TypeOfSensitivity)theSensType, + theDepth); +} + +//======================================================================= +// function : Overlaps +// purpose : Checks if line segment overlaps selecting volume +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + Standard_Real& theDepth) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, thePt2, theDepth); +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// triangle. The test may be considered of interior part or +// boundary line defined by triangle vertices depending on +// given sensitivity type +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + const gp_Pnt& thePt3, + Standard_Integer theSensType, + Standard_Real& theDepth) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt1, + thePt2, + thePt3, + (Select3D_TypeOfSensitivity)theSensType, + theDepth); +} + +//======================================================================= +// function : DistToGeometryCenter +// purpose : Measures distance between 3d projection of user-picked +// screen point and given point theCOG +//======================================================================= +const Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_Pnt& theCOG) +{ + if (myActiveSelectionType == Unknown) + return Standard_False; + + return mySelectingVolumes[myActiveSelectionType / 2]->DistToGeometryCenter (theCOG); +} + +// ======================================================================= +// function : DetectedPoint +// purpose : Calculates the point on a view ray that was detected during +// the run of selection algo by given depth. Is valid for point +// selection only +// ======================================================================= +NCollection_Vec3 SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const +{ + if (myActiveSelectionType != Point) + return NCollection_Vec3 (RealLast()); + + return mySelectingVolumes[Frustum]->DetectedPoint (theDepth); +} + +//======================================================================= +// function : IsClipped +// purpose : Checks if the point of sensitive in which selection was +// detected belongs to the region defined by clipping planes +//======================================================================= +const Standard_Boolean SelectMgr_SelectingVolumeManager::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, + const Standard_Real& theDepth) +{ + if (myActiveSelectionType == Point) + return Standard_False; + + return mySelectingVolumes[Frustum]->IsClipped (thePlanes, theDepth); +} diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx new file mode 100644 index 0000000000..2d0eb27664 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx @@ -0,0 +1,133 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_SelectingVolumeManager_HeaderFile +#define _SelectMgr_SelectingVolumeManager_HeaderFile + +#include + +#include +#include + +#include +#include +#include +#include + +//! This class is used to switch between active selecting volumes depending +//! on selection type chosen by the user +class SelectMgr_SelectingVolumeManager : public SelectBasics_SelectingVolumeManager +{ +public: + + //! Creates instances of all available selecting volume types + Standard_EXPORT SelectMgr_SelectingVolumeManager (Standard_Boolean theToAllocateFrustums = Standard_True); + + Standard_EXPORT virtual ~SelectMgr_SelectingVolumeManager() {}; + + //! Returns a copy of active frustum transformed according to the matrix given + Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Transform (const gp_Trsf& theTrsf); + + Standard_EXPORT virtual const Standard_Integer GetActiveSelectionType() const Standard_OVERRIDE; + + Standard_EXPORT void SetActiveSelectionType (const SelectionType& theType); + + //! Updates camera projection and orientation matrices in all selecting volumes + Standard_EXPORT void SetCamera (const Handle(Graphic3d_Camera) theCamera); + + //! Updates camera projection and orientation matrices in all selecting volumes + Standard_EXPORT void SetCamera (const Graphic3d_Mat4d& theProjection, + const Graphic3d_Mat4d& theOrientation, + const Standard_Boolean theIsOrthographic); + + //! Updates viewport in all selecting volumes + Standard_EXPORT void SetViewport (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theWidth, + const Standard_Real theHeight); + + //! Updates pixel tolerance in all selecting volumes + Standard_EXPORT void SetPixelTolerance (const Standard_Real theTolerance); + + //! Updates window size in all selecting volumes + Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight); + + + //! Builds rectangular selecting frustum for point selection + Standard_EXPORT void BuildSelectingVolume (const gp_Pnt2d& thePoint); + + //! Builds rectangular selecting frustum for box selection + Standard_EXPORT void BuildSelectingVolume (const gp_Pnt2d& theMinPt, + const gp_Pnt2d& theMaxPt); + + //! Builds set of triangular selecting frustums for polyline selection + Standard_EXPORT void BuildSelectingVolume (const TColgp_Array1OfPnt2d& thePoints); + + + //! SAT intersection test between defined volume and given axis-aligned box + Standard_EXPORT virtual const Standard_Boolean Overlaps (const BVH_Box& theBndBox, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box + //! with minimum corner at point theMinPt and maximum at point theMaxPt + Standard_EXPORT virtual const Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPt, + const SelectMgr_Vec3& theMaxPt) Standard_OVERRIDE; + + //! Intersection test between defined volume and given point + Standard_EXPORT virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given ordered set of points, + //! representing line segments. The test may be considered of interior part or + //! boundary line defined by segments depending on given sensitivity type + Standard_EXPORT virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Standard_Integer theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Checks if line segment overlaps selecting frustum + Standard_EXPORT virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given triangle. The test may + //! be considered of interior part or boundary line defined by triangle vertices + //! depending on given sensitivity type + Standard_EXPORT virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + const gp_Pnt& thePt3, + Standard_Integer theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + + //! Measures distance between 3d projection of user-picked + //! screen point and given point theCOG + Standard_EXPORT virtual const Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) Standard_OVERRIDE; + + //! Calculates the point on a view ray that was detected during the run of selection algo by given depth. Is valid for point + //! selection only + Standard_EXPORT virtual NCollection_Vec3 DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE; + + //! Checks if the point of sensitive in which selection was detected belongs + //! to the region defined by clipping planes + Standard_EXPORT virtual const Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, + const Standard_Real& theDepth); + +private: + enum { Frustum, FrustumSet, VolumeTypesNb }; //!< Defines the amount of available selecting volumes + + NCollection_Handle mySelectingVolumes[VolumeTypesNb]; //!< Array of selecting volumes +}; + +#endif diff --git a/src/SelectMgr/SelectMgr_Selection.cdl b/src/SelectMgr/SelectMgr_Selection.cdl deleted file mode 100644 index 59b9c1a3d3..0000000000 --- a/src/SelectMgr/SelectMgr_Selection.cdl +++ /dev/null @@ -1,151 +0,0 @@ --- Created on: 1995-02-06 --- Created by: Mister rmi --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -class Selection from SelectMgr inherits TShared from MMgt - - ---Purpose: Represents the state of a given selection mode for a - -- Selectable Object. Contains all the sensitive entities available for this mode. - -- An interactive object can have an indefinite number of - -- modes of selection, each representing a - -- "decomposition" into sensitive primitives; each - -- primitive has an Owner (SelectMgr_EntityOwner) - -- which allows us to identify the exact entity which has - -- been detected. Each Selection mode is identified by - -- an index. The set of sensitive primitives which - -- correspond to a given mode is stocked in a - -- SelectMgr_Selection object. By Convention, the - -- default selection mode which allows us to grasp the - -- Interactive object in its entirety will be mode 0. - -- AIS_Trihedron : 4 selection modes - -- - mode 0 : selection of a trihedron - -- - mode 1 : selection of the origin of the trihedron - -- - mode 2 : selection of the axes - -- - mode 3 : selection of the planes XOY, YOZ, XOZ - -- when you activate one of modes 1 2 3 4 , you pick AIS objects of type: - -- - AIS_Point - -- - AIS_Axis (and information on the type of axis) - -- - AIS_Plane (and information on the type of plane). - -- AIS_PlaneTrihedron offers 3 selection modes: - -- - mode 0 : selection of the whole trihedron - -- - mode 1 : selection of the origin of the trihedron - -- - mode 2 : selection of the axes - same remarks as for the Trihedron. - -- AIS_Shape : 7 maximum selection modes, depending - -- on the complexity of the shape : - -- - mode 0 : selection of the AIS_Shape - -- - mode 1 : selection of the vertices - -- - mode 2 : selection of the edges - -- - mode 3 : selection of the wires - -- - mode 4 : selection of the faces - -- - mode 5 : selection of the shells - -- - mode 6 : selection of the constituent solids. - -uses - SensitiveEntity from SelectBasics, - ListOfSensitive from SelectBasics, - ListIteratorOfListOfSensitive from SelectBasics, - TypeOfUpdate from SelectMgr - -raises - NullObject - -is - - - Create (IdMode : Integer = 0) returns Selection; - --- Purpose: Constructs a selection object defined by the selection mode IdMode. - -- The default setting 0 is the selection mode for a shape in its entirety. - - Destroy (me : mutable) is static; - ---Level: Public - ---Purpose: - ---Category: Methods to modify the class definition - ---C++: alias ~ - - Add (me : mutable; - aprimitive : SensitiveEntity from SelectBasics) - ---Purpose: Adds the sensitive primitive aprimitive to the list of - -- stored entities in this object. - -- Raises NullObject if the primitive is a null handle. - raises NullObject - is static; - - Clear(me :mutable) is static; - ---Purpose: empties the selection from all the stored entities - - IsEmpty(me) returns Boolean is static; - ---Purpose: returns true if no sensitive entity is stored. - - Mode (me) returns Integer; - ---Purpose: returns the selection mode represented by this selection - ---C++: inline - - - ---Category: get the sensitive entities inside the Selection - - Init(me:mutable) is static; - ---Purpose: Begins an iteration scanning for sensitive primitives. - ---C++: inline - - More(me) returns Boolean is static; - ---Purpose: Continues the iteration scanning for sensitive - -- primitives with the mode defined in this framework. - ---C++: inline - - - Next(me:mutable) is static; - ---Purpose: Returns the next sensitive primitive found in the - -- iteration. This is a scan for entities with the mode - -- defined in this framework. - ---C++: inline - - Sensitive (me) returns any SensitiveEntity from SelectBasics is static; - ---Purpose: Returns any sensitive primitive in this framework. - ---C++: return const& - ---C++: inline - - ---Category: Internal Methods for Management - -- - -- sets and gets the update status of a selection - - - - UpdateStatus(me) returns TypeOfUpdate from SelectMgr; - ---C++: inline - ---Purpose: Returns the flag UpdateFlag. - -- This flage gives the update status of this framework - -- in a ViewerSelector object: - -- - full - -- - partial, or - -- - none. - - - UpdateStatus(me:mutable;UpdateFlag : TypeOfUpdate from SelectMgr); - ---C++: inline - - - - -fields - - myentities : ListOfSensitive from SelectBasics; - myit : ListIteratorOfListOfSensitive from SelectBasics; - myMode : Integer from Standard; - myUpdateStatus : TypeOfUpdate from SelectMgr; - - -end Selection; - - diff --git a/src/SelectMgr/SelectMgr_Selection.cxx b/src/SelectMgr/SelectMgr_Selection.cxx index 187c3879f3..2ca550259e 100644 --- a/src/SelectMgr/SelectMgr_Selection.cxx +++ b/src/SelectMgr/SelectMgr_Selection.cxx @@ -14,65 +14,127 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (SelectMgr_Selection, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_Selection, MMgt_TShared) //================================================== -// Function: Create +// Function: SelectMgr_Selection // Purpose : //================================================== -SelectMgr_Selection -::SelectMgr_Selection (const Standard_Integer IdMode): -myMode(IdMode) +SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx) +: myMode (theModeIdx), + mySelectionState (SelectMgr_SOS_Unknown), + myBVHUpdateStatus (SelectMgr_TBU_None), + mySensFactor (2.0) {} +SelectMgr_Selection::~SelectMgr_Selection() +{ + Destroy(); +} + //================================================== // Function: Destroy // Purpose : //================================================== void SelectMgr_Selection::Destroy() { - for (SelectBasics_ListIteratorOfListOfSensitive anIt(myentities); anIt.More(); anIt.Next()) + for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Size(); ++anEntityIdx) { - anIt.Value()->Set (NULL); + SelectMgr_HSensitiveEntity& anEntity = myEntities.ChangeValue (anEntityIdx); + anEntity->BaseSensitive()->Set (NULL); } + mySensFactor = 2.0; } //================================================== // Function: ADD // Purpose : //================================================== -void SelectMgr_Selection -::Add (const Handle(SelectBasics_SensitiveEntity)& aprimitive) +void SelectMgr_Selection::Add (const Handle(SelectBasics_SensitiveEntity)& theSensitive) { // if input is null: // in debug mode raise exception Standard_NullObject_Raise_if - (aprimitive.IsNull(), "Null sensitive entity is added to the selection"); + (theSensitive.IsNull(), "Null sensitive entity is added to the selection"); + // in release mode do not add - if (!aprimitive.IsNull()) - myentities.Append(aprimitive); + if (!theSensitive.IsNull()) + { + SelectMgr_HSensitiveEntity anEntity = new SelectMgr_SensitiveEntity (theSensitive); + myEntities.Append (anEntity); + if (mySelectionState == SelectMgr_SOS_Activated && + !anEntity->IsActiveForSelection()) + { + anEntity->SetActiveForSelection(); + } + + mySensFactor = Max (mySensFactor, + anEntity->BaseSensitive()->SensitivityFactor()); + } } //================================================== -// Function: Clear +// Function: Clear // Purpose : //================================================== -void SelectMgr_Selection -::Clear () {myentities.Clear();} +void SelectMgr_Selection::Clear() +{ + for (Standard_Integer anIdx = 0; anIdx < myEntities.Size(); ++anIdx) + { + SelectMgr_HSensitiveEntity& anEntity = myEntities.ChangeValue (anIdx); + anEntity->Clear(); + } + + myEntities.Clear(); +} //================================================== // Function: IsEmpty // Purpose : //================================================== -Standard_Boolean SelectMgr_Selection -::IsEmpty() const +Standard_Boolean SelectMgr_Selection::IsEmpty() const { - return myentities.IsEmpty(); + return myEntities.IsEmpty(); } +//================================================== +// function: GetEntityById +// purpose : Returns sensitive entity stored by +// index theIdx in entites vector +//================================================== +SelectMgr_HSensitiveEntity& SelectMgr_Selection::GetEntityById (const Standard_Integer theIdx) +{ + return myEntities.ChangeValue (theIdx); +} +//================================================== +// function: GetSelectionState +// purpose : Returns status of selection +//================================================== +const SelectMgr_StateOfSelection SelectMgr_Selection::GetSelectionState() const +{ + return mySelectionState; +} +//================================================== +// function: SetSelectionState +// purpose : Sets status of selection +//================================================== +void SelectMgr_Selection::SetSelectionState (const SelectMgr_StateOfSelection theState) const +{ + mySelectionState = theState; +} - - +//================================================== +// function: Sensitivity +// purpose : Returns sensitivity of the selection +//================================================== +const Standard_Real SelectMgr_Selection::Sensitivity() const +{ + return mySensFactor; +} diff --git a/src/SelectMgr/SelectMgr_Selection.hxx b/src/SelectMgr/SelectMgr_Selection.hxx new file mode 100644 index 0000000000..cf0b79cfb2 --- /dev/null +++ b/src/SelectMgr/SelectMgr_Selection.hxx @@ -0,0 +1,161 @@ +// Created on: 1995-02-16 +// Created by: Mister rmi +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_Selection_HeaderFile +#define _SelectMgr_Selection_HeaderFile + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +class Standard_NullObject; +class SelectBasics_SensitiveEntity; + +typedef NCollection_Handle SelectMgr_HSensitiveEntity; + +//! Represents the state of a given selection mode for a +//! Selectable Object. Contains all the sensitive entities available for this mode. +//! An interactive object can have an indefinite number of +//! modes of selection, each representing a +//! "decomposition" into sensitive primitives; each +//! primitive has an Owner (SelectMgr_EntityOwner) +//! which allows us to identify the exact entity which has +//! been detected. Each Selection mode is identified by +//! an index. The set of sensitive primitives which +//! correspond to a given mode is stocked in a +//! SelectMgr_Selection object. By Convention, the +//! default selection mode which allows us to grasp the +//! Interactive object in its entirety will be mode 0. +//! AIS_Trihedron : 4 selection modes +//! - mode 0 : selection of a trihedron +//! - mode 1 : selection of the origin of the trihedron +//! - mode 2 : selection of the axes +//! - mode 3 : selection of the planes XOY, YOZ, XOZ +//! when you activate one of modes 1 2 3 4 , you pick AIS objects of type: +//! - AIS_Point +//! - AIS_Axis (and information on the type of axis) +//! - AIS_Plane (and information on the type of plane). +//! AIS_PlaneTrihedron offers 3 selection modes: +//! - mode 0 : selection of the whole trihedron +//! - mode 1 : selection of the origin of the trihedron +//! - mode 2 : selection of the axes - same remarks as for the Trihedron. +//! AIS_Shape : 7 maximum selection modes, depending +//! on the complexity of the shape : +//! - mode 0 : selection of the AIS_Shape +//! - mode 1 : selection of the vertices +//! - mode 2 : selection of the edges +//! - mode 3 : selection of the wires +//! - mode 4 : selection of the faces +//! - mode 5 : selection of the shells +//! - mode 6 : selection of the constituent solids. +class SelectMgr_Selection : public MMgt_TShared +{ + +public: + + //! Constructs a selection object defined by the selection mode IdMode. + //! The default setting 0 is the selection mode for a shape in its entirety. + Standard_EXPORT SelectMgr_Selection (const Standard_Integer theModeIdx = 0); + + ~SelectMgr_Selection(); + + Standard_EXPORT void Destroy(); + + //! Adds the sensitive primitive aprimitive to the list of + //! stored entities in this object. + //! Raises NullObject if the primitive is a null handle. + Standard_EXPORT void Add (const Handle(SelectBasics_SensitiveEntity)& theSensitive); + + //! empties the selection from all the stored entities + Standard_EXPORT void Clear(); + + //! returns true if no sensitive entity is stored. + Standard_EXPORT Standard_Boolean IsEmpty() const; + + //! returns the selection mode represented by this selection + Standard_Integer Mode() const; + + //! Begins an iteration scanning for sensitive primitives. + void Init(); + + //! Continues the iteration scanning for sensitive + //! primitives with the mode defined in this framework. + Standard_Boolean More() const; + + //! Returns the next sensitive primitive found in the + //! iteration. This is a scan for entities with the mode + //! defined in this framework. + void Next(); + + //! Returns any sensitive primitive in this framework. + const SelectMgr_HSensitiveEntity& Sensitive() const; + + //! Returns the flag UpdateFlag. + //! This flage gives the update status of this framework + //! in a ViewerSelector object: + //! - full + //! - partial, or + //! - none. + SelectMgr_TypeOfUpdate UpdateStatus() const; + + void UpdateStatus (const SelectMgr_TypeOfUpdate theStatus); + + void UpdateBVHStatus (const SelectMgr_TypeOfBVHUpdate theStatus); + + SelectMgr_TypeOfBVHUpdate BVHUpdateStatus() const; + + //! Returns status of selection + Standard_EXPORT const SelectMgr_StateOfSelection GetSelectionState() const; + + //! Sets status of selection + Standard_EXPORT void SetSelectionState (const SelectMgr_StateOfSelection theState) const; + + //! Returns sensitivity of the selection + Standard_EXPORT const Standard_Real Sensitivity() const; + + DEFINE_STANDARD_RTTI (SelectMgr_Selection) + +protected: + + //! Returns sensitive entity stored by index theIdx in entites vector + SelectMgr_HSensitiveEntity& GetEntityById (const Standard_Integer theIdx); + +private: + + NCollection_Vector myEntities; + NCollection_Vector::Iterator myEntityIter; + Standard_Integer myMode; + SelectMgr_TypeOfUpdate myUpdateStatus; + mutable SelectMgr_StateOfSelection mySelectionState; + mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus; + Standard_Real mySensFactor; +}; + +DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared) + +#include + +#endif diff --git a/src/SelectMgr/SelectMgr_Selection.lxx b/src/SelectMgr/SelectMgr_Selection.lxx index 112f295f37..60ed4db5af 100644 --- a/src/SelectMgr/SelectMgr_Selection.lxx +++ b/src/SelectMgr/SelectMgr_Selection.lxx @@ -12,22 +12,83 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline Standard_Integer SelectMgr_Selection::Mode() const {return myMode;} +// ======================================================================= +// function : Mode +// purpose : +// ======================================================================= +inline Standard_Integer SelectMgr_Selection::Mode() const +{ + return myMode; +} -inline void SelectMgr_Selection::Init () -{myit.Initialize(myentities);} +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +inline void SelectMgr_Selection::Init() +{ + myEntityIter.Init (myEntities); +} +// ======================================================================= +// function : More +// purpose : +// ======================================================================= inline Standard_Boolean SelectMgr_Selection::More() const -{return myit.More();} +{ + return myEntityIter.More(); +} -inline void SelectMgr_Selection::Next() -{myit.Next();} +// ======================================================================= +// function : Next +// purpose : +// ======================================================================= +inline void SelectMgr_Selection::Next() +{ + myEntityIter.Next(); +} -inline const Handle (SelectBasics_SensitiveEntity)& SelectMgr_Selection::Sensitive () const -{return myit.Value();} +// ======================================================================= +// function : Sensitive +// purpose : +// ======================================================================= +inline const SelectMgr_HSensitiveEntity& SelectMgr_Selection::Sensitive() const +{ + return myEntityIter.Value(); +} -inline void SelectMgr_Selection::UpdateStatus(const SelectMgr_TypeOfUpdate TheStat) -{myUpdateStatus = TheStat;} +// ======================================================================= +// function : UpdateStatus +// purpose : +// ======================================================================= +inline void SelectMgr_Selection::UpdateStatus(const SelectMgr_TypeOfUpdate theStatus) +{ + myUpdateStatus = theStatus; +} +// ======================================================================= +// function : UpdateStatus +// purpose : +// ======================================================================= inline SelectMgr_TypeOfUpdate SelectMgr_Selection::UpdateStatus() const -{return myUpdateStatus;} +{ + return myUpdateStatus; +} + +// ======================================================================= +// function : UpdateBVHStatus +// purpose : +// ======================================================================= +inline void SelectMgr_Selection::UpdateBVHStatus (const SelectMgr_TypeOfBVHUpdate theStatus) +{ + myBVHUpdateStatus = theStatus; +} + +// ======================================================================= +// function : BVHUpdateStatus +// purpose : +// ======================================================================= +inline SelectMgr_TypeOfBVHUpdate SelectMgr_Selection::BVHUpdateStatus() const +{ + return myBVHUpdateStatus; +} diff --git a/src/SelectMgr/SelectMgr_SelectionManager.cdl b/src/SelectMgr/SelectMgr_SelectionManager.cdl index 4e6f32287b..157d671a44 100644 --- a/src/SelectMgr/SelectMgr_SelectionManager.cdl +++ b/src/SelectMgr/SelectMgr_SelectionManager.cdl @@ -22,242 +22,206 @@ class SelectionManager from SelectMgr inherits TShared from MMgt - ---Purpose: A framework to manage selection from the point of - -- view of viewer selectors. These can be added and - -- removed, and selection modes can be activated and - -- deactivated. In addition, objects may be known to all - -- selectors or only to some. + ---Purpose: A framework to manage selection from the point of + -- view of viewer selectors. These can be added and + -- removed, and selection modes can be activated and + -- deactivated. In addition, objects may be known to all + -- selectors or only to some. uses - AsciiString from TCollection, - ViewerSelector from SelectMgr, - SelectableObject from SelectMgr, - CString from Standard, - MapOfTransient from TColStd, - TypeOfUpdate from SelectMgr, + AsciiString from TCollection, + ViewerSelector from SelectMgr, + SelectableObject from SelectMgr, + CString from Standard, + MapOfTransient from TColStd, + TypeOfUpdate from SelectMgr, DataMapOfObjectSelectors from SelectMgr - + is - - Create returns SelectionManager from SelectMgr; - --- Purpose: Constructs an empty selection manager object. + + Create returns SelectionManager from SelectMgr; + --- Purpose: Constructs an empty selection manager object. ---Category: Management of the view selectors - Add (me:mutable ; aSelector :ViewerSelector from SelectMgr)is static; - ---Purpose: Adds the viewer selector aSelector to this framework. + Add (me : mutable; + theSelector : ViewerSelector from SelectMgr) + is static; + ---Purpose: Adds the viewer selector theSelector to the list of known items. - Remove (me:mutable; aSelector :ViewerSelector from SelectMgr) is static; - ---Level: Public - ---Purpose: + Remove (me : mutable; + theSelector : ViewerSelector from SelectMgr) + is static; + ---Purpose: Removes viewer selector theSelector from the list of known items. - Contains (me;aSelector :ViewerSelector from SelectMgr) returns Boolean is static; - ---Purpose: - -- Returns true if this framework contains the viewer selector aSelector. + Contains (me; + theSelector : ViewerSelector from SelectMgr) + returns Boolean + is static; + ---Purpose: Returns true if the manager contains the viewer selector theSelector in a list of known items. - Contains(me;aSelectableObject: SelectableObject from SelectMgr) returns Boolean is static; - ---Purpose: Returns true if this framework contains the - -- selectable object aSelectableObject. - - - ---Category: about Presentable Objects which want to be pickable... - -- Loading Phase!!! No Mode Activation ! - - - Load(me : mutable; - anObject : SelectableObject from SelectMgr ; - aMode : Integer =-1) is static; - ---Purpose: Loads and computes one mode of - -- selection if notequal -1 ; - -- if already has a - -- selection with this mode, it's emptied and the sensitive - -- entities are computed for this mode else one Selection - -- is created with this mode before computing. - - - - Load(me : mutable; - anObject : SelectableObject from SelectMgr ; - aSelector : ViewerSelector from SelectMgr; - aMode : Integer = -1 ) is static; - ---Purpose: Local object available for - -- Only. the sensitive entities for selection - -- of mode are computed if not equal -1. - -- if =-1 oc compute is done + Contains (me; + theObject : SelectableObject from SelectMgr) + returns Boolean + is static; + ---Purpose: Returns true if the manager contains the selectable object theObject. - Remove(me:mutable; anObject:SelectableObject from SelectMgr) is static; - ---Level: Public - ---Purpose: removes the object from All the ViewerSelectors where it was; - - Remove(me:mutable; anObject :SelectableObject from SelectMgr; - aSelector :ViewerSelector from SelectMgr) is static; - ---Level: Public - ---Purpose: removes the object from aSelector; + + + Load (me : mutable; + theObject : SelectableObject from SelectMgr; + theMode : Integer = -1) + is static; + ---Purpose: Loads and computes selection mode theMode (if it is not equal to -1) in global context and adds selectable + -- object to BVH tree. If the object theObject has an already calculated selection with mode theMode and it was removed, + -- the selection will be recalculated. + + Load (me : mutable; + theObject : SelectableObject from SelectMgr; + theSelector : ViewerSelector from SelectMgr; + theMode : Integer = -1) + is static; + ---Purpose: Loads and computes selection mode theMode (if it is not equal to -1) and adds selectable object to BVH tree. + -- Does not perform check of existance of theObject in global context before addition, but adds theSelector to local context. + + + Remove (me : mutable; + theObject : SelectableObject from SelectMgr) + is static; + ---Purpose: Removes selectable object theObject from all viewer selectors it was added to previously, removes it from all contexts + -- and clears all computed selections of theObject. + + + Remove (me : mutable; + theObject : SelectableObject from SelectMgr; + theSelector : ViewerSelector from SelectMgr) + is static; + ---Purpose: Removes theObject from theSelector, does not clear selections and unbind theObject from context maps. + + + + + + Activate (me : mutable; + theObject : SelectableObject from SelectMgr; + theMode : Integer = 0; + theSelector : ViewerSelector from SelectMgr = NULL) + is static; + ---Purpose: Activates the selection mode theMode in the selector theSelector for the selectable object anObject. + -- By default, theMode is equal to 0. If theSelector is set to default (NULL), the selection with the mode theMode + -- will be activated in all the viewers available. + + Deactivate (me : mutable; + theObject : SelectableObject from SelectMgr; + theMode : Integer = -1; + theSelector : ViewerSelector from SelectMgr = NULL); + ---Purpose: Deactivates mode theMode of theObject in theSelector. If theMode value is set to default (-1), all + -- avtive selection modes will be deactivated. Likewise, if theSelector value is set to default (NULL), theMode + -- will be deactivated in all viewer selectors. - - ---Category: Activation/desactivation phase..... - -- Activation of desired selection modes in active views - -- all the combinations activate/desactivate a mode of selection for - -- an object in a view, in all the views, .... - - - - Activate(me : mutable; - anObject : SelectableObject from SelectMgr; - aMode : Integer = 0; - AutomaticProj: Boolean = Standard_True) - is static; - ---Purpose: Activates the selection mode aMode in a selector - -- for the selectable object anObject. - - Activate(me : mutable; - anObject : SelectableObject from SelectMgr; - aMode : Integer; - aSelector : ViewerSelector from SelectMgr; - AutomaticProj : Boolean = Standard_True) is static; - ---Purpose: Activates the selection mode aMode in the selector - -- aSelector for the selectable object anObject. - - Deactivate (me : mutable ; - anObject : SelectableObject from SelectMgr); - ---Purpose: Deactivate all the activated modes in any - -- Selector for - - - Deactivate (me : mutable ; - anObject : SelectableObject from SelectMgr; - aMode : Integer) is static; - ---Level: Public - ---Purpose: Deactivates the Mode in every Selector where - -- it was activated + IsActivated (me; + theObject : SelectableObject from SelectMgr; + theMode : Integer = -1; + theSelector : ViewerSelector from SelectMgr = NULL) + returns Boolean from Standard; + ---Purpose: Returns true if the selection with theMode is active for the selectable object theObject and selector theSelector. + -- If all parameters are set to default values, it returns it there is any active selection in any known viewer selector for + -- object theObject. - Deactivate(me : mutable ; - anObject : SelectableObject from SelectMgr; - aMode : Integer; - aSelector : ViewerSelector from SelectMgr) is static; - --- Purpose: Deactivates the selection mode aMode in the - -- selector aSelector for the selectable object anObject. - Deactivate(me : mutable ; - anObject : SelectableObject from SelectMgr; - aSelector : ViewerSelector from SelectMgr) is static; - ---Purpose: Deactivates all selection modes in the selector - -- aSelector for the selectable object anObject. + + ClearSelectionStructures (me : mutable; + theObj : SelectableObject from SelectMgr; + theMode : Integer from Standard = -1; + theSelector : ViewerSelector from SelectMgr = NULL) + is static; + ---Purpose: Removes sensitive entities from all viewer selectors + -- after method Clear() was called to the selection they belonged to + -- or it was recomputed somehow. + + RestoreSelectionStructures (me : mutable; + theObj : SelectableObject from SelectMgr; + theMode : Integer from Standard = -1; + theSelector : ViewerSelector from SelectMgr = NULL) + is static; + ---Purpose: Re-adds newely calculated sensitive entities of recomputed selection + -- defined by mode theMode to all viewer selectors contained that selection. - Sleep (me:mutable; aSelector :ViewerSelector from SelectMgr) is static; - ---Purpose: Ensures that no object in the selector aSelector will be active. - Sleep(me:mutable; anObject : SelectableObject from SelectMgr); - ---Level: Public - ---Purpose: the objet is temporarily deactivated everywhere it was activated. - Sleep(me:mutable; - anObject : SelectableObject from SelectMgr; - aSelector: ViewerSelector from SelectMgr)is static ; - ---Level: Public - ---Purpose: Different from Deactivate; this method - -- deactivates the activated modes of an object, - -- but just for a time; when the Awake Method is called - -- the sleeping modes are reactivated. - - - Awake (me : mutable; - aSelector : ViewerSelector from SelectMgr; - AutomaticProj : Boolean = Standard_True) is static; - ---Level: Public - ---Purpose: activates all the deactivated objects in a selector. - - - Awake(me : mutable; - anObject : SelectableObject from SelectMgr; - AutomaticProj : Boolean = Standard_True) is static; - - Awake (me : mutable; - anObject : SelectableObject from SelectMgr; - aSelector : ViewerSelector from SelectMgr; - AutomaticProj : Boolean = Standard_True) is static; - ---Level: Public - ---Purpose: activates all the deactivated modes - -- of an object in a selector - - IsActivated(me; - anObject : SelectableObject from SelectMgr) - returns Boolean from Standard; - ---Purpose: Returns true if the selection is active for the selectable object anObject. - - IsActivated(me; - anObject : SelectableObject from SelectMgr; - aMode : Integer from Standard) returns Boolean from Standard; - ---Purpose: Returns true if the selection mode aMode is active for the selectable object anObject. - - IsActivated(me; - anObject : SelectableObject from SelectMgr; - aSelector : ViewerSelector from SelectMgr; - aMode : Integer from Standard) returns Boolean from Standard; - ---Purpose: Returns true if the selection mode aMode is active for the selectable - -- object anObject in the viewer selector aSelector. + RecomputeSelection (me : mutable; + theObject : SelectableObject from SelectMgr; + theIsForce : Boolean from Standard = Standard_False; + theMode : Integer from Standard = -1); + ---Purpose: Recomputes activated selections of theObject for all known viewer selectors according to theMode specified. + -- If theMode is set to default (-1), then all activated selections will be recomputed. If theIsForce is set to true, + -- then selection mode theMode for object theObject will be recomputed regardless of its activation status. - RecomputeSelection(me : mutable; - anIObj : SelectableObject from SelectMgr; - ForceUpdate : Boolean from Standard = Standard_False; - aMode : Integer from Standard = -1); - ---Purpose: computes Selections in if they are - -- activated in at least one Selector. - -- puts a recompute flag in each selection which is not active. - -- if =-1 all the selection modes will have to be - -- recomputed. - -- if = True, all selections are recomputed, - -- even if they are not active. + Update (me : mutable; + theObject : SelectableObject from SelectMgr; + theIsForce : Boolean from Standard = Standard_True) + is static; + ---Purpose: Updates all selections of theObject in all viewer selectors according to its current update status. + -- If theIsForce is set to true, the call is equal to recomputation. + + Update (me : mutable; + theObject : SelectableObject from SelectMgr; + theSelector : ViewerSelector from SelectMgr; + theIsForce : Boolean from Standard = Standard_True) + is static; + ---Purpose: Updates all selections of theObject in specified viewer selector according to its current update status. + -- If theIsForce is set to true, the call is equal to recomputation. - Update(me : mutable; - anObject : SelectableObject from SelectMgr; - ForceUpdate : Boolean from Standard = Standard_True) is static; - ---Level: Public - ---Purpose: updates the selectionModes of - -- According to - -- . the stored type of update in each selection - -- mode, - -- . the activation status of each selection mode - -- if == True Recompute - - Update(me : mutable; - anObject : SelectableObject from SelectMgr; - aSelector : ViewerSelector from SelectMgr; - ForceUpdate : Boolean from Standard = Standard_True) is static; - ---Level: Public - SetUpdateMode(me : mutable; - anObject : SelectableObject from SelectMgr; - aType : TypeOfUpdate from SelectMgr) is static; - - - SetUpdateMode(me :mutable; - anObject : SelectableObject from SelectMgr; - aSelMode : Integer from Standard; - aType : TypeOfUpdate from SelectMgr) is static; - - ---Category: Internal Verification methods ... - - Status (me) returns AsciiString from TCollection is static; + SetUpdateMode (me : mutable; + theObject : SelectableObject from SelectMgr; + theType : TypeOfUpdate from SelectMgr) + is static; + ---Purpose: Sets type of update of all selections of theObject to the given theType. + + + SetUpdateMode (me : mutable; + theObject : SelectableObject from SelectMgr; + theMode : Integer from Standard; + theType : TypeOfUpdate from SelectMgr) + is static; + ---Purpose: Sets type of update of selection with theMode of theObject to the given theType. + + + + + + loadMode (me : mutable; + theObject : SelectableObject from SelectMgr; + theMode : Integer; + theSelector : ViewerSelector from SelectMgr = NULL) + is static private; + ---Purpose: Loads and creates selection structures for object theObject with mode theMode in specified + -- viewer selector theSelector. If theSelector is set to default value (NULL), the selection mode + -- created will be added to all known viewer selectors. + + rebuildSelectionStructures (me : mutable; + theSelector : ViewerSelector from SelectMgr = NULL) + is static private; + ---Purpose: Internal function that marks 1st level BVH of the object theObj as + -- outdated. + - Status (me; anObject : SelectableObject from SelectMgr) - returns AsciiString from TCollection is static; - LoadMode(me:mutable;anObject: SelectableObject from SelectMgr;aMode:Integer) is static private; fields @@ -267,9 +231,9 @@ fields -- mylocal : objects with the selectors where they are selectable - myselectors : MapOfTransient from TColStd; - myglobal : MapOfTransient from TColStd; - mylocal : DataMapOfObjectSelectors from SelectMgr; + mySelectors : MapOfTransient from TColStd; + myGlobal : MapOfTransient from TColStd; + myLocal : DataMapOfObjectSelectors from SelectMgr; end SelectionManager; diff --git a/src/SelectMgr/SelectMgr_SelectionManager.cxx b/src/SelectMgr/SelectMgr_SelectionManager.cxx index 73506ee853..5e8513baec 100644 --- a/src/SelectMgr/SelectMgr_SelectionManager.cxx +++ b/src/SelectMgr/SelectMgr_SelectionManager.cxx @@ -26,618 +26,693 @@ #include #include - -static Standard_Boolean SelectDebugModeOnSM() +static Standard_Integer FindIndex (const SelectMgr_SequenceOfSelector& theSelectorsSeq, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - static Standard_Integer isDebugMode( -1 ); - if ( isDebugMode < 0 ) { - isDebugMode = 1; - OSD_Environment selectdb("SELECTIONDEBUG"); - if ( selectdb.Value().IsEmpty() ) - isDebugMode = 0; - } - return ( isDebugMode != 0 ); + Standard_Integer aFoundIdx = 0; + + for (Standard_Integer anIdx = 1; anIdx <= theSelectorsSeq.Length() && aFoundIdx==0; anIdx++) + { + if (theSelector == theSelectorsSeq.Value (anIdx)) + aFoundIdx = anIdx; + } + + return aFoundIdx; } -static Standard_Integer SMSearch(const SelectMgr_SequenceOfSelector& seq, - const Handle(SelectMgr_ViewerSelector)& theSel) -{ - Standard_Integer ifound=0; - for (Standard_Integer i=1;i<=seq.Length()&& ifound==0;i++) - {if(theSel==seq.Value(i)) ifound=i;} - return ifound; - -} - //================================================== // Function: Create // Purpose : //================================================== - -SelectMgr_SelectionManager::SelectMgr_SelectionManager() -{} - +SelectMgr_SelectionManager::SelectMgr_SelectionManager() {} //================================================== // Function: Add // Purpose : //================================================== -void SelectMgr_SelectionManager:: -Add (const Handle(SelectMgr_ViewerSelector)& aViewSel) +void SelectMgr_SelectionManager::Add (const Handle(SelectMgr_ViewerSelector)& theSelector) { - myselectors.Add(aViewSel); + mySelectors.Add (theSelector); } - - //================================================== // Function: Remove // Purpose : //================================================== -void SelectMgr_SelectionManager:: -Remove (const Handle(SelectMgr_ViewerSelector)& aViewSel) +void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_ViewerSelector)& theSelector) { - SelectMgr_DataMapIteratorOfDataMapOfObjectSelectors It(mylocal); - for(;It.More();It.Next()) + for (SelectMgr_DataMapIteratorOfDataMapOfObjectSelectors aSelIter (myLocal); aSelIter.More(); aSelIter.Next()) { - SelectMgr_SequenceOfSelector& theviews =mylocal.ChangeFind(It.Key()); - Standard_Integer rank = SMSearch(theviews,aViewSel); - if(rank!=0 && rank<=theviews.Length()) theviews.Remove(rank); + SelectMgr_SequenceOfSelector& theSelectors = myLocal.ChangeFind (aSelIter.Key()); + Standard_Integer aRank = FindIndex (theSelectors, theSelector); + if (aRank != 0 && aRank <= theSelectors.Length()) + theSelectors.Remove (aRank); } - if(myselectors.Contains(aViewSel)) myselectors.Remove(aViewSel); + + if (mySelectors.Contains (theSelector)) + mySelectors.Remove (theSelector); } //================================================== // Function: Contains // Purpose : //================================================== -Standard_Boolean SelectMgr_SelectionManager:: -Contains (const Handle(SelectMgr_ViewerSelector)& aViewSel) const -{return myselectors.Contains(aViewSel);} +Standard_Boolean SelectMgr_SelectionManager::Contains (const Handle(SelectMgr_ViewerSelector)& theSelector) const +{ + return mySelectors.Contains (theSelector); +} //================================================== // Function: Contains // Purpose : //================================================== -Standard_Boolean SelectMgr_SelectionManager:: -Contains (const Handle(SelectMgr_SelectableObject)& aSelObj) const -{if (myglobal.Contains(aSelObj)) return Standard_True; -if (mylocal.IsBound(aSelObj)) return Standard_True; -return Standard_False; +Standard_Boolean SelectMgr_SelectionManager::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const +{ + if (myGlobal.Contains (theObject)) + return Standard_True; + + if (myLocal.IsBound (theObject)) + return Standard_True; + + return Standard_False; } - - //================================================== // Function: Load // Purpose : //================================================== - -void SelectMgr_SelectionManager:: -Load (const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer amode) +void SelectMgr_SelectionManager::Load (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode) { - if(!myglobal.Contains(anObject)) - myglobal.Add(anObject); - if(amode!=-1) - LoadMode (anObject,amode); -} + if (myGlobal.Contains(theObject)) + return; - -//================================================== -// Function: Load -// Purpose : -//================================================== -void SelectMgr_SelectionManager:: -Load (const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aview, - const Standard_Integer amode) -{ - if(!myselectors.Contains(aview)) myselectors.Add(aview); - if(amode!=-1) - LoadMode (anObject,amode); - - - if (mylocal.IsBound(anObject)){ - SelectMgr_SequenceOfSelector& theviews = mylocal.ChangeFind(anObject); - if (SMSearch(theviews,aview)==0) theviews.Append(aview); + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + Load (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode); } - else { - if(!myglobal.Contains(anObject)){ - SelectMgr_SequenceOfSelector newviews; - newviews.Append(aview); - mylocal.Bind(anObject,newviews); - } - } -} + if (!theObject->HasOwnPresentations()) + return; -//================================================== -// Function: Remove -// Purpose : -//================================================== - -void SelectMgr_SelectionManager:: -Remove(const Handle(SelectMgr_SelectableObject)& anObject) -{ - - if(myglobal.Contains(anObject)) { - TColStd_MapIteratorOfMapOfTransient It(myselectors); - for(;It.More();It.Next()) + myGlobal.Add(theObject); + for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next()) + { + Handle(SelectMgr_ViewerSelector) aSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + if (!aSelector->Contains (theObject) && theObject->HasOwnPresentations()) { - Handle(SelectMgr_ViewerSelector) curview = - Handle(SelectMgr_ViewerSelector)::DownCast(It.Key()); - if(curview->Contains(anObject)){ - for(anObject->Init();anObject->More();anObject->Next()) - { - curview->Remove(anObject->CurrentSelection()); - } - - } + aSelector->AddSelectableObject (theObject); } - myglobal.Remove(anObject); + } + if (theMode != -1) + loadMode (theObject, theMode); +} + + +//================================================== +// Function: Load +// Purpose : +//================================================== +void SelectMgr_SelectionManager::Load (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_ViewerSelector)& theSelector, + const Standard_Integer theMode) +{ + if (!mySelectors.Contains (theSelector)) + { + mySelectors.Add (theSelector); } - else if(mylocal.IsBound(anObject)) { - SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject); - for (Standard_Integer i=1;i<=seq.Length();i++) { - Handle(SelectMgr_ViewerSelector) curview = - Handle(SelectMgr_ViewerSelector)::DownCast(seq(i)); - if(curview->Contains(anObject)){ - for(anObject->Init();anObject->More();anObject->Next()) + if (theMode != -1) + loadMode (theObject, theMode, theSelector); + + if (theObject->HasOwnPresentations()) + theSelector->AddSelectableObject (theObject); + + if (myLocal.IsBound (theObject)) + { + SelectMgr_SequenceOfSelector& aSelectors = myLocal.ChangeFind (theObject); + if (FindIndex (aSelectors, theSelector) == 0) + { + aSelectors.Append (theSelector); + } + } + else + { + if (!myGlobal.Contains (theObject)) + { + if (theObject->HasOwnPresentations()) + { + SelectMgr_SequenceOfSelector aSelectors; + aSelectors.Append (theSelector); + myLocal.Bind (theObject, aSelectors); + } + else + { + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) { - curview->Remove(anObject->CurrentSelection()); + Load (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theSelector, theMode); } } - } - mylocal.UnBind(anObject); } } + +//================================================== +// Function: Remove +// Purpose : +//================================================== +void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject) +{ + if (myGlobal.Contains (theObject)) + { + for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next()) + { + Handle(SelectMgr_ViewerSelector) aCurSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + + if (!aCurSelector->Contains (theObject)) + continue; + + for (theObject->Init(); theObject->More(); theObject->Next()) + { + aCurSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection()); + theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove); + } + aCurSelector->RemoveSelectableObject (theObject); + } + + myGlobal.Remove (theObject); + } + else if (myLocal.IsBound (theObject)) + { + SelectMgr_SequenceOfSelector& aSelectors = myLocal.ChangeFind (theObject); + for (Standard_Integer aSelectorsIdx = 1; aSelectorsIdx <= aSelectors.Length(); aSelectorsIdx++) + { + Handle(SelectMgr_ViewerSelector) aCurSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (aSelectors (aSelectorsIdx)); + if (!aCurSelector->Contains (theObject)) + continue; + + for (theObject->Init(); theObject->More(); theObject->Next()) + { + aCurSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection()); + theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove); + } + aCurSelector->RemoveSelectableObject (theObject); + } + + myLocal.UnBind (theObject); + } + else if (!theObject->HasOwnPresentations()) + { + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + Remove (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value())); + } + } + + theObject->ClearSelections(); +} + //================================================== // Function: Remove // Purpose : //================================================== - -void SelectMgr_SelectionManager:: -Remove(const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aVS) +void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(aVS->Contains(anObject)) { - for(anObject->Init();anObject->More();anObject->Next()){ - aVS->Remove(anObject->CurrentSelection()); - } + if (!theSelector->Contains (theObject)) + return; - - if(mylocal.IsBound(anObject)) { - SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject); - Standard_Boolean NotFound (Standard_True); - for (Standard_Integer i=1;i<=seq.Length()&&NotFound;i++) { - if(seq(i)== aVS){ - seq.Remove(i); - NotFound =Standard_False; - } - } - if(seq.IsEmpty()) - mylocal.UnBind(anObject); - } - } -} - -//================================================== -// Function: Activate -// Purpose : -//================================================== - -void SelectMgr_SelectionManager:: -Activate(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer aMode, - const Standard_Boolean AutomaticProj) -{ - if(aMode==-1) return; - // Standard_Boolean global = Standard_False; - if(!anObject->HasSelection(aMode)) LoadMode(anObject,aMode); - - - if(myglobal.Contains(anObject)) { - TColStd_MapIteratorOfMapOfTransient It(myselectors); - - for(;It.More();It.Next()){ - Handle(SelectMgr_ViewerSelector) curview = - Handle(SelectMgr_ViewerSelector)::DownCast(It.Key()); - Activate(anObject,aMode,curview,AutomaticProj); - } + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + Remove (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theSelector); } - else if(mylocal.IsBound(anObject)) { - SelectMgr_SequenceOfSelector& seq = mylocal.ChangeFind (anObject); - for (Standard_Integer i=1;i<=seq.Length();i++) { - Handle(SelectMgr_ViewerSelector) curview = - Handle(SelectMgr_ViewerSelector)::DownCast(seq(i)); - // ATTENTION : si la selection est a remettre a jour, on le fait la .... - const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode); + if (!theObject->HasOwnPresentations()) + return; - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(aMode); // pas de break expres... - case SelectMgr_TOU_Partial: - { - if(anObject->HasTransformation()) - anObject->UpdateTransformations(Sel); - Sel->UpdateStatus(SelectMgr_TOU_None); - break; - } - default: + for (theObject->Init(); theObject->More(); theObject->Next()) + { + theSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection()); + theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove); + } + + theSelector->RemoveSelectableObject (theObject); + + if (myLocal.IsBound (theObject)) + { + SelectMgr_SequenceOfSelector& aSelectors = myLocal.ChangeFind (theObject); + for (Standard_Integer aSelectorIdx = 1; aSelectorIdx <= aSelectors.Length(); aSelectorIdx++) + { + if (aSelectors (aSelectorIdx) == theSelector) + { + aSelectors.Remove (aSelectorIdx); break; } + } + theSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection()); + theSelector->RemoveSelectableObject (theObject); + theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove); - curview->Activate(Sel,AutomaticProj); + if (aSelectors.IsEmpty()) + { + myLocal.UnBind (theObject); } } } - //================================================== // Function: Activate // Purpose : //================================================== - -void SelectMgr_SelectionManager:: -Activate(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer aMode, - const Handle(SelectMgr_ViewerSelector)& aViewSel, - const Standard_Boolean AutomaticProj) +void SelectMgr_SelectionManager::Activate (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(aMode==-1) return; + if (theMode == -1) + return; - if(!myselectors.Contains(aViewSel)) return; + if (!theSelector.IsNull() && !mySelectors.Contains (theSelector)) + return; - if (!anObject->HasSelection(aMode)) LoadMode(anObject,aMode); - - const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode); - - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(aMode); - case SelectMgr_TOU_Partial: + if (!theObject->HasOwnPresentations()) + { + for (PrsMgr_ListOfPresentableObjectsIter anChildIter (theObject->Children()); anChildIter.More(); anChildIter.Next()) { - if(anObject->HasTransformation()) - anObject->UpdateTransformations(Sel); - break; + Activate (Handle(SelectMgr_SelectableObject)::DownCast (anChildIter.Value()), theMode, theSelector); } + + return; + } + + Standard_Boolean isComputed = Standard_False; + if (theObject->HasSelection (theMode)) + { + isComputed = theObject->Selection (theMode)->IsEmpty() ? 0 : 1; + } + + if (!isComputed) + loadMode (theObject, theMode); + + if (theSelector.IsNull()) + { + if (myGlobal.Contains (theObject)) + { + for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next()) + { + Handle(SelectMgr_ViewerSelector) aCurSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + Activate (theObject, theMode, aCurSelector); + } + } + else if (myLocal.IsBound (theObject)) + { + SelectMgr_SequenceOfSelector& theSelectors = myLocal.ChangeFind (theObject); + for (Standard_Integer aSelectorIdx = 1; aSelectorIdx <= theSelectors.Length(); aSelectorIdx++) + { + Handle(SelectMgr_ViewerSelector) aCurSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (theSelectors (aSelectorIdx)); + Activate (theObject, theMode, aCurSelector); + } + } + } + + const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode); + + switch (aSelection->UpdateStatus()) + { + case SelectMgr_TOU_Full: + if (theObject->HasSelection (theMode)) + theSelector->RemoveSelectionOfObject (theObject, aSelection); + theObject->RecomputePrimitives (theMode); + case SelectMgr_TOU_Partial: + if(theObject->HasTransformation()) + theObject->UpdateTransformations (aSelection); + theSelector->RebuildObjectsTree(); + break; default: break; } - Sel->UpdateStatus(SelectMgr_TOU_None); + aSelection->UpdateStatus(SelectMgr_TOU_None); - if (myglobal.Contains(anObject)) - aViewSel->Activate (anObject->Selection(aMode)); - - else { - if (mylocal.IsBound(anObject)) { - if (SMSearch(mylocal.Find(anObject),aViewSel)==0) - (mylocal.ChangeFind (anObject)).Append(aViewSel); - aViewSel->Activate (anObject->Selection(aMode),AutomaticProj); - } - } -} - -//================================================== -// Function: Deactivate -// Purpose : -//================================================== - -void SelectMgr_SelectionManager:: -Deactivate(const Handle(SelectMgr_SelectableObject)& anObject) -{ - Standard_Boolean global = Standard_False; - if(myglobal.Contains(anObject)) global = Standard_True; - TColStd_MapIteratorOfMapOfTransient It(myselectors); - Handle(SelectMgr_ViewerSelector) curview; - for(;It.More();It.Next()){ - curview = Handle(SelectMgr_ViewerSelector)::DownCast(It.Key()); - if (global || mylocal.IsBound (anObject)) { - for (anObject->Init();anObject->More();anObject->Next()) - {curview->Deactivate(anObject->CurrentSelection());} - - } - - } -} - -//================================================== -// Function: Deactivate -// Purpose : -//================================================== - -void SelectMgr_SelectionManager:: -Deactivate(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer amode) - -{ - Standard_Boolean global = Standard_False; - if(myglobal.Contains(anObject)) global = Standard_True; - TColStd_MapIteratorOfMapOfTransient It(myselectors); - Handle(SelectMgr_ViewerSelector) curview; - for(;It.More();It.Next()){ - curview = Handle(SelectMgr_ViewerSelector)::DownCast(It.Key()); - if (global || mylocal.IsBound(anObject)) { - if(anObject->HasSelection(amode)) - curview->Deactivate(anObject->Selection(amode)); - - } - } -} - -//================================================== -// Function: Deactivate -// Purpose : -//================================================== - -void SelectMgr_SelectionManager:: -Deactivate(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer aMode, - const Handle(SelectMgr_ViewerSelector)& aViewSel) -{ - if(myselectors.Contains(aViewSel)) + switch (aSelection->BVHUpdateStatus()) { - if(myglobal.Contains(anObject)|| mylocal.IsBound(anObject)) - if(anObject->HasSelection(aMode)) - aViewSel->Deactivate (anObject->Selection(aMode)); - } + case SelectMgr_TBU_Add: + case SelectMgr_TBU_Renew: + theSelector->AddSelectionToObject (theObject, aSelection); + break; + case SelectMgr_TBU_Remove: + if (aSelection->GetSelectionState() == SelectMgr_SOS_Deactivated) + theSelector->AddSelectionToObject (theObject, aSelection); + break; + default: + break; + } + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + if (myGlobal.Contains (theObject)) + { + if (theMode != 0 && theSelector->IsActive (theObject, 0)) + { + theSelector->Deactivate (theObject->Selection (0)); + } + theSelector->Activate (theObject->Selection (theMode)); + } + else + { + if (myLocal.IsBound (theObject)) + { + if (FindIndex (myLocal.Find (theObject), theSelector) == 0) + (myLocal.ChangeFind (theObject)).Append (theSelector); + theSelector->Activate (theObject->Selection (theMode)); + } + } } + //================================================== // Function: Deactivate // Purpose : //================================================== - -void SelectMgr_SelectionManager:: -Deactivate(const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aViewSel) - +void SelectMgr_SelectionManager::Deactivate (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(myselectors.Contains(aViewSel)) + + if (!theObject->HasOwnPresentations()) { - if(myglobal.Contains(anObject)|| mylocal.IsBound(anObject)) { - for (anObject->Init();anObject->More();anObject->Next()) - {aViewSel->Deactivate(anObject->CurrentSelection());}} + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + Deactivate (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode, theSelector); + } - } - -} - - -//================================================== -// Function: Sleep -// Purpose : -//================================================== -void SelectMgr_SelectionManager:: -Sleep (const Handle(SelectMgr_ViewerSelector)& aViewSel) -{ - if (myselectors.Contains(aViewSel)) - aViewSel->Sleep(); -} - -void SelectMgr_SelectionManager:: -Sleep (const Handle(SelectMgr_SelectableObject)& anObject) -{ - - if(myglobal.Contains(anObject)){ - for( TColStd_MapIteratorOfMapOfTransient It(myselectors); - It.More();It.Next()) - Handle(SelectMgr_ViewerSelector)::DownCast(It.Key())->Sleep(anObject); - } - else if(mylocal.IsBound(anObject)){ - const SelectMgr_SequenceOfSelector & VSeq = mylocal(anObject); - for (Standard_Integer I=1;I<=VSeq.Length();I++) - VSeq(I)->Sleep(anObject); + return; } + Standard_Boolean isInGlobal = myGlobal.Contains (theObject); + Standard_Boolean hasSelection = theMode == -1 ? Standard_True : theObject->HasSelection (theMode); -} - -//======================================================================= -//function : Sleep -//purpose : -//======================================================================= -void SelectMgr_SelectionManager:: -Sleep(const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aViewSel) -{ - if(!myselectors.Contains(aViewSel)) return; - - if(!myglobal.Contains(anObject)){ - if(!mylocal.IsBound(anObject)) - return; - if(SMSearch(mylocal(anObject),aViewSel)==0) - return; + if (theSelector.IsNull()) + { + Handle(SelectMgr_ViewerSelector) aSelector; + for (TColStd_MapIteratorOfMapOfTransient aSelectorIter (mySelectors); aSelectorIter.More(); aSelectorIter.Next()) + { + aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorIter.Key()); + if (isInGlobal || myLocal.IsBound (theObject)) + { + if (theMode == -1) + { + for (theObject->Init(); theObject->More(); theObject->Next()) + { + aSelector->Deactivate (theObject->CurrentSelection()); + } + } + else + { + if (hasSelection) + aSelector->Deactivate (theObject->Selection (theMode)); + } + } + } } - aViewSel->Sleep(anObject); -} - - - -//================================================== -// Function: Awake -// Purpose : -//================================================== -void SelectMgr_SelectionManager:: -Awake (const Handle(SelectMgr_ViewerSelector)& aViewSel, - const Standard_Boolean AutomaticProj) -{ - if (myselectors.Contains(aViewSel)) - aViewSel->Awake(AutomaticProj); -} - - -//======================================================================= -//function : Awake -//purpose : -//======================================================================= -void SelectMgr_SelectionManager::Awake (const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Boolean AutomaticProj) -{ - if(myglobal.Contains(anObject)){ - for( TColStd_MapIteratorOfMapOfTransient It(myselectors); - It.More();It.Next()) - Handle(SelectMgr_ViewerSelector)::DownCast( It.Key())->Awake(anObject,AutomaticProj); - } - else if(mylocal.IsBound(anObject)){ - const SelectMgr_SequenceOfSelector & VSeq = mylocal(anObject); - for (Standard_Integer I=1;I<=VSeq.Length();I++) - VSeq(I)->Awake(anObject,AutomaticProj); + else + { + if (theMode == -1) + { + for (theObject->Init(); theObject->More(); theObject->Next()) + { + theSelector->Deactivate (theObject->CurrentSelection()); + } + } + else + if (hasSelection) + theSelector->Deactivate (theObject->Selection (theMode)); } } -//======================================================================= -//function : Awake -//purpose : -//======================================================================= -void SelectMgr_SelectionManager::Awake (const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aViewSel, - const Standard_Boolean AutomaticProj) -{ - if(!myselectors.Contains(aViewSel)) return; - - if(!myglobal.Contains(anObject)){ - if(!mylocal.IsBound(anObject)) - return; - if(SMSearch(mylocal(anObject),aViewSel)==0) - return; - } - aViewSel->Awake(anObject,AutomaticProj); - -} - - //======================================================================= //function : IsActivated -//purpose : +//purpose : //======================================================================= -Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject) const +Standard_Boolean SelectMgr_SelectionManager::IsActivated (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) const { - for(anObject->Init();anObject->More();anObject->Next()){ - if(IsActivated(anObject,anObject->CurrentSelection()->Mode())) - return Standard_True; + if (!theObject->HasOwnPresentations()) + { + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + if (IsActivated (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode, theSelector)) + return Standard_True; + } + + return Standard_False; } + + if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject))) + return Standard_False; + + if (theMode == -1 && theSelector.IsNull()) + { + for (theObject->Init(); theObject->More(); theObject->Next()) + { + if (IsActivated (theObject, theObject->CurrentSelection()->Mode())) + return Standard_True; + } + + return Standard_False; + } + + if (!theObject->HasSelection (theMode)) + return Standard_False; + + const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode); + if (theSelector.IsNull()) + { + for (TColStd_MapIteratorOfMapOfTransient aSelectorIter (mySelectors); aSelectorIter.More(); aSelectorIter.Next()) + { + const Handle(SelectMgr_ViewerSelector)& aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorIter.Key()); + if (aSelector->Status (aSelection) == SelectMgr_SOS_Activated) + return Standard_True; + } + } + else + { + return theSelector->Status (aSelection) == SelectMgr_SOS_Activated; + } + return Standard_False; } + //======================================================================= -//function : IsActivated -//purpose : +//function : ClearSelectionStructures +//purpose : Removes sensitive entities from all viewer selectors +// after method Clear() was called to the selection they belonged to +// or it was recomputed somehow //======================================================================= -Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer aMode) const +void SelectMgr_SelectionManager::ClearSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(!anObject->HasSelection(aMode)) return Standard_False; - if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))) - return Standard_False; - - Handle(Standard_Transient) Tr; - const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode); - for(TColStd_MapIteratorOfMapOfTransient It(myselectors);It.More();It.Next()){ - Tr = It.Key(); - Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr); - if(VS->Status(Sel)==SelectMgr_SOS_Activated) - return Standard_True; + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + ClearSelectionStructures (theObj, theMode, theSelector); } - return Standard_False; + if (!theObj->HasOwnPresentations()) + return; + + if (theSelector == NULL) + { + if (!(myGlobal.Contains (theObj) || myLocal.IsBound(theObj))) + return; + + TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); + Handle(SelectMgr_ViewerSelector) aSelector; + for( ; aSelectorsIter.More(); aSelectorsIter.Next()) + { + aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + ClearSelectionStructures (theObj, theMode, aSelector); + } + } + else + { + if (!(myGlobal.Contains (theObj) || myLocal.IsBound (theObj))) + return; + + if (theMode != -1) + { + if (theObj->HasSelection (theMode)) + { + const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode); + if (theObj->HasSelection (theMode)) + { + theSelector->RemoveSelectionOfObject (theObj, aSelection); + aSelection->UpdateBVHStatus (SelectMgr_TBU_Add); + } + } + } + else + { + for (theObj->Init(); theObj->More(); theObj->Next()) + { + const Handle(SelectMgr_Selection)& aSelection = theObj->CurrentSelection(); + theSelector->RemoveSelectionOfObject (theObj, aSelection); + aSelection->UpdateBVHStatus (SelectMgr_TBU_Add); + } + } + theSelector->RebuildObjectsTree(); + } } //======================================================================= -//function : IsActivated -//purpose : +//function : RestoreSelectionStructuress +//purpose : Re-adds newely calculated sensitive entities of recomputed selection +// defined by mode theMode to all viewer selectors contained that selection. //======================================================================= -Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& VS, - const Standard_Integer aMode) const +void SelectMgr_SelectionManager::RestoreSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(!anObject->HasSelection(aMode)) - return Standard_False; - if(!myselectors.Contains(VS)) - return Standard_False; - if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))) - return Standard_False; - const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode); - return (VS->Status(Sel)==SelectMgr_SOS_Activated); + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + RestoreSelectionStructures (theObj, theMode, theSelector); + } + + if (!theObj->HasOwnPresentations()) + return; + + if (theSelector == NULL) + { + if (!(myGlobal.Contains (theObj) || myLocal.IsBound(theObj))) + return; + + TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); + Handle(SelectMgr_ViewerSelector) aSelector; + for( ; aSelectorsIter.More(); aSelectorsIter.Next()) + { + aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + RestoreSelectionStructures (theObj, theMode, aSelector); + } + } + else + { + if (!(myGlobal.Contains (theObj) || myLocal.IsBound (theObj))) + return; + + if (theMode != -1) + { + if (theObj->HasSelection (theMode)) + { + const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode); + if (theObj->HasSelection (theMode)) + { + theSelector->AddSelectionToObject (theObj, aSelection); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + } + } + } + else + { + for (theObj->Init(); theObj->More(); theObj->Next()) + { + const Handle(SelectMgr_Selection)& aSelection = theObj->CurrentSelection(); + theSelector->AddSelectionToObject (theObj, aSelection); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + } + } + theSelector->RebuildObjectsTree(); + } +} + +//======================================================================= +//function : rebuildSelectionStructures +//purpose : Internal function that marks 1st level BVH of object theObj +// as outdated +//======================================================================= +void SelectMgr_SelectionManager::rebuildSelectionStructures (const Handle(SelectMgr_ViewerSelector)& theSelector) +{ + if (theSelector == NULL) + { + Handle(SelectMgr_ViewerSelector) aSelector; + for(TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next()) + { + aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key()); + rebuildSelectionStructures (aSelector); + } + } + else + { + theSelector->RebuildObjectsTree(); + } } //================================================== // Function: Update // Purpose : //================================================== -void SelectMgr_SelectionManager:: -RecomputeSelection (const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Boolean ForceUpdate, - const Standard_Integer aMode) +void SelectMgr_SelectionManager::RecomputeSelection (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Boolean theIsForce, + const Standard_Integer theMode) { - if( SelectDebugModeOnSM() ) cout<<"===>SelectMgr_SelectionManager::Update"<UpdateSelection(); - anObject->UpdateTransformation(); + if (theIsForce) + { + if (theMode == -1) + { + ClearSelectionStructures (theObject); + theObject->RecomputePrimitives(); + theObject->UpdateTransformation(); + RestoreSelectionStructures (theObject); } - else if(anObject->HasSelection(aMode)){ - anObject->UpdateSelection(aMode); - anObject->UpdateTransformation(); + else if (theObject->HasSelection (theMode)) + { + ClearSelectionStructures (theObject, theMode); + theObject->RecomputePrimitives (theMode); + theObject->UpdateTransformation(); + RestoreSelectionStructures (theObject, theMode); } return; } - // objet is not known to SMgr. - if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))){ - if( SelectDebugModeOnSM() ) {cout<<"\t Object not loaded in the SelectionManager"<Init();anObject->More();anObject->Next()){ - if( SelectDebugModeOnSM() ) cout<<"\t\t Mode "<CurrentSelection()->Mode()<<" "; - anObject->CurrentSelection()->UpdateStatus(SelectMgr_TOU_Full); - } - if( SelectDebugModeOnSM() ) - cout << endl; - } - else if (anObject->HasSelection(aMode)) - anObject->Selection(aMode)->UpdateStatus(SelectMgr_TOU_Full); + + for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next()) + { + RecomputeSelection (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theIsForce, theMode); } - // recalculate whatever is required - // and set flag on top... - else{ - TColStd_MapIteratorOfMapOfTransient It; - Handle(Standard_Transient) Tr; - Standard_Boolean Found; - // object selections are parsed + if (!theObject->HasOwnPresentations()) + return; - for(anObject->Init();anObject->More();anObject->Next()){ - const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection(); - Sel->UpdateStatus(SelectMgr_TOU_Full); - Standard_Integer curmode = Sel->Mode(); - Found = Standard_False; + if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject))) + return; - // parsing of selections ... - for(It.Initialize(myselectors);It.More();It.Next()){ - Tr = It.Key(); - Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr); - if(VS->Status(Sel)==SelectMgr_SOS_Activated){ - Found = Standard_True; - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(curmode); // no break on purpose... - case SelectMgr_TOU_Partial: - anObject->UpdateTransformations(Sel); - break; - default: - break; - } - if(Found){ - VS->Convert(Sel); - Sel->UpdateStatus(SelectMgr_TOU_None); - } + for(theObject->Init(); theObject->More(); theObject->Next()) + { + const Handle(SelectMgr_Selection)& aSelection = theObject->CurrentSelection(); + aSelection->UpdateStatus (SelectMgr_TOU_Full); + Standard_Integer aSelMode = aSelection->Mode(); + + for (TColStd_MapIteratorOfMapOfTransient aSelectorIter (mySelectors); aSelectorIter.More(); aSelectorIter.Next()) + { + const Handle(SelectMgr_ViewerSelector)& aCurSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorIter.Key()); + if (aCurSelector->Status (aSelection) == SelectMgr_SOS_Activated) + { + switch (aSelection->UpdateStatus()) + { + case SelectMgr_TOU_Full: + ClearSelectionStructures (theObject, aSelMode, aCurSelector); + theObject->RecomputePrimitives(aSelMode); + RestoreSelectionStructures (theObject, aSelMode, aCurSelector); + case SelectMgr_TOU_Partial: + theObject->UpdateTransformations (aSelection); + aCurSelector->RebuildObjectsTree(); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + break; + default: + break; } + aSelection->UpdateStatus (SelectMgr_TOU_None); } } } @@ -650,206 +725,195 @@ RecomputeSelection (const Handle(SelectMgr_SelectableObject)& anObject, // If ForceUpdate = True, and they are "TO RECALCULATE" // This is done without caring for the state of activation. //======================================================================= -void SelectMgr_SelectionManager::Update(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Boolean ForceUpdate) +void SelectMgr_SelectionManager::Update (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Boolean theIsForce) { - PrsMgr_ListOfPresentableObjectsIter anIter (anObject->Children()); - for (; anIter.More(); anIter.Next()) + for (PrsMgr_ListOfPresentableObjectsIter aChildIter (theObject->Children()); aChildIter.More(); aChildIter.Next()) { - const Handle(SelectMgr_SelectableObject) aSelectable = Handle(SelectMgr_SelectableObject)::DownCast (anIter.Value()); - - if (!aSelectable.IsNull()) - { - Update (aSelectable, ForceUpdate); - } + Update (Handle(SelectMgr_SelectableObject)::DownCast (aChildIter.Value()), theIsForce); } - Standard_Boolean wasrecomputed; + if (!theObject->HasOwnPresentations()) + return; - for(anObject->Init();anObject->More();anObject->Next()){ - const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection(); - wasrecomputed = Standard_False; - if(ForceUpdate){ - switch(Sel->UpdateStatus()){ + for (theObject->Init(); theObject->More(); theObject->Next()) + { + const Handle(SelectMgr_Selection)& aSelection = theObject->CurrentSelection(); + if (theIsForce) + { + switch (aSelection->UpdateStatus()) + { case SelectMgr_TOU_Full: - anObject->UpdateSelection(Sel->Mode()); // no break on purpose... + ClearSelectionStructures (theObject, aSelection->Mode()); + theObject->RecomputePrimitives (aSelection->Mode()); // no break on purpose... + RestoreSelectionStructures (theObject, aSelection->Mode()); case SelectMgr_TOU_Partial: - anObject->UpdateTransformations(Sel); - wasrecomputed = Standard_True; + theObject->UpdateTransformations (aSelection); + rebuildSelectionStructures(); break; default: break; } - Sel->UpdateStatus(SelectMgr_TOU_None); + aSelection->UpdateStatus (SelectMgr_TOU_None); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); } - // it is checked which selectors are concerned by the selection - // to redo projections if necessary. - Handle(Standard_Transient) Tr; - for(TColStd_MapIteratorOfMapOfTransient It(myselectors);It.More();It.Next()){ - Tr = It.Key(); - Handle(SelectMgr_ViewerSelector) VS = *((Handle(SelectMgr_ViewerSelector)*)&Tr); - if(VS->Status(Sel)==SelectMgr_SOS_Activated) - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(Sel->Mode()); // no break on purpose... - case SelectMgr_TOU_Partial: - anObject->UpdateTransformations(Sel); - wasrecomputed = Standard_True; - break; - default: - break; - } - if(wasrecomputed) - VS->Convert(Sel); - Sel->UpdateStatus(SelectMgr_TOU_None); + for (TColStd_MapIteratorOfMapOfTransient aSelectorIter (mySelectors); aSelectorIter.More(); aSelectorIter.Next()) + { + const Handle(SelectMgr_ViewerSelector)& aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorIter.Key()); + Update (theObject, aSelector, Standard_False); } } } - //================================================== // Function: Update // Purpose : Attention, it is required to know what is done... //================================================== -void SelectMgr_SelectionManager:: -Update(const Handle(SelectMgr_SelectableObject)& anObject, - const Handle(SelectMgr_ViewerSelector)& aViewSel, - const Standard_Boolean ForceUpdate) -{ - if( SelectDebugModeOnSM() ) cout<<"==>SelectMgr_SelectionManager::Update(obj,VS)"<Init();anObject->More();anObject->Next()){ - const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection(); - wasrecomputed = Standard_False; - if(ForceUpdate){ - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(Sel->Mode()); // no break on purpose... - case SelectMgr_TOU_Partial: - anObject->UpdateTransformations(Sel); - wasrecomputed = Standard_True; - break; - default: - break; - } - Sel->UpdateStatus(SelectMgr_TOU_None); - } - - if(aViewSel->Status(Sel) == SelectMgr_SOS_Activated){ - switch(Sel->UpdateStatus()){ - case SelectMgr_TOU_Full: - anObject->UpdateSelection(Sel->Mode()); - case SelectMgr_TOU_Partial: - if(anObject->HasTransformation()) - anObject->UpdateTransformations(Sel); - wasrecomputed = Standard_True; - break; - default: - break; - } - if(wasrecomputed) - aViewSel->Convert(Sel); - Sel->UpdateStatus(SelectMgr_TOU_None); - } - } -} - -//================================================== -// Function: Status -// Purpose : -//================================================== -TCollection_AsciiString SelectMgr_SelectionManager:: -Status() const{ - TCollection_AsciiString theMgrStatus("\t\t\tStatus of the SelectManager :;\n\t\t\t============================\n"); - - TCollection_AsciiString nbview (myselectors.Extent()),nbglobal(myglobal.Extent()); - - theMgrStatus += "\t Number of ViewerSelectors: "; - theMgrStatus += nbview + "\n\t Number of global objects : " + nbglobal+"\n"; - theMgrStatus = theMgrStatus+"\t Number of local objects : " + TCollection_AsciiString (mylocal.Extent())+" \n"; - - return theMgrStatus; -} - -//================================================== -// Function: Status -// Purpose : -//================================================== - - -TCollection_AsciiString SelectMgr_SelectionManager:: -Status(const Handle(SelectMgr_SelectableObject)& anObject) const +void SelectMgr_SelectionManager::Update (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_ViewerSelector)& theSelector, + const Standard_Boolean theIsForce) { - TCollection_AsciiString TheStatus("\t\tStatus of object:"); + if (!mySelectors.Contains (theSelector)) + return; - if(myglobal.Contains(anObject)) - {TheStatus += "GLOBAL (available for all viewers in the SelectionManager)\n";} - else if (mylocal.IsBound(anObject))TheStatus +="LOCAL:\n\t\t"; - TColStd_MapIteratorOfMapOfTransient It(myselectors); - Standard_Integer iv = 0; - // Standard_Boolean FirstTime=Standard_True; - for(;It.More();It.Next()){ - const Handle(SelectMgr_ViewerSelector)& curview = - Handle(SelectMgr_ViewerSelector)::DownCast(It.Key()); - iv++; - TheStatus = TheStatus + "status in the ViewerSelector :"+TCollection_AsciiString(iv)+"\n\t\t"; - TheStatus+=curview->Status(anObject); - TheStatus+="\n\t\t----------------------\n\t\t"; + Standard_Boolean isKnown = myGlobal.Contains (theObject); + if (!isKnown) + isKnown = (myLocal.IsBound (theObject) && (FindIndex (myLocal.Find (theObject), theSelector) != 0)); + if (!isKnown) + return; + + for (PrsMgr_ListOfPresentableObjectsIter aChildIter (theObject->Children()); aChildIter.More(); aChildIter.Next()) + { + Update (Handle(SelectMgr_SelectableObject)::DownCast (aChildIter.Value()), theSelector, theIsForce); } - return TheStatus; + if (!theObject->HasOwnPresentations()) + return; + for (theObject->Init(); theObject->More(); theObject->Next()) + { + const Handle(SelectMgr_Selection)& aSelection = theObject->CurrentSelection(); + if (theIsForce) + { + switch (aSelection->UpdateStatus()) + { + case SelectMgr_TOU_Full: + ClearSelectionStructures (theObject, aSelection->Mode()); + theObject->RecomputePrimitives (aSelection->Mode()); + RestoreSelectionStructures (theObject, aSelection->Mode()); + case SelectMgr_TOU_Partial: + theObject->UpdateTransformations (aSelection); + rebuildSelectionStructures(); + break; + default: + break; + } + aSelection->UpdateStatus (SelectMgr_TOU_None); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + } + + if (theSelector->Status (aSelection) == SelectMgr_SOS_Activated) + { + switch (aSelection->UpdateStatus()) + { + case SelectMgr_TOU_Full: + ClearSelectionStructures (theObject, aSelection->Mode(), theSelector); + theObject->RecomputePrimitives (aSelection->Mode()); + RestoreSelectionStructures (theObject, aSelection->Mode(), theSelector); + case SelectMgr_TOU_Partial: + if (theObject->HasTransformation()) + { + theObject->UpdateTransformations (aSelection); + theSelector->RebuildObjectsTree(); + } + break; + default: + break; + } + + aSelection->UpdateStatus(SelectMgr_TOU_None); + aSelection->UpdateBVHStatus (SelectMgr_TBU_None); + } + } } //================================================== -// Function: LoadMode +// Function: loadMode // Purpose : Private Method //================================================== - - -void SelectMgr_SelectionManager -::LoadMode (const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer amode) +void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const Handle(SelectMgr_ViewerSelector)& theSelector) { - if(amode==-1) return; - if(!anObject->HasSelection(amode)) + if (theMode == -1) + return; + + if (!theObject->HasSelection (theMode)) { - Handle(SelectMgr_Selection) NewSel = new SelectMgr_Selection(amode); - anObject->AddSelection (NewSel,amode); + Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode); + theObject->AddSelection (aNewSel, theMode); + if (theSelector == NULL) + { + if (myGlobal.Contains (theObject)) + { + TColStd_MapIteratorOfMapOfTransient aSelectorIter (mySelectors); + for ( ; aSelectorIter.More(); aSelectorIter.Next()) + { + Handle(SelectMgr_ViewerSelector) aSelector = + Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorIter.Key()); + aSelector->AddSelectionToObject (theObject, aNewSel); + aNewSel->UpdateBVHStatus (SelectMgr_TBU_None); + } + } + else if (myLocal.IsBound (theObject)) + { + const SelectMgr_SequenceOfSelector& aSelectors = myLocal (theObject); + for (Standard_Integer aSelectorIdx = 1; aSelectorIdx <= aSelectors.Length(); ++aSelectorIdx) + { + aSelectors (aSelectorIdx)->AddSelectionToObject (theObject, aNewSel); + aNewSel->UpdateBVHStatus (SelectMgr_TBU_None); + } + } + } + else + { + theSelector->AddSelectionToObject (theObject, aNewSel); + aNewSel->UpdateBVHStatus (SelectMgr_TBU_None); + } + } + else if (theObject->Selection (theMode)->IsEmpty()) + { + if (theObject->Selection (theMode)->BVHUpdateStatus() == SelectMgr_TBU_Remove) + { + Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode); + theObject->AddSelection (aNewSel, theMode); + theObject->Selection (theMode)->UpdateBVHStatus (SelectMgr_TBU_Remove); + theObject->Selection (theMode)->SetSelectionState (SelectMgr_SOS_Deactivated); + } } } - //======================================================================= //function : SetUpdateMode -//purpose : +//purpose : //======================================================================= - -void SelectMgr_SelectionManager:: -SetUpdateMode(const Handle(SelectMgr_SelectableObject)& anObject, - const SelectMgr_TypeOfUpdate aType) +void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject, + const SelectMgr_TypeOfUpdate theType) { - for(anObject->Init();anObject->More();anObject->Next()) - anObject->CurrentSelection()->UpdateStatus(aType); - + for (theObject->Init(); theObject->More(); theObject->Next()) + theObject->CurrentSelection()->UpdateStatus (theType); } -void SelectMgr_SelectionManager:: -SetUpdateMode(const Handle(SelectMgr_SelectableObject)& anObject, - const Standard_Integer aMode, - const SelectMgr_TypeOfUpdate aType) +//======================================================================= +//function : SetUpdateMode +//purpose : +//======================================================================= +void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Integer theMode, + const SelectMgr_TypeOfUpdate theType) { - if(anObject->HasSelection(aMode)) - anObject->Selection(aMode)->UpdateStatus(aType); + if (theObject->HasSelection (theMode)) + theObject->Selection (theMode)->UpdateStatus (theType); } diff --git a/src/SelectMgr/SelectMgr_SensitiveEntity.cxx b/src/SelectMgr/SelectMgr_SensitiveEntity.cxx new file mode 100644 index 0000000000..5d515ed981 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SensitiveEntity.cxx @@ -0,0 +1,74 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +// function : SelectMgr_SensitiveEntity +// purpose : Creates new inactive for selection object with base entity +// theEntity +//======================================================================= +SelectMgr_SensitiveEntity::SelectMgr_SensitiveEntity (const Handle(SelectBasics_SensitiveEntity)& theEntity) +{ + mySensitive = theEntity; + myIsActiveForSelection = Standard_False; +} + +//======================================================================= +// function : Clear +// purpose : Clears up all the resources and memory +//======================================================================= +void SelectMgr_SensitiveEntity::Clear() +{ + mySensitive->Clear(); + mySensitive.Nullify(); +} + +//======================================================================= +// function : BaseSensitive +// purpose : Returns related instance of SelectBasics class +//======================================================================= +const Handle(SelectBasics_SensitiveEntity)& SelectMgr_SensitiveEntity::BaseSensitive() const +{ + return mySensitive; +} + +//======================================================================= +// function : IsActiveForSelection +// purpose : Returns true if this entity belongs to the active selection +// mode of parent object +//======================================================================= +const Standard_Boolean SelectMgr_SensitiveEntity::IsActiveForSelection() const +{ + return myIsActiveForSelection; +} + +//======================================================================= +// function : ResetSelectionActiveStatus +// purpose : Marks entity as inactive for selection +//======================================================================= +void SelectMgr_SensitiveEntity::ResetSelectionActiveStatus() const +{ + myIsActiveForSelection = Standard_False; +} + +//======================================================================= +// function : SetActiveForSelection +// purpose : Marks entity as active for selection +//======================================================================= +void SelectMgr_SensitiveEntity::SetActiveForSelection() const +{ + myIsActiveForSelection = Standard_True; +} diff --git a/src/SelectMgr/SelectMgr_SensitiveEntity.hxx b/src/SelectMgr/SelectMgr_SensitiveEntity.hxx new file mode 100644 index 0000000000..71787a0f69 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SensitiveEntity.hxx @@ -0,0 +1,55 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_SensitiveEntity_HeaderFile +#define _SelectMgr_SensitiveEntity_HeaderFile + +#include +#include + +//! The purpose of this class is to mark sensitive entities selectable or not +//! depending on current active selection of parent object for proper BVH traverse +class SelectMgr_SensitiveEntity +{ +public: + + //! Creates new inactive for selection object with base entity theEntity + SelectMgr_SensitiveEntity (const Handle(SelectBasics_SensitiveEntity)& theEntity); + + ~SelectMgr_SensitiveEntity() {} + + //! Clears up all resources and memory + void Clear(); + + //! Returns related instance of SelectBasics class + Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& BaseSensitive() const; + + //! Returns true if this entity belongs to the active selection + //! mode of parent object + const Standard_Boolean IsActiveForSelection() const; + + //! Marks entity as inactive for selection + Standard_EXPORT void ResetSelectionActiveStatus() const; + + //! Marks entity as active for selection + Standard_EXPORT void SetActiveForSelection() const; + +private: + + Handle(SelectBasics_SensitiveEntity) mySensitive; //!< Related SelectBasics entity + mutable Standard_Boolean myIsActiveForSelection; //!< Selection activity status +}; + +#endif // _SelectMgr_SensitiveEntity_HeaderFile diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx new file mode 100644 index 0000000000..e2a591af78 --- /dev/null +++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx @@ -0,0 +1,181 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +#include +#include + +//======================================================================= +// function : SelectMgr_SensitiveEntitySet +// purpose : +//======================================================================= +SelectMgr_SensitiveEntitySet::SelectMgr_SensitiveEntitySet() +{ + myBuilder = new BVH_BinnedBuilder (1, 32, Standard_True); +} + +//======================================================================= +// function : Append +// purpose : Adds new entity to the set and marks BVH tree for rebuild +//======================================================================= +void SelectMgr_SensitiveEntitySet::Append (const SelectMgr_HSensitiveEntity& theEntity) +{ + if (!theEntity->BaseSensitive()->IsKind ("Select3D_SensitiveEntity")) + { + theEntity->ResetSelectionActiveStatus(); + return; + } + myEntities.Append (theEntity); + myEntityIdxs.Append (myEntities.Size()); + MarkDirty(); +} + +//======================================================================= +// function : Append +// purpose : Adds every entity of selection theSelection to the set +// and marks BVH tree for rebuild +//======================================================================= +void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_Selection)& theSelection) +{ + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + if (!theSelection->Sensitive()->BaseSensitive()->IsKind ("Select3D_SensitiveEntity")) + { + theSelection->Sensitive()->ResetSelectionActiveStatus(); + continue; + } + myEntities.Append (theSelection->Sensitive()); + myEntityIdxs.Append (myEntities.Size()); + } + MarkDirty(); +} + +//======================================================================= +// function : Remove +// purpose : Removes entity from the set and marks BVH tree for rebuild +//======================================================================= +void SelectMgr_SensitiveEntitySet::Remove (const SelectMgr_HSensitiveEntity& theEntity) +{ + for (Standard_Integer anEntityIdx = 1; anEntityIdx <= myEntities.Size(); ++anEntityIdx) + { + if (myEntities.Value (anEntityIdx) == theEntity) + { + myEntities.Remove (anEntityIdx); + myEntityIdxs.Clear(); + for (Standard_Integer anEntityIndexesIter = 1; anEntityIndexesIter <= myEntities.Size(); ++anEntityIndexesIter) + { + myEntityIdxs.Append (anEntityIndexesIter); + } + MarkDirty(); + break; + } + } +} + +//======================================================================= +// function : Remove +// purpose : Removes every entity of selection theSelection from the set +// and marks BVH tree for rebuild +//======================================================================= +void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& theSelection) +{ + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + for (Standard_Integer anEntityIdx = 1; anEntityIdx <= myEntities.Size(); ++anEntityIdx) + { + if (myEntities.Value (anEntityIdx) == theSelection->Sensitive()) + { + myEntities.Remove (anEntityIdx); + MarkDirty(); + } + } + } + + if (BVH_Object::myIsDirty) + { + myEntityIdxs.Clear(); + for (Standard_Integer anEntityIdxsIter = 1; anEntityIdxsIter <= myEntities.Size(); ++anEntityIdxsIter) + { + myEntityIdxs.Append (anEntityIdxsIter); + } + } +} + +//======================================================================= +// function : Box +// purpose : Returns bounding box of entity with index theIdx +//======================================================================= +Select3D_BndBox3d SelectMgr_SensitiveEntitySet::Box (const Standard_Integer theIndex) const +{ + Standard_Integer anEntityIdx = myEntityIdxs.Value (theIndex + 1); + return myEntities.Value (anEntityIdx)->BaseSensitive()->BoundingBox(); +} + +//======================================================================= +// function : Center +// purpose : Returns geometry center of sensitive entity index theIdx +// along the given axis theAxis +//======================================================================= +Standard_Real SelectMgr_SensitiveEntitySet::Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const +{ + Standard_Integer anEntityIdx = myEntityIdxs.Value (theIndex + 1); + const Handle(SelectBasics_SensitiveEntity)& aBasicEntity = + myEntities.Value (anEntityIdx)->BaseSensitive(); + const Handle(Select3D_SensitiveEntity)& aSensitive = + Handle(Select3D_SensitiveEntity)::DownCast (aBasicEntity); + const gp_Pnt aCenter = aSensitive->CenterOfGeometry(); + Standard_Real aCenterCoord = 0.0; + aCenterCoord = theAxis == 0 ? aCenter.X() : + (theAxis == 1 ? aCenter.Y() : aCenter.Z()); + + return aCenterCoord; +} + +//======================================================================= +// function : Swap +// purpose : Swaps items with indexes theIdx1 and theIdx2 +//======================================================================= +void SelectMgr_SensitiveEntitySet::Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) +{ + Standard_Integer anEntityIdx1 = myEntityIdxs.Value (theIndex1 + 1); + Standard_Integer anEntityIdx2 = myEntityIdxs.Value (theIndex2 + 1); + myEntityIdxs.ChangeValue (theIndex1 + 1) = anEntityIdx2; + myEntityIdxs.ChangeValue (theIndex2 + 1) = anEntityIdx1; +} + +//======================================================================= +// function : Size +// purpose : Returns the amount of entities +//======================================================================= +Standard_Integer SelectMgr_SensitiveEntitySet::Size() const +{ + return myEntityIdxs.Size(); +} + +//======================================================================= +// function : GetSensitiveById +// purpose : Returns the entity with index theIndex in the set +//======================================================================= +const SelectMgr_HSensitiveEntity& SelectMgr_SensitiveEntitySet::GetSensitiveById + (const Standard_Integer theIndex) const +{ + Standard_Integer anIdx = myEntityIdxs.Value (theIndex + 1); + return myEntities.Value (anIdx); +} diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx new file mode 100644 index 0000000000..c143bb94cb --- /dev/null +++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx @@ -0,0 +1,78 @@ +// Created on: 2014-08-15 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_SensitiveEntitySet_HeaderFile +#define _SelectMgr_SensitiveEntitySet_HeaderFile + +#include + +#include +#include + +#include + +#include +#include + +//! This class is used to store all calculated sensitive entites of one selectable +//! object. It provides an interface for building BVH tree which is used to speed-up +//! the performance of searching for overlap among sensitives of one selectable object +class SelectMgr_SensitiveEntitySet : public BVH_PrimitiveSet +{ +public: + + SelectMgr_SensitiveEntitySet(); + + virtual ~SelectMgr_SensitiveEntitySet() {}; + + //! Adds new entity to the set and marks BVH tree for rebuild + void Append (const SelectMgr_HSensitiveEntity& theEntity); + + //! Adds every entity of selection theSelection to the set and marks + //! BVH tree for rebuild + void Append (const Handle(SelectMgr_Selection)& theSelection); + + //! Removes entity from the set and marks BVH tree for rebuild + void Remove (const SelectMgr_HSensitiveEntity& theEntity); + + //! Removes every entity of selection theSelection from the set + //! and marks BVH tree for rebuild + void Remove (const Handle(SelectMgr_Selection)& theSelection); + + //! Returns bounding box of entity with index theIdx + virtual Select3D_BndBox3d Box (const Standard_Integer theIndex) const Standard_OVERRIDE; + + //! Returns geometry center of sensitive entity index theIdx + //! along the given axis theAxis + virtual Standard_Real Center (const Standard_Integer theIndex, + const Standard_Integer theAxis) const Standard_OVERRIDE; + + //! Swaps items with indexes theIdx1 and theIdx2 + virtual void Swap (const Standard_Integer theIndex1, + const Standard_Integer theIndex2) Standard_OVERRIDE; + + //! Returns the amount of entities + virtual Standard_Integer Size() const Standard_OVERRIDE; + + //! Returns the entity with index theIndex in the set + const SelectMgr_HSensitiveEntity& GetSensitiveById (const Standard_Integer theIndex) const; + +private: + + NCollection_Sequence myEntities; //!< A sequence of calculated sensitives of the object + NCollection_Sequence myEntityIdxs; //!< Cached indexes for faster BVH build +}; + +#endif // _SelectMgr_SensitiveEntitySet_HeaderFile diff --git a/src/Select3D/Select3D_SensitiveEntity.lxx b/src/SelectMgr/SelectMgr_SequenceOfSelection.hxx similarity index 58% rename from src/Select3D/Select3D_SensitiveEntity.lxx rename to src/SelectMgr/SelectMgr_SequenceOfSelection.hxx index 47c57a6d3b..a1c9781f8b 100644 --- a/src/Select3D/Select3D_SensitiveEntity.lxx +++ b/src/SelectMgr/SelectMgr_SequenceOfSelection.hxx @@ -1,5 +1,6 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS +// Created on: 2015-02-13 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // @@ -12,6 +13,13 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline Standard_Boolean Select3D_SensitiveEntity::NeedsConversion() const -{return Standard_True;} +#ifndef _SelectMgr_SequenceOfSelection_HeaderFile +#define _SelectMgr_SequenceOfSelection_HeaderFile + +#include +#include + +typedef NCollection_Sequence SelectMgr_SequenceOfSelection; + +#endif // _SelectMgr_SequenceOfSelection_HeaderFile diff --git a/src/SelectMgr/SelectMgr_TriangularFrustum.cxx b/src/SelectMgr/SelectMgr_TriangularFrustum.cxx new file mode 100644 index 0000000000..715d1a8e7c --- /dev/null +++ b/src/SelectMgr/SelectMgr_TriangularFrustum.cxx @@ -0,0 +1,341 @@ +// Created on: 2014-11-21 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z()) +#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z()) +#define LENGTH(A) (std::sqrt (A.x() * A.x() + A.y() * A.y() + A.z() * A.z())) + +SelectMgr_TriangularFrustum::~SelectMgr_TriangularFrustum() +{ + Clear(); +} + +//======================================================================= +// function : SelectMgr_TriangularFrustum +// purpose : Creates new triangular frustum with bases of triangles with +// vertices theP1, theP2 and theP3 projections onto near and +// far view frustum planes +//======================================================================= +void SelectMgr_TriangularFrustum::Build (const gp_Pnt2d& theP1, + const gp_Pnt2d& theP2, + const gp_Pnt2d& theP3) +{ + // V0_Near + myVertices[0] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 0.0); + // V1_Near + myVertices[1] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 0.0); + // V2_Near + myVertices[2] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 0.0); + // V0_Far + myVertices[3] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 1.0); + // V1_Far + myVertices[4] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 1.0); + // V2_Far + myVertices[5] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 1.0); + + // V0V1 + myPlanes[0] = myBuilder->PlaneEquation (myVertices[0], + myVertices[3], + myVertices[4], + myVertices[1]); + // V1V2 + myPlanes[1] = myBuilder->PlaneEquation (myVertices[1], + myVertices[4], + myVertices[5], + myVertices[2]); + // V0V2 + myPlanes[2] = myBuilder->PlaneEquation (myVertices[0], + myVertices[3], + myVertices[5], + myVertices[2]); + // Near + myPlanes[3] = myBuilder->PlaneEquation (myVertices[0], + myVertices[1], + myVertices[2]); + // Far + myPlanes[4] = myBuilder->PlaneEquation (myVertices[3], + myVertices[4], + myVertices[5]); + + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++aPlaneIdx) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx) + { + Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + myMaxVertsProjections[aPlaneIdx] = aMax; + myMinVertsProjections[aPlaneIdx] = aMin; + } + + SelectMgr_Vec3 aDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + myMaxOrthoVertsProjections[aDim] = aMax; + myMinOrthoVertsProjections[aDim] = aMin; + } + + // V0_Near - V0_Far + myEdgeDirs[0] = myVertices[0] - myVertices[3]; + // V1_Near - V1_Far + myEdgeDirs[1] = myVertices[1] - myVertices[4]; + // V2_Near - V1_Far + myEdgeDirs[2] = myVertices[2] - myVertices[5]; + // V1_Near - V0_Near + myEdgeDirs[3] = myVertices[1] - myVertices[0]; + // V2_Near - V1_Near + myEdgeDirs[4] = myVertices[2] - myVertices[1]; + // V1_Near - V0_Near + myEdgeDirs[5] = myVertices[2] - myVertices[0]; +} + +//======================================================================= +// function : Transform +// purpose : Returns a copy of the frustum transformed according to the matrix given +//======================================================================= +NCollection_Handle SelectMgr_TriangularFrustum::Transform (const gp_Trsf& theTrsf) +{ + SelectMgr_TriangularFrustum* aRes = new SelectMgr_TriangularFrustum(); + + // V0_Near + aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]); + // V1_Near + aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]); + // V2_Near + aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]); + // V0_Far + aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]); + // V1_Far + aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]); + // V2_Far + aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]); + + aRes->myIsOrthographic = myIsOrthographic; + + // V0V1 + aRes->myPlanes[0] = myBuilder->PlaneEquation (aRes->myVertices[0], + aRes->myVertices[3], + aRes->myVertices[4], + aRes->myVertices[1]); + // V1V2 + aRes->myPlanes[1] = myBuilder->PlaneEquation (aRes->myVertices[1], + aRes->myVertices[4], + aRes->myVertices[5], + aRes->myVertices[2]); + // V0V2 + aRes->myPlanes[2] = myBuilder->PlaneEquation (aRes->myVertices[0], + aRes->myVertices[3], + aRes->myVertices[5], + aRes->myVertices[2]); + // Near + aRes->myPlanes[3] = myBuilder->PlaneEquation (aRes->myVertices[0], + aRes->myVertices[1], + aRes->myVertices[2]); + // Far + aRes->myPlanes[4] = myBuilder->PlaneEquation (aRes->myVertices[3], + aRes->myVertices[4], + aRes->myVertices[5]); + + for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++aPlaneIdx) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx) + { + Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + aRes->myMaxVertsProjections[aPlaneIdx] = aMax; + aRes->myMinVertsProjections[aPlaneIdx] = aMin; + } + + SelectMgr_Vec3 aDimensions[3] = + { + SelectMgr_Vec3 (1.0, 0.0, 0.0), + SelectMgr_Vec3 (0.0, 1.0, 0.0), + SelectMgr_Vec3 (0.0, 0.0, 1.0) + }; + + for (Standard_Integer aDim = 0; aDim < 3; ++aDim) + { + Standard_Real aMax = -DBL_MAX; + Standard_Real aMin = DBL_MAX; + for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx) + { + Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]); + aMax = Max (aMax, aProjection); + aMin = Min (aMin, aProjection); + } + aRes->myMaxOrthoVertsProjections[aDim] = aMax; + aRes->myMinOrthoVertsProjections[aDim] = aMin; + } + + // V0_Near - V0_Far + aRes->myEdgeDirs[0] = aRes->myVertices[0] - aRes->myVertices[3]; + // V1_Near - V1_Far + aRes->myEdgeDirs[1] = aRes->myVertices[1] - aRes->myVertices[4]; + // V2_Near - V1_Far + aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[5]; + // V1_Near - V0_Near + aRes->myEdgeDirs[3] = aRes->myVertices[1] - aRes->myVertices[0]; + // V2_Near - V1_Near + aRes->myEdgeDirs[4] = aRes->myVertices[2] - aRes->myVertices[1]; + // V1_Near - V0_Near + aRes->myEdgeDirs[5] = aRes->myVertices[2] - aRes->myVertices[0]; + + return NCollection_Handle (aRes); +} + +//======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and +// given axis-aligned box +//======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const BVH_Box& theBox, + Standard_Real& /*theDepth*/) +{ + return hasOverlap (theBox.CornerMin(), theBox.CornerMax()); +} + +// ======================================================================= +// function : Overlaps +// purpose : Returns true if selecting volume is overlapped by +// axis-aligned bounding box with minimum corner at point +// theMinPt and maximum at point theMaxPt +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const SelectMgr_Vec3& theMinPt, + const SelectMgr_Vec3& theMaxPt) +{ + return hasOverlap (theMinPt, theMaxPt); +} + +// ======================================================================= +// function : Overlaps +// purpose : Intersection test between defined volume and given point +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt, + Standard_Real& /*theDepth*/) +{ + return hasOverlap (thePnt); +} + +// ======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// ordered set of points, representing line segments. The test +// may be considered of interior part or boundary line defined +// by segments depending on given sensitivity type +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& /*theDepth*/) +{ + if (theSensType == Select3D_TOS_BOUNDARY) + { + Standard_Integer aLower = theArrayOfPnts->Lower(); + Standard_Integer anUpper = theArrayOfPnts->Upper(); + + for (Standard_Integer aPtIdx = aLower; aPtIdx <= anUpper; ++aPtIdx) + { + const gp_Pnt& aStartPt = theArrayOfPnts->Value (aPtIdx); + const gp_Pnt& aEndPt = aPtIdx == anUpper ? theArrayOfPnts->Value (aLower) : theArrayOfPnts->Value (aPtIdx + 1); + + if (!hasOverlap (aStartPt, aEndPt)) + { + return Standard_False; + } + } + } + else if (theSensType == Select3D_TOS_INTERIOR) + { + SelectMgr_Vec3 aNorm (RealLast()); + return hasOverlap (theArrayOfPnts, aNorm); + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : Checks if line segment overlaps selecting frustum +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + Standard_Real& /*theDepth*/) +{ + return hasOverlap (thePnt1, thePnt2); +} + +// ======================================================================= +// function : Overlaps +// purpose : SAT intersection test between defined volume and given +// triangle. The test may be considered of interior part or +// boundary line defined by triangle vertices depending on +// given sensitivity type +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) +{ + if (theSensType == Select3D_TOS_BOUNDARY) + { + Handle(TColgp_HArray1OfPnt) aPtsArray = new TColgp_HArray1OfPnt(1, 4); + aPtsArray->SetValue (1, thePnt1); + aPtsArray->SetValue (2, thePnt2); + aPtsArray->SetValue (3, thePnt3); + return Overlaps (aPtsArray, Select3D_TOS_BOUNDARY, theDepth); + } + else if (theSensType == Select3D_TOS_INTERIOR) + { + SelectMgr_Vec3 aNorm (RealLast()); + return hasOverlap (thePnt1, thePnt2, thePnt3, aNorm); + } + + return Standard_True; +} + +// ======================================================================= +// function : Clear +// purpose : Nullifies the handle for corresponding builder instance to prevent +// memory leaks +// ======================================================================= +void SelectMgr_TriangularFrustum::Clear() +{ + myBuilder.Nullify(); +} diff --git a/src/SelectMgr/SelectMgr_TriangularFrustum.hxx b/src/SelectMgr/SelectMgr_TriangularFrustum.hxx new file mode 100644 index 0000000000..fc8e5cd71a --- /dev/null +++ b/src/SelectMgr/SelectMgr_TriangularFrustum.hxx @@ -0,0 +1,85 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_TriangularFrustum_HeaderFile +#define _SelectMgr_TriangularFrustum_HeaderFile + +#include + +//! This class contains representation of triangular selecting frustum, created in case +//! of polyline selection, and algorithms for overlap detection between selecting +//! frustum and sensitive entities. +//! Overlap detection tests are implemented according to the terms of separating axis +//! theorem (SAT). +class SelectMgr_TriangularFrustum : public SelectMgr_Frustum<3> +{ +public: + + //! Creates new triangular frustum with bases of triangles with vertices theP1, + //! theP2 and theP3 projections onto near and far view frustum planes + SelectMgr_TriangularFrustum() {}; + + ~SelectMgr_TriangularFrustum(); + + //! Creates new triangular frustum with bases of triangles with vertices theP1, theP2 and theP3 + //! projections onto near and far view frustum planes (only for triangular frustums) + virtual void Build (const gp_Pnt2d& theP1, + const gp_Pnt2d& theP2, + const gp_Pnt2d& theP3) Standard_OVERRIDE; + + //! Returns a copy of the frustum transformed according to the matrix given + virtual NCollection_Handle Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; + + // SAT Tests for different objects + + //! SAT intersection test between defined volume and given axis-aligned box + virtual const Standard_Boolean Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Returns true if selecting volume is overlapped by axis-aligned bounding box + //! with minimum corner at point theMinPt and maximum at point theMaxPt + virtual const Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPt, + const SelectMgr_Vec3& theMaxPt) Standard_OVERRIDE; + + //! Intersection test between defined volume and given point + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given ordered set of points, + //! representing line segments. The test may be considered of interior part or + //! boundary line defined by segments depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Checks if line segment overlaps selecting frustum + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! SAT intersection test between defined volume and given triangle. The test may + //! be considered of interior part or boundary line defined by triangle vertices + //! depending on given sensitivity type + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + //! Nullifies the handle to corresponding builder instance to prevent memory leaks + void Clear(); +}; + +#endif // _SelectMgr_TriangularFrustum_HeaderFile diff --git a/src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx b/src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx new file mode 100644 index 0000000000..fd9c2f6291 --- /dev/null +++ b/src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx @@ -0,0 +1,222 @@ +// Created on: 2014-11-21 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include + +#include + +#define MEMORY_BLOCK_SIZE 512 * 7 + +// ======================================================================= +// function : BuildSelectingVolume +// purpose : Meshes polygon bounded by polyline. Than organizes a set of +// triangular frustums, where each triangle's projection onto +// near and far view frustum planes is considered as a frustum +// base +// ======================================================================= +void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoints) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + SelectMgr_HTriangularFrustum& aFrust = anIter.ChangeValue(); + aFrust.Nullify(); + } + myFrustums.Clear(); + + Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE); + Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator); + Standard_Integer aPtsLower = thePoints.Lower(); + Standard_Integer aPtsUpper = thePoints.Upper(); + BRepMesh::Array1OfInteger anIndexes (0, thePoints.Length() - 1); + for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx) + { + BRepMesh_Vertex aVertex (thePoints.Value (aPtIdx).XY(), aPtIdx, BRepMesh_Frontier); + anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex); + } + + Standard_Real aPtSum = 0; + for (Standard_Integer aIdx = aPtsLower; aIdx <= aPtsUpper; ++aIdx) + { + Standard_Integer aNextIdx = (aIdx % thePoints.Length()) + 1; + aPtSum += (thePoints.Value (aNextIdx).Coord().X() - thePoints.Value (aIdx).Coord().X()) + * (thePoints.Value (aNextIdx).Coord().Y() + thePoints.Value (aIdx).Coord().Y()); + } + Standard_Boolean isClockwiseOrdered = aPtSum < 0; + + for (Standard_Integer aIdx = 0; aIdx < anIndexes.Length(); ++aIdx) + { + Standard_Integer aPtIdx = isClockwiseOrdered ? aIdx : (aIdx + 1) % anIndexes.Length(); + Standard_Integer aNextPtIdx = isClockwiseOrdered ? (aIdx + 1) % anIndexes.Length() : aIdx; + BRepMesh_Edge anEdge (anIndexes.Value (aPtIdx), + anIndexes.Value (aNextPtIdx), + BRepMesh_Frontier); + aMeshStructure->AddLink (anEdge); + } + + BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes); + const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain(); + if (aTriangles.Extent() < 1) + return; + + BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles); + for (; aTriangleIt.More(); aTriangleIt.Next()) + { + const Standard_Integer aTriangleId = aTriangleIt.Key(); + const BRepMesh_Triangle& aCurrentTriangle = aMeshStructure->GetElement (aTriangleId); + + if (aCurrentTriangle.Movability() == BRepMesh_Deleted) + continue; + + Standard_Integer aTriangleVerts[3]; + aMeshStructure->ElementNodes (aCurrentTriangle, aTriangleVerts); + + gp_Pnt2d aPts[3]; + for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx) + { + const BRepMesh_Vertex& aVertex = aMeshStructure->GetNode (aTriangleVerts[aVertIdx]); + aPts[aVertIdx] = aVertex.Coord(); + } + + SelectMgr_HTriangularFrustum aTrFrustum = new SelectMgr_TriangularFrustum(); + aTrFrustum->SetBuilder (myBuilder); + aTrFrustum->Build (aPts[0], aPts[1], aPts[2]); + myFrustums.Append (aTrFrustum); + } + + aMeshStructure.Nullify(); + anAllocator.Nullify(); +} + +// ======================================================================= +// function : Transform +// purpose : Returns a copy of the frustum with all sub-volumes transformed +// according to the matrix given +// ======================================================================= +NCollection_Handle SelectMgr_TriangularFrustumSet::Transform (const gp_Trsf& theTrsf) +{ + SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet(); + + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + aRes->myFrustums.Append (NCollection_Handle::DownCast (anIter.Value()->Transform (theTrsf))); + } + + return NCollection_Handle (aRes); +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (theBox, theDepth)) + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt)) + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt, + Standard_Real& theDepth) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (thePnt, theDepth)) + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (theArrayOfPts, theSensType, theDepth)) + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + Standard_Real& theDepth) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (thePnt1, thePnt2, theDepth)) + return Standard_True; + } + + return Standard_False; +} + +// ======================================================================= +// function : Overlaps +// purpose : +// ======================================================================= +const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1, + const gp_Pnt& thePnt2, + const gp_Pnt& thePnt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) +{ + for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) + { + if (anIter.Value()->Overlaps (thePnt1, thePnt2, thePnt3, theSensType, theDepth)) + return Standard_True; + } + + return Standard_False; +} + +#undef MEMORY_BLOCK_SIZE diff --git a/src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx b/src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx new file mode 100644 index 0000000000..25133141d9 --- /dev/null +++ b/src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx @@ -0,0 +1,81 @@ +// Created on: 2014-05-22 +// Created by: Varvara POSKONINA +// Copyright (c) 2005-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_TriangularFrustumSet_HeaderFile +#define _SelectMgr_TriangularFrustumSet_HeaderFile + +#include +#include + +#include +#include + +typedef NCollection_Handle SelectMgr_HTriangularFrustum; +typedef NCollection_List SelectMgr_TriangFrustums; +typedef NCollection_List::Iterator SelectMgr_TriangFrustumsIter; + +//! This class is used to handle polyline selection. The main principle of polyline selection +//! algorithm is to split the polygon defined by polyline onto triangles. Than each of +//! them is considered as a base for triangular frustum building. In other +//! words, each triangle vertiex will be projected from 2d screen space to 3d world space +//! onto near and far view frustum planes. Thus, the projected triangles make up the bases of +//! selecting frustum. When the set of such frustums is created, the function determining +//! selection iterates through triangular frustum set and searches for overlap with any +//! frustum. +class SelectMgr_TriangularFrustumSet : public SelectMgr_BaseFrustum +{ +public: + + SelectMgr_TriangularFrustumSet() {}; + + ~SelectMgr_TriangularFrustumSet() {}; + + //! Meshes polygon bounded by polyline. Than organizes a set of triangular frustums, + //! where each triangle's projection onto near and far view frustum planes is + //! considered as a frustum base + virtual void Build (const TColgp_Array1OfPnt2d& thePoints) Standard_OVERRIDE; + + //! Returns a copy of the frustum with all sub-volumes transformed according to the matrix given + virtual NCollection_Handle Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const BVH_Box& theBox, + Standard_Real& theDepth) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt, + const SelectMgr_Vec3& theMaxPnt) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt, + Standard_Real& theDepth) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + Standard_Real& theDepth) Standard_OVERRIDE; + + virtual const Standard_Boolean Overlaps (const gp_Pnt& thePt1, + const gp_Pnt& thePt2, + const gp_Pnt& thePt3, + Select3D_TypeOfSensitivity theSensType, + Standard_Real& theDepth) Standard_OVERRIDE; + +private: + + SelectMgr_TriangFrustums myFrustums; +}; + +#endif // _SelectMgr_TriangularFrustumSet_HeaderFile diff --git a/src/SelectMgr/SelectMgr_VectorTypes.hxx b/src/SelectMgr/SelectMgr_VectorTypes.hxx new file mode 100644 index 0000000000..c8b92b2f1f --- /dev/null +++ b/src/SelectMgr/SelectMgr_VectorTypes.hxx @@ -0,0 +1,33 @@ +#ifndef _SelectMgr_VectorTypes_HeaderFile +#define _SelectMgr_VectorTypes_HeaderFile + +#include +#include +#include +#include +#include + +typedef NCollection_Vec3 SelectMgr_Vec3; +typedef NCollection_Vec4 SelectMgr_Vec4; +typedef NCollection_Mat4 SelectMgr_Mat4; + +namespace SelectMgr_MatOp +{ + inline SelectMgr_Vec3 Transform (const gp_Trsf& theTrsf, + const SelectMgr_Vec3& theVec) + { + SelectMgr_Vec3 aRes (0.0); + for (Standard_Integer aRow = 1; aRow <= 3; ++aRow) + { + for (Standard_Integer aCol = 1; aCol <= 3; ++aCol) + { + aRes[aRow - 1] += theVec[aCol - 1] * theTrsf.Value (aRow, aCol); + } + aRes[aRow - 1] += theTrsf.Value (aRow, 4); + } + + return aRes; + } +}; + +#endif // _SelectMgr_VectorTypes_HeaderFile diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cdl b/src/SelectMgr/SelectMgr_ViewerSelector.cdl deleted file mode 100644 index 01143d4135..0000000000 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cdl +++ /dev/null @@ -1,445 +0,0 @@ --- Created on: 1995-02-10 --- Created by: Mister rmi --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - ---modified by rob -FEB 01 1996 --- -JUL 23 1997 : optimize recompute of selections... --- insert real sleep/awake option.... --- -APR 02 1998 : improvment of selection. --- Sort with new Criterions --- (depth + size +...) --- store detected in a best way... - - -deferred class ViewerSelector from SelectMgr inherits TShared from MMgt - - ---Purpose: A framework to define finding, sorting the sensitive - -- primitives in a view. Services are also provided to - -- define the return of the owners of those primitives - -- selected. The primitives are sorted by criteria such - -- as priority of the primitive or its depth in the view - -- relative to that of other primitives. - -- This framework is undefined for either 2D or 3D, - -- and is consequently used by both - -- StdSelect_ViewerSelector2d and - -- StdSelect_ViewerSelector3d, which inherit it, and - -- which in turn, return 2D and 3D owners of sensitive - -- primitives respectively. - -- Note that in 3D, the inheriting framework - -- StdSelect_ViewerSelector3d is only to be used - -- if you do not want to use the services provided by - -- AIS. In 2D, you will, however, need the services - -- provided by the StdSelect_ViewerSelector2d. - -- Two tools are available to find and select objects - -- found at a given position in the view. If you want to - -- select the owners of all the objects detected at - -- point x,y, you use the Init - More - Next - Picked - -- loop. If, on the other hand, you want to select only - -- one object detected at that point, you use the Init - - -- More - OnePicked loop. In this iteration, More is - -- used to see if an object was picked and - -- OnePicked, to get the object closest to the pick position. - -- Viewer selectors are driven by - -- SelectMgr_SelectionManager, and manipulate - -- the SelectMgr_Selection objects given to them by - -- the selection manager. - -uses - AsciiString from TCollection, - SelectableObject from SelectMgr, - DataMapOfIntegerSensitive from SelectMgr, - DataMapOfSelectionActivation from SelectMgr, - Selection from SelectMgr, - Box2d from Bnd, - HArray1OfInteger from TColStd, - ListOfInteger from TColStd, - SequenceOfInteger from TColStd, - MapOfTransient from TColStd, - IndexedMapOfInteger from TColStd, - IndexedDataMapOfOwnerCriterion from SelectMgr, - SensitiveEntity from SelectBasics, - SortAlgo from SelectBasics, - PickArgs from SelectBasics, - EntityOwner from SelectMgr, - StateOfSelection from SelectMgr, - Array1OfPnt2d from TColgp, - Lin from gp - -is - - Initialize ; - - - - - Convert (me:mutable;aSelection : Selection from SelectMgr) is virtual; - ---Level: Public - ---Purpose: to be redefined if conversion is necessary for SensitiveEntities... - - - - ---Category: Activation/Desactivation Of Selection For Objects - -- No general method like "activate a mode (integer) " is possible - -- here because objects inside the selection view are of different type - -- - - - Activate (me : mutable; - aSelection : Selection from SelectMgr; - AutomaticProj : Boolean = Standard_True) - is static private; - ---Level: Internal - - - - - ---Category: Management Methods . Some following methods are private - -- because they owed to be called only through The Selection Manager !! - - Clear(me:mutable) is static; - ---Level: Public - ---Purpose: Empties all the tables, removes all selections... - - UpdateConversion(me :mutable) is static; - ---Level: Public - ---Purpose: converts all the sensitive entities ; - - Deactivate (me : mutable; - aSelection : Selection from SelectMgr) - is static private; - ---Level: Internal - - Sleep (me:mutable) is static private; - ---Level: Internal - ---Purpose: Desactivates all the objects of the view; - -- no object in this view will be selectable; - - Awake (me :mutable;AutomaticProj : Boolean = Standard_True) is static private; - ---Level: Internal - ---Purpose: reactivates all the selection which were sleeping.... - - Sleep (me : mutable; - anObject : SelectableObject from SelectMgr) is static private; - - Awake (me : mutable; - anObject : SelectableObject from SelectMgr; - AutomaticProj : Boolean = Standard_True) is static private; - - - Remove(me:mutable ; aSelection: Selection from SelectMgr) is static private; - ---Level: Public - ---Purpose: removes a Selection from the Selector - - - - ---Category: SELECTION OPERATIONS - ------------===================== - - SetSensitivity (me : mutable ; aTol:Real) is static; - ---Level: Public - ---Purpose: changes the Sensitivity of picking - -- Input value is Real. - - Sensitivity (me) returns Real from Standard; - ---Level: Public - ---Purpose: returns the Sensitivity of picking - ---C++: inline - - SetClipping(me:mutable ; Xc,Yc,Height,Width:Real) is static; - ---Level: Public - ---Purpose: sets the clipping limits of dynamic picking - -- input value are Real - - SetClipping(me:mutable ; aRectangle : Box2d from Bnd) is static; - ---Level: Public - ---Purpose: sets the clipping limits of dynamic picking - -- input value are Real - - - - - InitSelect (me : mutable ; Xr,Yr : Real) is static; - ---Level: Public - ---Purpose: Performs a pick action. Xr, Yr are the real 2D mouse - -- coordinates in the view. The selector looks for areas - -- and owners that are touched. - - InitSelect (me : mutable ; aRect: Box2d from Bnd) is static; - ---Level: Public - ---Purpose: Performs a pick action. aRect is a Box2d (real - -- coordinates) for the selection. The selector looks for - -- areas and owners that are touched. - - InitSelect (me : mutable ; Xmin,Ymin,Xmax,Ymax: Real) is static; - ---Purpose: Performs a pick action - -- - Xmin, Ymin define the coordinates of the minimum - -- point in the lower left hand corner of the selection - -- box, and XMax, YMax define the coordinates of - -- the maximum point in the upper right hand corner - -- of the selection box. The selector looks for areas - -- and owners that are touched. - - InitSelect (me : mutable ; Polyline:Array1OfPnt2d from TColgp) is static; - ---Level: Public - ---Purpose: pick action - input values of a polyline selection for selection. - - - - - ---Category: RESULT OF SELECTION... - -- 2 Methods : *all the detected objects are given - -- (use More - Next - Picked loop) - -- *only one is wanted : - -- (use More to know if something was picked and OnePicked - -- to get the closest object of pick position). - -- - -- - - SortResult(me:mutable) is virtual; - ---Purpose: Sorts the detected entites by priority and distance. - -- to be redefined if other criterion are used... - - Init(me:mutable) is static; - ---Purpose: Begins an iteration scanning for the owners detected at a position in the view. - ---C++: inline - - More(me:mutable) returns Boolean from Standard is static; - ---Purpose: Continues the interation scanning for the owners - -- detected at a position in the view, or - -- - continues the iteration scanning for the owner - -- closest to the position in the view. - - Next(me:mutable) is static; - ---Purpose: Returns the next owner found in the iteration. This is - -- a scan for the owners detected at a position in the view. - ---C++: inline - - - Picked(me) returns EntityOwner from SelectMgr is static; - ---Level: Public - ---Purpose: Returns the current selected entity detected by the selector; - - - OnePicked(me:mutable) returns EntityOwner from SelectMgr is static; - ---Purpose: Returns the picked element with the highest priority, - -- and which is the closest to the last successful mouse position. - - SetPickClosest(me: mutable; preferClosest: Boolean); - ---Purpose: Set preference of selecting one object for OnePicked() method: - -- - If True, objects with less depth (distance fron the view plane) are - -- preferred regardless of priority (priority is used then to choose among - -- objects with similar depth), - -- - If False, objects with higher priority are preferred regardless of the - -- depth which is used to choose among objects of the same priority. - ---C++: inline - - - NbPicked(me) returns Integer from Standard; - ---Purpose: Returns the number of owners found at a position in - -- the view by the Init - More - Next - Picked iteration. - - Picked(me;aRank:Integer from Standard) - returns any EntityOwner from SelectMgr; - ---Purpose: Returns the entity which is at rank - -- in the list of stored ones. - - - HasStored (me:mutable) returns Boolean is static; - ---Level: Public - ---Purpose: Returns True if a successful pick was stored, - -- i.e. LastPosition method means something... - - LastPosition (me; Xr,Yr : out Real ) is static; - ---Level: Public - ---Purpose: Gives the last successful pick position; - -- is useful to get objects really picked - - - - - - ---Category: INFORMATION ABOUT OBJECTS IN THE VIEWER SELECTOR - - - Contains (me;aSelectableObject: SelectableObject from SelectMgr) - returns Boolean is static; - - - Modes (me; - aSelectableObject:SelectableObject from SelectMgr; - ModeList : in out ListOfInteger from TColStd; - WantedState : StateOfSelection from SelectMgr = SelectMgr_SOS_Any) returns Boolean; - ---Purpose: Returns the list of selection modes ModeList found in - -- this selector for the selectable object aSelectableObject. - -- Returns true if aSelectableObject is referenced inside - -- this selector; returns false if the object is not present - -- in this selector. - - IsActive (me;aSelectableObject:SelectableObject;aMode:Integer) returns Boolean is static ; - ---Purpose: Returns true if the selectable object - -- aSelectableObject having the selection mode aMode - -- is active in this selector. - - IsInside (me;aSelectableObject:SelectableObject;aMode:Integer) returns Boolean is static ; - ---Purpose: Returns true if the selectable object - -- aSelectableObject having the selection mode aMode - -- is in this selector. - - Status (me;aSelection :Selection from SelectMgr) returns StateOfSelection from SelectMgr; - ---Purpose: Returns the selection status Status of the selection aSelection. - - Dump(me;S : in out OStream from Standard); - - - Status (me;aSelectableObject:SelectableObject) returns AsciiString from TCollection is static; - - Status (me) returns AsciiString from TCollection is static; - ---Level: Internal - ---Purpose: gives general information about the Selector - - - - - - - - ---Category: Internal Methods - - - NbBoxes(me:mutable) returns Integer is static private; - ---Level: Internal - - UpdateSort (me:mutable) is static; - ---Level: Internal - - LoadResult (me:mutable) is virtual protected; - ---Level: Internal - - LoadResult (me:mutable;aBox:Box2d from Bnd) is virtual protected; - ---Level: Internal - - LoadResult (me:mutable;Polyline:Array1OfPnt2d from TColgp) is virtual protected; - ---Level: Internal - - - - Primitive(me;Rank:Integer from Standard) - returns SensitiveEntity from SelectBasics; - ---Level: Internal - - Primitives(me) - returns DataMapOfIntegerSensitive from SelectMgr; - ---Level: Internal - ---C++: inline - ---C++: return const& - - SetUpdateSortPossible( me: mutable; possible : Boolean from Standard ); - IsUpdateSortPossible( me ) returns Boolean from Standard; - - PickingLine (me; theX, theY : Real from Standard) - returns Lin from gp - is virtual protected; - ---Level: Internal - ---Purpose: Returns picking line along which the depth value should be - -- computed. Override this method to compute picking line by the same - -- which is used for projecting sensitive entities to selection space. - -- @param theX [in] the x picking coordinate. - -- @param theY [in] the y picking coordinate. - -- @return picking line. - - DepthClipping (me; theX, theY : Real from Standard; - theMin, theMax : out Real from Standard) - is virtual protected; - ---Level: Internal - ---Purpose: Returns global depth clipping limits applied to every sensitive. - -- Override this method to convert clippings defined by application into - -- selection space for mouse picking detection. - -- Default implementation returns infinite clip limits (no clipping). - -- @param theX [in] the x picking coordinate. - -- @param theY [in] the y picking coordinate. - -- @param theMin [out] the minimum depth. Default is RealFirst() - -- @param theMax [out] the maximum depth. Default is RealLast() - - DepthClipping (me; theX, theY : Real from Standard; - theOwner : EntityOwner from SelectMgr; - theMin, theMax : out Real from Standard) - is virtual protected; - ---Level: Internal - ---Purpose: Returns depth clipping limits applied to sensitives of - -- entity owner. Override this method to convert clippings defined by - -- application owners into selection space for mouse picking detection. - -- Default implementation returns infinite clip limits (no clipping). - -- @param theX [in] the x picking coordinate. - -- @param theY [in] the y picking coordinate. - -- @param theOwner [in] the sensitive owner. - -- @param theMin [out] the minimum depth. Default is RealFirst() - -- @param theMax [out] the maximum depth. Default is RealLast() - - HasDepthClipping (me; theOwner : EntityOwner from SelectMgr) - returns Boolean is virtual protected; - ---Level: Internal - ---Purpose: Returns True if the owner provides clipping by depth - -- for its sensitives. Override this method to tell the selector - -- to use the DepthClipping method for the owner. - -- Default implementation returns False for every owner. - -- @param theOwner [in] the onwer to check. - -- @return True if owner provides depth limits for sensitive clipping. - - LastPickingArguments(me) returns PickArgs from SelectBasics; - ---C++: inline - ---C++: return const& - -- Return last picking arguments. - -fields - ---before selection - myentities : DataMapOfIntegerSensitive is protected; - myselections : DataMapOfSelectionActivation is protected; - toupdate : Boolean is protected; - tosort : Boolean is protected; - preferclosest: Boolean is protected; ---for selection - mytolerance : Real is protected; - myselector : SortAlgo from SelectBasics is protected; - myclip : Box2d from Bnd is protected; - myactivenb : Integer; ---after selection -results... we sort the list of indexes not the map... - mystored : IndexedDataMapOfOwnerCriterion from SelectMgr is protected; - myIndexes : HArray1OfInteger from TColStd; - myprim : SequenceOfInteger from TColStd; -- for debug only - myCurRank : Integer from Standard; - - myLastPickArgs : PickArgs from SelectBasics; - lastx : Real; - lasty : Real; - - myUpdateSortPossible : Boolean from Standard; - -friends - class SelectionManager from SelectMgr - -end ViewerSelector; - - - - - - - - - - - - diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 31210be3d2..9190f3bf45 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -18,27 +18,26 @@ // ROB JAN/07/98 : Improve Storage of detected entities // AGV OCT/23/03 : Optimize the method SortResult() (OCC4201) -#include -#include -#include +#include #include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (SelectMgr_ViewerSelector, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared) static Standard_Boolean SelectDebugModeOnVS() { @@ -52,45 +51,90 @@ static Standard_Boolean SelectDebugModeOnVS() return ( isDebugMode != 0 ); } -namespace +SelectMgr_ToleranceMap::SelectMgr_ToleranceMap() { - // container to store depth limits in collection map - struct SelectMgr_DepthRange + myLargestKey = -1; +} + +SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap() +{ + myTolerances.Clear(); +} + +void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance) +{ + if (myTolerances.IsBound (theTolerance)) { - Standard_Real DepthMin; - Standard_Real DepthMax; - Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); } + Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); + aFreq++; - void Common (const SelectMgr_DepthRange& theOther) + if (theTolerance == myLargestKey) + return; + + Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey); + if (aFreq >= aMaxFreq) { - if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin) - { - DepthMin = RealFirst(); - DepthMax = RealLast(); - return; - } - - DepthMin = Max (DepthMin, theOther.DepthMin); - DepthMax = Min (DepthMax, theOther.DepthMax); + myLargestKey = aFreq == aMaxFreq ? Max (myLargestKey, theTolerance) : theTolerance; } - }; -}; + } + else + { + if (myTolerances.IsEmpty()) + { + myTolerances.Bind (theTolerance, 1); + myLargestKey = theTolerance; + return; + } + + myTolerances.Bind (theTolerance, 1); + Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey); + if (aMaxFreq <= 1) + { + myLargestKey = aMaxFreq == 1 ? Max (myLargestKey, theTolerance) : theTolerance; + } + } +} + +void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance) +{ + if (myTolerances.IsBound (theTolerance)) + { + Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); + aFreq--; + + if (theTolerance == myLargestKey) + { + Standard_Integer aMaxFreq = aFreq; + for (NCollection_DataMap::Iterator anIter (myTolerances); anIter.More(); anIter.Next()) + { + if (aMaxFreq <= anIter.Value() && myLargestKey != anIter.Key()) + { + aMaxFreq = anIter.Value(); + myLargestKey = anIter.Key(); + } + } + } + } +} + +const Standard_Real SelectMgr_ToleranceMap::Largest() +{ + return myLargestKey; +} //================================================== // Function: Initialize // Purpose : //================================================== SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): -toupdate(Standard_True), -tosort(Standard_True), preferclosest(Standard_True), -mytolerance(0.), -myCurRank(0), -myLastPickArgs (0.0, 0.0, 0.0, RealFirst(), RealLast(), gp_Lin()), -lastx (Precision::Infinite()), -lasty (Precision::Infinite()), -myUpdateSortPossible( Standard_True ) +mytolerance(2.0), +myToUpdateTolerance (Standard_True), +myCurRank (0), +myIsLeftChildQueuedFirst (Standard_False), +myEntityIdx (0) { + mySelectableObjects = new SelectMgr_SelectableObjectSet(); } @@ -98,22 +142,18 @@ myUpdateSortPossible( Standard_True ) // Function: Activate // Purpose : //================================================== -void SelectMgr_ViewerSelector:: -Activate (const Handle(SelectMgr_Selection)& aSelection, - const Standard_Boolean AutomaticProj) +void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection) { - tosort = Standard_True; + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + theSelection->Sensitive()->SetActiveForSelection(); + } - if (!myselections.IsBound(aSelection)) - { - myselections.Bind(aSelection,0); - } - else if (myselections(aSelection)!=0) - { - myselections(aSelection)= 0; - } - if(AutomaticProj) - Convert(aSelection); + theSelection->SetSelectionState (SelectMgr_SOS_Activated); + + myTolerances.Add (theSelection->Sensitivity()); + mytolerance = myTolerances.Largest(); + myToUpdateTolerance = Standard_True; } @@ -121,409 +161,242 @@ Activate (const Handle(SelectMgr_Selection)& aSelection, // Function: Deactivate // Purpose : //================================================== -void SelectMgr_ViewerSelector:: -Deactivate (const Handle(SelectMgr_Selection)& aSel) +void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection) { - if(myselections.IsBound(aSel)) - {myselections(aSel)=1; - tosort = Standard_True;} -} - - - - - -//================================================== -// Function: Sleep -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::Sleep() -{ SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); -for (;It.More();It.Next()){ - if(It.Value()==0) myselections(It.Key())= 2; -} -UpdateSort(); -} -//======================================================================= -//function : Sleep -//purpose : -//======================================================================= - -void SelectMgr_ViewerSelector::Sleep(const Handle(SelectMgr_SelectableObject)& SO) -{ - - for(SO->Init();SO->More();SO->Next()){ - if(myselections.IsBound(SO->CurrentSelection())){ - myselections(SO->CurrentSelection()) = 2; - } - } - UpdateSort(); -} - - -//================================================== -// Function: Awake -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::Awake(const Standard_Boolean AutomaticProj) -{ - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); - for (;It.More();It.Next()){ - if(It.Value()==2) - myselections(It.Key())=0; - if(AutomaticProj) - UpdateConversion(); - UpdateSort(); - } -} - -void SelectMgr_ViewerSelector::Awake(const Handle(SelectMgr_SelectableObject)& SO, - const Standard_Boolean AutomaticProj) -{ - for(SO->Init();SO->More();SO->Next()){ - if(myselections.IsBound(SO->CurrentSelection())){ - myselections(SO->CurrentSelection()) =0; - if(AutomaticProj) - Convert(SO->CurrentSelection()); - } + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + theSelection->Sensitive()->ResetSelectionActiveStatus(); } + theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); + + myTolerances.Decrement (theSelection->Sensitivity()); + mytolerance = myTolerances.Largest(); + myToUpdateTolerance = Standard_True; } + //================================================== // Function: Clear // Purpose : //================================================== void SelectMgr_ViewerSelector::Clear() { - myentities.Clear(); - myselections.Clear(); - toupdate = Standard_True; - tosort = Standard_True; mystored.Clear(); - lastx = Precision::Infinite(); - lasty = Precision::Infinite(); - + myMapOfDetected.Clear(); } -//================================================== -// Function: UpdateConversion -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::UpdateConversion() +//======================================================================= +// function: checkOverlap +// purpose : Internal function that checks if a particular sensitive +// entity theEntity overlaps current selecting volume precisely +//======================================================================= +void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity, + const Standard_Integer theEntityIdx, + SelectMgr_SelectingVolumeManager& theMgr) { - if( SelectDebugModeOnVS() ) - cout<<"\t\t\t\t\t SelectMgr_VS::UpdateConversion"<OwnerId()); - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); - for(;It.More();It.Next()){ - //Convert only if active... - if(It.Value()==0) - Convert(It.Key()); + SelectBasics_PickResult aPickResult; + if (theEntity->Matches (theMgr, aPickResult)) + { + if (!anOwner.IsNull()) + { + Standard_Boolean isPointSelection = + theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point; + if (HasDepthClipping (anOwner) && isPointSelection) + { + Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(), + aPickResult.Depth()); + if (isClipped) + return; + } + + Standard_Integer aPriority = anOwner->Priority(); + + SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest); + if (mystored.Contains (anOwner)) + { + if (theMgr.GetActiveSelectionType() != 1) + { + SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner); + if (aCriterion > aPrevCriterion) + { + aPrevCriterion = aCriterion; + myMapOfDetected.ChangeFind (anOwner) = theEntityIdx; + } + } + } + else + { + mystored.Add (anOwner, aCriterion); + myMapOfDetected.Bind (anOwner, theEntityIdx); + } + } } - toupdate = Standard_False; - tosort = Standard_True; } - -//================================================== -// Function: Convert -// Purpose : -//================================================== -void SelectMgr_ViewerSelector:: -Convert (const Handle(SelectMgr_Selection)& /*aSel*/) {tosort=Standard_True;} - - -//================================================== -// Function: UpdateSort -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::UpdateSort() +//======================================================================= +// function: traverseObject +// purpose : Internal function that checks if there is possible overlap +// between some entity of selectable object theObject and +// current selecting volume +//======================================================================= +void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject) { - if( !myUpdateSortPossible ) + NCollection_Handle& anEntitySet = + myMapOfObjectSensitives.ChangeFind (theObject); + + if (anEntitySet->Size() == 0) return; - if( SelectDebugModeOnVS() ) - cout<<"\t\t\t\t\t SelectMgr_ViewerSelector::UpdateSort()"< >& aSensitivesTree = anEntitySet->BVH(); - if(myactivenb > 0) { - Standard_Boolean NoClip = myclip.IsVoid(); - Handle(Bnd_HArray1OfBox2d) refToTab = new Bnd_HArray1OfBox2d(1,myactivenb); - Bnd_Array1OfBox2d & tab = refToTab->ChangeArray1(); - Standard_Real xmin=Precision::Infinite(),ymin=Precision::Infinite(),xmax=-Precision::Infinite(),ymax=-Precision::Infinite(); - Standard_Real curxmin,curymin,curxmax,curymax; - // Standard_Integer boxindex=0,indexsel=0,indexprim=0; - Standard_Integer boxindex=0; + SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ? + mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr; - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It; - SelectBasics_ListIteratorOfListOfBox2d LIt; - Handle(SelectMgr_Selection) curEntity; - Standard_Real ScaleFactor; - for(It.Initialize(myselections);It.More();It.Next()){ - if(It.Value()== 0) - { curEntity = It.Key(); - for(curEntity->Init();curEntity->More();curEntity->Next()) - { - static SelectBasics_ListOfBox2d BoxList; - BoxList.Clear(); - curEntity->Sensitive()->Areas(BoxList); - ScaleFactor = curEntity->Sensitive()->SensitivityFactor(); - - - for(LIt.Initialize(BoxList);LIt.More();LIt.Next()){ - boxindex++; - - tab.SetValue(boxindex,LIt.Value()); - - tab(boxindex).SetGap(mytolerance*ScaleFactor); - myentities.Bind(boxindex,curEntity->Sensitive()); - if(NoClip){ - if (!tab(boxindex).IsVoid()) { - tab(boxindex).Get(curxmin,curymin,curxmax,curymax); - if(curxminxmax) xmax=curxmax; - if(curyminymax) ymax=curymax; - } - } - } - } - } - } - - - if(NoClip) {myclip.SetVoid();myclip.Update(xmin,ymin,xmax,ymax);} - myselector.Initialize(myclip, mytolerance,refToTab); - tosort = Standard_False; - if(NoClip) myclip.SetVoid(); - } -} - - -//================================================== -// Function: Remove -// Purpose : -//================================================== -void SelectMgr_ViewerSelector:: -Remove(const Handle(SelectMgr_Selection)& aSel) -{ - if (myselections.IsBound(aSel)) - { myselections.UnBind(aSel); - tosort = Standard_True; - } -} - -//================================================== -// Function: SetSensitivity -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::SetSensitivity(const Standard_Real aVal) -{mytolerance = aVal; -tosort=Standard_True;} - -//================================================== -// Function: SetClipping -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::SetClipping(const Standard_Real Xc, - const Standard_Real Yc, - const Standard_Real Height, - const Standard_Real Width) -{ - Bnd_Box2d aClip; - aClip.Set(gp_Pnt2d(Xc-Width/2, Yc-Height/2)); - aClip.Add(gp_Pnt2d(Xc+Width/2, Yc+Height/2)); - myclip = aClip; - tosort = Standard_True; -} - - -//================================================== -// Function: SetClipping -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::SetClipping (const Bnd_Box2d& abox) -{myclip = abox; -tosort = Standard_True; -} - -//================================================== -// Function: InitSelect -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xr, - const Standard_Real Yr) -{ - Standard_OutOfRange_Raise_if(Abs(Xr-Precision::Infinite())<=Precision::Confusion() || - Abs(Yr-Precision::Infinite())<=Precision::Confusion(), - " Infinite values in IniSelect"); - mystored.Clear(); - myprim.Clear(); - if (toupdate) UpdateConversion(); - if (tosort) UpdateSort(); - if(myactivenb!=0){ - myselector.InitSelect(Xr,Yr); - if(myselector.More()) {lastx = Xr;lasty=Yr;} - LoadResult(); - } -} - -//================================================== -// Function: InitSelect -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::InitSelect(const Bnd_Box2d& aBox) -{ - mystored.Clear(); - if(toupdate) UpdateConversion(); - if (tosort) UpdateSort(); - if (myactivenb!=0){ - myselector.InitSelect(aBox); - LoadResult(aBox); - } -} - -//================================================== -// Function: InitSelect -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xmin, - const Standard_Real Ymin, - const Standard_Real Xmax, - const Standard_Real Ymax) -{ - mystored.Clear(); - - if (toupdate) UpdateConversion(); - if (tosort) UpdateSort(); - if (myactivenb!=0){ - Bnd_Box2d aBox; - aBox.Update(Xmin,Ymin,Xmax,Ymax); - myselector.InitSelect(aBox); - LoadResult(aBox); - } -} - -//================================================== -// Function: InitSelect -// Purpose : Polyline Selection -//================================================== -void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly) -{ - mystored.Clear(); - - if (toupdate) UpdateConversion(); - if (tosort) UpdateSort(); - if (myactivenb!=0){ - // the Bnd boxes are used for the first time - Bnd_Box2d aBox; - Standard_Integer NbPnt = aPoly.Length(); - Standard_Integer i; - for(i=1;i<=NbPnt;i++) { - aBox.Update(aPoly(i).X(),aPoly(i).Y()); - } - myselector.InitSelect(aBox); - LoadResult(aPoly); - // LoadResult(aBox); - } -} - - -//================================================== -// Function: LoadResult -// Purpose : for the moment the size of the primitive -// is not taken into account in the search criteriai... -// The priority, the depth and the min. distance to CDG or Borders is taken... -//================================================== -void SelectMgr_ViewerSelector::LoadResult() -{ - if (myselector.More()) + Standard_Integer aNode = 0; // a root node + if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0), + aSensitivesTree->MaxPoint (0))) { - NCollection_DataMap aMapOfOwnerRanges; - - // collect information on depth clipping from implementations - gp_Lin aPickLine = PickingLine (lastx, lasty); - SelectMgr_DepthRange aViewDRange; - DepthClipping (lastx, lasty, aViewDRange.DepthMin, aViewDRange.DepthMax); - - Standard_Real aDMin; - Standard_Real aDepthMin; - Standard_Integer aNument; - - if (!aViewDRange.IsEmpty()) + return; + } + Standard_Integer aStack[32]; + Standard_Integer aHead = -1; + for (;;) + { + if (!aSensitivesTree->IsOuter (aNode)) { - for (; myselector.More(); myselector.Next()) + const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode); + const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode); + const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx), + aSensitivesTree->MaxPoint (aLeftChildIdx)); + const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx), + aSensitivesTree->MaxPoint (aRightChildIdx)); + if (isLeftChildIn + && isRightChildIn) { - aNument = myselector.Value(); - - const Handle(SelectBasics_SensitiveEntity)& SE = myentities (aNument); - const Handle(SelectMgr_EntityOwner)& anOwner = - Handle(SelectMgr_EntityOwner)::DownCast (SE->OwnerId()); - - // compute depth range for sensitives of entity owner - SelectMgr_DepthRange anEntityDRange (aViewDRange); - if (!anOwner.IsNull() && HasDepthClipping (anOwner) && !aMapOfOwnerRanges.Find (anOwner, anEntityDRange)) + aNode = aLeftChildIdx; + ++aHead; + aStack[aHead] = aRightChildIdx; + } + else if (isLeftChildIn + || isRightChildIn) + { + aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + } + else + { + if (aHead < 0) { - // get depth range from implementation - SelectMgr_DepthRange aGetRange; - DepthClipping (lastx, lasty, anOwner, aGetRange.DepthMin, aGetRange.DepthMax); - - // concatenate and remember depth range for pefromance increase - anEntityDRange.Common (aGetRange); - aMapOfOwnerRanges.Bind (anOwner, anEntityDRange); + break; } - if (anEntityDRange.IsEmpty()) - { - continue; - } - - myLastPickArgs = SelectBasics_PickArgs (lastx, lasty, mytolerance, - anEntityDRange.DepthMin, - anEntityDRange.DepthMax, - aPickLine); - - if (SE->Matches (myLastPickArgs, aDMin, aDepthMin)) - { - if (!anOwner.IsNull()) - { - Standard_Integer aPrior = anOwner->Priority(); - - SelectMgr_SortCriterion SC (aPrior, aDepthMin, aDMin, mytolerance, preferclosest); - if (mystored.Contains (anOwner)) - { - SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey (anOwner); - if (SC > Crit) - { - Crit = SC; - - // update previously recorded entity for this owner - for (int i = 1; i <= myprim.Length(); i++) - { - if (myentities (myprim(i))->OwnerId() == anOwner) - { - myprim.SetValue (i, aNument); - break; - } - } - } - } - else - { - mystored.Add (anOwner, SC); - - // record entity - myprim.Append (aNument); - } - } - } + aNode = aStack[aHead]; + --aHead; } } + else + { + Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode); + Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode); + for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) + { + const SelectMgr_HSensitiveEntity& aSensitive = + anEntitySet->GetSensitiveById (anIdx); + if (aSensitive->IsActiveForSelection()) + { + checkOverlap (aSensitive->BaseSensitive(), anIdx, aMgr); + } + } + if (aHead < 0) + { + break; + } - SortResult(); + aNode = aStack[aHead]; + --aHead; + } } +} + +//======================================================================= +// function: TraverseSensitives +// purpose : Traverses BVH containing all added selectable objects and +// finds candidates for further search of overlap +//======================================================================= +void SelectMgr_ViewerSelector::TraverseSensitives() +{ + mystored.Clear(); + myMapOfDetected.Clear(); + + if (mySelectableObjects->Size() == 0) + return; + + const NCollection_Handle >& anObjectsTree = mySelectableObjects->BVH(); + + Standard_Integer aNode = 0; + if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0), + anObjectsTree->MaxPoint (0))) + { + return; + } + Standard_Integer aStack[32]; + Standard_Integer aHead = -1; + for (;;) + { + if (!anObjectsTree->IsOuter (aNode)) + { + const Standard_Integer aLeftChildIdx = anObjectsTree->LeftChild (aNode); + const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode); + const Standard_Boolean isLeftChildIn = + mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx), + anObjectsTree->MaxPoint (aLeftChildIdx)); + const Standard_Boolean isRightChildIn = + mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx), + anObjectsTree->MaxPoint (aRightChildIdx)); + if (isLeftChildIn + && isRightChildIn) + { + aNode = aLeftChildIdx; + ++aHead; + aStack[aHead] = aRightChildIdx; + } + else if (isLeftChildIn + || isRightChildIn) + { + aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + } + else + { + if (aHead < 0) + { + break; + } + + aNode = aStack[aHead]; + --aHead; + } + } + else + { + Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode); + Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode); + for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) + { + traverseObject (mySelectableObjects->GetObjectById (anIdx)); + } + if (aHead < 0) + { + break; + } + + aNode = aStack[aHead]; + --aHead; + } + } + + SortResult(); if (SelectDebugModeOnVS()) { @@ -540,117 +413,6 @@ void SelectMgr_ViewerSelector::LoadResult() } } -//================================================== -// Function: LoadResult -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox) -{ - mystored.Clear(); - - // Handle(SelectMgr_EntityOwner) OWNR; - if(myselector.More()) - { Standard_Real xmin,ymin,xmax,ymax; - abox.Get(xmin,ymin,xmax,ymax); - // Standard_Boolean Found(Standard_False); - // Standard_Real DMin=0.; - Standard_Integer nument; - for(;myselector.More();myselector.Next()){ - nument = myselector.Value(); - const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument); - if (SE->Matches(xmin,ymin,xmax,ymax,0.0)){ - const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId(); - if(!OWNR.IsNull()){ - if(!mystored.Contains(OWNR)){ - SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(), - Precision::Infinite(),mytolerance,preferclosest); - mystored.Add(OWNR,SC); - myprim.Append(nument); - } - } - } - } - - // do not parse in case of selection by elastic rectangle (BUG ANALYST) - if(mystored.IsEmpty()) return; - if(myIndexes.IsNull()) - myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); - else if(mystored.Extent() !=myIndexes->Length()) - myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); - - // to work faster... - TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); - for(Standard_Integer I=1;I<=mystored.Extent();I++) - thearr(I)=I; - } -} -//================================================== -// Function: LoadResult -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly) -{ - mystored.Clear(); - Bnd_Box2d aBox; - Standard_Integer NbPnt = aPoly.Length(); - Standard_Integer i; - for(i=1;i<=NbPnt;i++) { - aBox.Update(aPoly(i).X(),aPoly(i).Y()); - } - Standard_Integer NB=0; - // Handle(SelectMgr_EntityOwner) OWNR; - if(myselector.More()) - { - Standard_Integer nument; - - for(;myselector.More();myselector.Next()){ - NB++; - nument = myselector.Value(); - const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument); - if (SE->Matches(aPoly,aBox,0.0)){ - const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId(); - if(!OWNR.IsNull()){ - if(!mystored.Contains(OWNR)){ - SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(), - Precision::Infinite(),mytolerance,preferclosest); - mystored.Add(OWNR,SC); - myprim.Append(nument); - } - } - } - } - - if(mystored.IsEmpty()) return; - if(myIndexes.IsNull()) - myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); - else if(mystored.Extent() !=myIndexes->Length()) - myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); - - // to work faster... - TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); - for(Standard_Integer I=1;I<=mystored.Extent();I++) - thearr(I)=I; - } -} - - -//================================================== -// Function: HasStored -// Purpose : -//================================================== -Standard_Boolean SelectMgr_ViewerSelector:: -HasStored () -{ - if(Abs(lastx-Precision::Infinite())<=Precision::Confusion()) return Standard_False; - if(Abs(lasty-Precision::Infinite())<=Precision::Confusion()) return Standard_False; - InitSelect(lastx,lasty); - Init(); - return More(); -} - - - - //================================================== // Function: Picked // Purpose : @@ -658,7 +420,7 @@ HasStored () Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector ::Picked() const { - Standard_Integer RankInMap = myIndexes->Value(myCurRank); + Standard_Integer RankInMap = myIndexes->Value (myCurRank); const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap); Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto); return Ownr; @@ -689,7 +451,7 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector Init(); if(More()){ - Standard_Integer RankInMap = myIndexes->Value(1); + Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower()); const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap); Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto); return Ownr; @@ -716,36 +478,16 @@ Standard_Integer SelectMgr_ViewerSelector::NbPicked() const Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const { - Handle(SelectMgr_EntityOwner) Own; - if (aRank<1 || aRank>NbPicked()) - return Own; - Standard_Integer Indx = myIndexes->Value(aRank); + Handle(SelectMgr_EntityOwner) anOwner; + if (aRank < 1 || aRank > NbPicked()) + return anOwner; + Standard_Integer anOwnerIdx = myIndexes->Value (aRank); - const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(Indx); - Own = *((Handle(SelectMgr_EntityOwner)*) &toto); - return Own; + const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx); + anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner); + return anOwner; } -//======================================================================= -//function : Primitive -//purpose : -//======================================================================= -Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive -(const Standard_Integer /*Index*/) const -{ - return myentities(myprim(myCurRank)); -} - - -//================================================== -// Function: LastPosition -// Purpose : -//================================================== -void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast, - Standard_Real& YLast) const -{ Xlast = lastx;YLast = lasty;} - - //=================================================== // @@ -753,100 +495,78 @@ void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast, // //================================================== - - - -//================================================== -// Function: NbBoxes -// Purpose : -//================================================== -Standard_Integer SelectMgr_ViewerSelector::NbBoxes() -{ - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); - // Standard_Integer Nbb=0, first,last; - Standard_Integer Nbb=0; - - for(;It.More();It.Next()){ - if(It.Value()==0){ - for(It.Key()->Init();It.Key()->More();It.Key()->Next()) - {Nbb+= It.Key()->Sensitive()->MaxBoxes();} - } - } - return Nbb; -} - - - - //================================================== // Function: Contains // Purpose : //================================================== -Standard_Boolean SelectMgr_ViewerSelector:: -Contains(const Handle(SelectMgr_SelectableObject)& anObject) const +Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const { - for (anObject->Init();anObject->More();anObject->Next()){ - if(myselections.IsBound(anObject->CurrentSelection())) - return Standard_True; - } - return Standard_False; + return mySelectableObjects->Contains (theObject); } - - //================================================== // Function: ActiveModes // Purpose : return all the modes with a given state for an object //================================================== - - -Standard_Boolean SelectMgr_ViewerSelector:: -Modes(const Handle(SelectMgr_SelectableObject)& SO, - TColStd_ListOfInteger& TheActiveList, - const SelectMgr_StateOfSelection WantedState) const +Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + TColStd_ListOfInteger& theModeList, + const SelectMgr_StateOfSelection theWantedState) const { - Standard_Boolean Found= Standard_False; - for(SO->Init();SO->More();SO->Next()){ - if(myselections.IsBound(SO->CurrentSelection())){ - if(WantedState==SelectMgr_SOS_Any) - TheActiveList.Append(SO->CurrentSelection()->Mode()); - else if( myselections(SO->CurrentSelection())==WantedState) - TheActiveList.Append(SO->CurrentSelection()->Mode()); - - if(!Found) Found=Standard_True; - } + Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject); + for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) + { + if (theWantedState == SelectMgr_SOS_Any) + { + theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); + } + else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState()) + { + theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); + } } - return Found; + + return hasActivatedStates; } - -Standard_Boolean SelectMgr_ViewerSelector:: -IsActive(const Handle(SelectMgr_SelectableObject)& SO, - const Standard_Integer aMode) const +//================================================== +// Function: IsActive +// Purpose : +//================================================== +Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + const Standard_Integer theMode) const { - for(SO->Init();SO->More();SO->Next()){ - if(aMode==SO->CurrentSelection()->Mode()){ - if(myselections.IsBound(SO->CurrentSelection()) && - myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated) - return Standard_True; - else return Standard_False; + if (!mySelectableObjects->Contains (theSelectableObject)) + return Standard_False; + + for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) + { + if (theMode == theSelectableObject->CurrentSelection()->Mode()) + { + return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated; } } + return Standard_False; } - -Standard_Boolean SelectMgr_ViewerSelector:: -IsInside(const Handle(SelectMgr_SelectableObject)& SO, - const Standard_Integer aMode) const +//================================================== +// Function: IsInside +// Purpose : +//================================================== +Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + const Standard_Integer theMode) const { - for(SO->Init();SO->More();SO->Next()){ - if(aMode==SO->CurrentSelection()->Mode()){ - if(myselections.IsBound(SO->CurrentSelection())) return Standard_True; - else return Standard_False; + if (!mySelectableObjects->Contains (theSelectableObject)) + return Standard_False; + for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) + { + if (theMode == theSelectableObject->CurrentSelection()->Mode()) + { + return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown; } } + return Standard_False; } @@ -856,90 +576,44 @@ IsInside(const Handle(SelectMgr_SelectableObject)& SO, //purpose : //======================================================================= -SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const +SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const { - if(!myselections.IsBound(aSel)) return SelectMgr_SOS_Unknown; - //JR/Hp - Standard_Integer ie = myselections(aSel) ; - return SelectMgr_StateOfSelection( ie ); - // return SelectMgr_StateOfSelection(myselections(aSel)); - + return theSelection->GetSelectionState(); } - - -//======================================================================= -//function : Dump -//purpose : -//======================================================================= - -void SelectMgr_ViewerSelector::Dump(Standard_OStream& S) const -{ - S<<"=========================="<Init();SO->More();SO->Next()){ - if(myselections.IsBound(SO->CurrentSelection())) - { - Found = Standard_True; - Status = Status + "Mode " + - TCollection_AsciiString(SO->CurrentSelection()->Mode()) + - " present - " ; - if(myselections(SO->CurrentSelection())) - Status = Status + " Active \n\t"; - else - Status = Status + " Inactive \n\t"; - } - } + TCollection_AsciiString aStatus ("Status Object :\n\t"); - if(!Found) Status = Status + "Not Present in the selector\n\n"; - return Status; -} - - -TCollection_AsciiString SelectMgr_ViewerSelector:: -Status () const -{ - // sevsitive primitives present - //----------------------------- - TCollection_AsciiString Status("\t\tSelector Status :\n\t"); - // selections - //----------- - Standard_Integer NbActive =0,NbPrim=0; - Status = Status + "Number of already computed selections : " + - TCollection_AsciiString(myselections.Extent()); - - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); - for(;It.More();It.Next()) + for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) { - if(It.Value()==0) {NbActive++; - for(It.Key()->Init();It.Key()->More();It.Key()->Next()){NbPrim++;} + if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown) + { + aStatus = aStatus + "Mode " + + TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) + + " present - "; + if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) + { + aStatus = aStatus + " Active \n\t"; + } + else + { + aStatus = aStatus + " Inactive \n\t"; + } } } - Status = Status + " - " + TCollection_AsciiString(NbActive) + " activated ones\n\t"; - Status = Status + "Number of active sensitive primitives : " + - TCollection_AsciiString(NbPrim)+"\n\t"; - Status = Status + "Real stored Pick Tolerance : " + TCollection_AsciiString(mytolerance) +"\n\t"; - if(toupdate) { - Status = Status + "\nWARNING : those informations will be obsolete for the next Pick\n" - +"to get the real status of the selector - make One pick and call Status again\n"; + + if (mySelectableObjects->Contains (theSelectableObject)) + { + aStatus = aStatus + "Not Present in the selector\n\n"; } - return Status; + + return aStatus; } //======================================================================= @@ -968,104 +642,8 @@ void SelectMgr_ViewerSelector::SortResult() for (I=1; I <= anExtent; I++) thearr(I)=I; - // OCC4201 (AGV): This loop is inefficient on large arrays, so I replace it - // with a standard sort algo - // // on trie suivant les criteres (i) (Owner) (SortCriterion) - // Standard_Boolean OKSort; - // Standard_Integer temp,indx,indx1; - // Standard_Integer tmprim; - // // merci lbr... - // do{ - // OKSort =Standard_True; - // for(I=1;I 0 && ind <= myPrimArr.Upper()) - myprim (I) = myPrimArr (ind); - } - // OCC4201 (AGV): fin - // it is enough to return owners corresponding to parced indices... - -} - - -//======================================================================= -//function : -//purpose : -//======================================================================= -Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const -{ - return myUpdateSortPossible; -} - -//======================================================================= -//function : -//purpose : -//======================================================================= -void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible ) -{ - myUpdateSortPossible = possible; -} - -//======================================================================= -//function : PickingLine -//purpose : Stub -//======================================================================= -gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/, - const Standard_Real /*theY*/) const -{ - return gp_Lin(); -} - -//======================================================================= -//function : DepthClipping -//purpose : Stub -//======================================================================= -void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/, - const Standard_Real /*theY*/, - Standard_Real& theMin, - Standard_Real& theMax) const -{ - theMin = RealFirst(); - theMax = RealLast(); -} - -//======================================================================= -//function : DepthClipping -//purpose : Stub -//======================================================================= -void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/, - const Standard_Real /*theY*/, - const Handle(SelectMgr_EntityOwner)& /*theOwner*/, - Standard_Real& theMin, - Standard_Real& theMax) const -{ - theMin = RealFirst(); - theMax = RealLast(); } //======================================================================= @@ -1076,3 +654,159 @@ Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(Select { return Standard_False; } + +//======================================================================= +// function : AddSelectableObject +// purpose : Adds new object to the map of selectable objects +//======================================================================= +void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) +{ + if (!myMapOfObjectSensitives.IsBound (theObject)) + { + mySelectableObjects->Append (theObject); + NCollection_Handle anEntitySet = new SelectMgr_SensitiveEntitySet(); + myMapOfObjectSensitives.Bind (theObject, anEntitySet); + } +} + +//======================================================================= +// function : AddSelectionToObject +// purpose : Adds new selection to the object and builds its BVH tree +//======================================================================= +void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_Selection)& theSelection) +{ + if (myMapOfObjectSensitives.IsBound (theObject)) + { + NCollection_Handle& anEntitySet = + myMapOfObjectSensitives.ChangeFind (theObject); + anEntitySet->Append (theSelection); + anEntitySet->BVH(); + } + else + { + AddSelectableObject (theObject); + AddSelectionToObject (theObject, theSelection); + } +} + +//======================================================================= +// function : RemoveSelectableObject +// purpose : Removes selectable object from map of selectable ones +//======================================================================= +void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) +{ + if (myMapOfObjectSensitives.IsBound (theObject)) + { + myMapOfObjectSensitives.UnBind (theObject); + mySelectableObjects->Remove (theObject); + } +} + +//======================================================================= +// function : RemoveSelectionOfObject +// purpose : Removes selection of the object and marks its BVH tree +// for rebuild +//======================================================================= +void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_Selection)& theSelection) +{ + if (myMapOfObjectSensitives.IsBound (theObject)) + { + NCollection_Handle& anEntitySet = + myMapOfObjectSensitives.ChangeFind (theObject); + anEntitySet->Remove (theSelection); + } +} + +//======================================================================= +// function : RebuildObjectsTree +// purpose : Marks BVH of selectable objects for rebuild +//======================================================================= +void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce) +{ + mySelectableObjects->MarkDirty(); + + if (theIsForce) + { + mySelectableObjects->BVH(); + } +} + +//======================================================================= +// function : RebuildSensitivesTree +// purpose : Marks BVH of sensitive entities of particular selectable +// object for rebuild +//======================================================================= +void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Boolean theIsForce) +{ + if (!mySelectableObjects->Contains (theObject)) + return; + + NCollection_Handle& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); + anEntitySet->MarkDirty(); + + if (theIsForce) + { + anEntitySet->BVH(); + } +} + +//======================================================================= +// function : resetSelectionActivationStatus +// purpose : Marks all added sensitive entities of all objects as +// non-selectable +//======================================================================= +void SelectMgr_ViewerSelector::resetSelectionActivationStatus() +{ + SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); + for ( ; aSensitivesIter.More(); aSensitivesIter.Next()) + { + NCollection_Handle& anEntitySet = + aSensitivesIter.ChangeValue(); + Standard_Integer anEntitiesNb = anEntitySet->Size(); + for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) + { + anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus(); + } + } +} + +//======================================================================= +// function : DetectedEntity +// purpose : Returns sensitive entity that was detected during the +// previous run of selection algorithm +//======================================================================= +const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const +{ + const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key(); + const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable(); + const NCollection_Handle& anEntitySet = + myMapOfObjectSensitives.Find (anObject); + + return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive(); +} + +//======================================================================= +// function : ActiveOwners +// purpose : Returns the list of active entity owners +//======================================================================= +NCollection_List SelectMgr_ViewerSelector::ActiveOwners() const +{ + NCollection_List anActiveOwners; + for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next()) + { + const NCollection_Handle& anEntitySet = anIter.Value(); + Standard_Integer anEntitiesNb = anEntitySet->Size(); + for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) + { + if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection()) + { + anActiveOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId()); + } + } + } + + return anActiveOwners; +} diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.hxx b/src/SelectMgr/SelectMgr_ViewerSelector.hxx new file mode 100644 index 0000000000..ed28c9f874 --- /dev/null +++ b/src/SelectMgr/SelectMgr_ViewerSelector.hxx @@ -0,0 +1,292 @@ +// Created on: 1995-02-15 +// Created by: Roberc Coublanc +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Modified by ... +// ROB JAN/07/98 : Improve Storage of detected entities +// AGV OCT/23/03 : Optimize the method SortResult() (OCC4201) + +#ifndef _SelectMgr_ViewerSelector_HeaderFile +#define _SelectMgr_ViewerSelector_HeaderFile + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TColStd_HArray1OfInteger; +class SelectMgr_SelectionManager; +class SelectMgr_Selection; +class SelectMgr_SensitiveEntitySet; +class SelectMgr_EntityOwner; +class TColStd_ListOfInteger; +class TCollection_AsciiString; +class SelectBasics_SensitiveEntity; +class SelectMgr_SelectableObjectSet; + +typedef NCollection_DataMap > SelectMgr_MapOfObjectSensitives; +typedef NCollection_DataMap >::Iterator SelectMgr_MapOfObjectSensitivesIterator; + +typedef NCollection_DataMap SelectMgr_MapOfOwnerDetectedEntities; +typedef NCollection_DataMap::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator; + +class SelectMgr_ToleranceMap +{ +public: + + SelectMgr_ToleranceMap(); + + Standard_EXPORT ~SelectMgr_ToleranceMap(); + + Standard_EXPORT void Add (const Standard_Real& theTolerance); + + Standard_EXPORT void Decrement (const Standard_Real& theTolerance); + + Standard_EXPORT const Standard_Real Largest(); + +private: + NCollection_DataMap myTolerances; + Standard_Real myLargestKey; +}; + +//! A framework to define finding, sorting the sensitive +//! primitives in a view. Services are also provided to +//! define the return of the owners of those primitives +//! selected. The primitives are sorted by criteria such +//! as priority of the primitive or its depth in the view +//! relative to that of other primitives. +//! Note that in 3D, the inheriting framework +//! StdSelect_ViewerSelector3d is only to be used +//! if you do not want to use the services provided by +//! AIS. +//! Two tools are available to find and select objects +//! found at a given position in the view. If you want to +//! select the owners of all the objects detected at +//! point x,y,z you use the Init - More - Next - Picked +//! loop. If, on the other hand, you want to select only +//! one object detected at that point, you use the Init - +//! More - OnePicked loop. In this iteration, More is +//! used to see if an object was picked and +//! OnePicked, to get the object closest to the pick position. +//! Viewer selectors are driven by +//! SelectMgr_SelectionManager, and manipulate +//! the SelectMgr_Selection objects given to them by +//! the selection manager. +class SelectMgr_ViewerSelector : public MMgt_TShared +{ +public: + + //! Empties all the tables, removes all selections... + Standard_EXPORT void Clear(); + + //! returns the Sensitivity of picking + Standard_Real Sensitivity() const; + + //! Sorts the detected entites by priority and distance. + //! to be redefined if other criterion are used... + Standard_EXPORT void SortResult(); + + //! Begins an iteration scanning for the owners detected at a position in the view. + void Init(); + + //! Continues the interation scanning for the owners + //! detected at a position in the view, or + //! - continues the iteration scanning for the owner + //! closest to the position in the view. + Standard_EXPORT Standard_Boolean More(); + + //! Returns the next owner found in the iteration. This is + //! a scan for the owners detected at a position in the view. + void Next(); + + //! Returns the current selected entity detected by the selector; + Standard_EXPORT Handle_SelectMgr_EntityOwner Picked() const; + + //! Returns the picked element with the highest priority, + //! and which is the closest to the last successful mouse position. + Standard_EXPORT Handle_SelectMgr_EntityOwner OnePicked(); + + //! Set preference of selecting one object for OnePicked() method: + //! - If True, objects with less depth (distance fron the view plane) are + //! preferred regardless of priority (priority is used then to choose among + //! objects with similar depth), + //! - If False, objects with higher priority are preferred regardless of the + //! depth which is used to choose among objects of the same priority. + void SetPickClosest (const Standard_Boolean preferClosest); + + //! Returns the number of owners found at a position in + //! the view by the Init - More - Next - Picked iteration. + Standard_EXPORT Standard_Integer NbPicked() const; + + //! Returns the entity which is at rank + //! in the list of stored ones. + Standard_EXPORT Handle_SelectMgr_EntityOwner Picked (const Standard_Integer aRank) const; + + Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const; + + //! Returns the list of selection modes ModeList found in + //! this selector for the selectable object aSelectableObject. + //! Returns true if aSelectableObject is referenced inside + //! this selector; returns false if the object is not present + //! in this selector. + Standard_EXPORT Standard_Boolean Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + TColStd_ListOfInteger& theModeList, + const SelectMgr_StateOfSelection theWantedState = SelectMgr_SOS_Any) const; + + //! Returns true if the selectable object + //! aSelectableObject having the selection mode aMode + //! is active in this selector. + Standard_EXPORT Standard_Boolean IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + const Standard_Integer theMode) const; + + //! Returns true if the selectable object + //! aSelectableObject having the selection mode aMode + //! is in this selector. + Standard_EXPORT Standard_Boolean IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject, + const Standard_Integer theMode) const; + + //! Returns the selection status Status of the selection aSelection. + Standard_EXPORT SelectMgr_StateOfSelection Status (const Handle(SelectMgr_Selection)& theSelection) const; + + Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const; + + //! Returns the list of active entity owners + Standard_EXPORT NCollection_List ActiveOwners() const; + + //! Adds new object to the map of selectable objects + Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject); + + //! Adds new selection to the object and builds its BVH tree + Standard_EXPORT void AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_Selection)& theSelection); + + //! Removes selectable object from map of selectable ones + Standard_EXPORT void RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject); + + //! Removes selection of the object and marks its BVH tree for rebuild + Standard_EXPORT void RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject, + const Handle(SelectMgr_Selection)& theSelection); + + //! Marks BVH of selectable objects for rebuild. Parameter theIsForce set as true + //! guarantees that 1st level BVH for the viewer selector will be rebuilt during this call + Standard_EXPORT void RebuildObjectsTree (const Standard_Boolean theIsForce = Standard_False); + + //! Marks BVH of sensitive entities of particular selectable object for rebuild. Parameter + //! theIsForce set as true guarantees that 2nd level BVH for the object given will be + //! rebuilt during this call + Standard_EXPORT void RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, + const Standard_Boolean theIsForce = Standard_False); + + //! Initializes internal iterator for stored detected sensitive entities + Standard_EXPORT void InitDetected(); + + //! Makes a step along the map of detected sensitive entities and their owners + Standard_EXPORT void NextDetected(); + + //! Returns true if iterator of map of detected sensitive entities has reached + //! its end + Standard_EXPORT Standard_Boolean MoreDetected(); + + //! Returns sensitive entity that was detected during the previous run of + //! selection algorithm + Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const; + + //! Returns instance of selecting volume manager of the viewer selector + Standard_EXPORT SelectMgr_SelectingVolumeManager& GetManager(); + + friend class SelectMgr_SelectionManager; + + DEFINE_STANDARD_RTTI(SelectMgr_ViewerSelector) + +protected: + + Standard_EXPORT SelectMgr_ViewerSelector(); + + //! Traverses BVH containing all added selectable objects and + //! finds candidates for further search of overlap + Standard_EXPORT void TraverseSensitives(); + + //! Returns True if the owner provides clipping by depth + //! for its sensitives. Override this method to tell the selector + //! to use the DepthClipping method for the owner. + //! Default implementation returns False for every owner. + //! @param theOwner [in] the onwer to check. + //! @return True if owner provides depth limits for sensitive clipping. + Standard_EXPORT virtual Standard_Boolean HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const; + + //! Internal function that checks if there is possible overlap + //! between some entity of selectable object theObject and + //! current selecting volume + void traverseObject (const Handle(SelectMgr_SelectableObject)& theObject); + + //! Internal function that checks if a particular sensitive + //! entity theEntity overlaps current selecting volume precisely + void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity, + const Standard_Integer theEntityIdx, + SelectMgr_SelectingVolumeManager& theMgr); + + //! Marks all added sensitive entities of all objects as non-selectable + void resetSelectionActivationStatus(); + +private: + + void Activate (const Handle(SelectMgr_Selection)& theSelection); + + void Deactivate (const Handle(SelectMgr_Selection)& theSelection); + + //! removes a Selection from the Selector + void Remove (const Handle(SelectMgr_Selection)& aSelection); + +protected: + + Standard_Boolean preferclosest; + Standard_Real mytolerance; + Standard_Boolean myToUpdateTolerance; + SelectMgr_IndexedDataMapOfOwnerCriterion mystored; + SelectMgr_SelectingVolumeManager mySelectingVolumeMgr; + mutable NCollection_Handle mySelectableObjects; + SelectMgr_ToleranceMap myTolerances; + +private: + + Handle_TColStd_HArray1OfInteger myIndexes; + Standard_Integer myCurRank; + Standard_Boolean myIsLeftChildQueuedFirst; + Standard_Integer myEntityIdx; + SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives; + SelectMgr_MapOfOwnerDetectedEntities myMapOfDetected; + SelectMgr_MapOfOwnerDetectedEntitiesIterator myDetectedIter; +}; + +DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, MMgt_TShared) + +#include + +#endif diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.lxx b/src/SelectMgr/SelectMgr_ViewerSelector.lxx index 6263e24c8d..3f9c99183a 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.lxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.lxx @@ -32,12 +32,22 @@ inline void SelectMgr_ViewerSelector::SetPickClosest (const Standard_Boolean pre preferclosest = preferClosest; } -inline const SelectBasics_PickArgs& SelectMgr_ViewerSelector::LastPickingArguments() const +inline void SelectMgr_ViewerSelector::InitDetected() { - return myLastPickArgs; + myDetectedIter.Initialize (myMapOfDetected); } -inline const SelectMgr_DataMapOfIntegerSensitive& SelectMgr_ViewerSelector::Primitives() const +inline void SelectMgr_ViewerSelector::NextDetected() { - return myentities; + myDetectedIter.Next(); +} + +inline Standard_Boolean SelectMgr_ViewerSelector::MoreDetected() +{ + return myDetectedIter.More(); +} + +inline SelectMgr_SelectingVolumeManager& SelectMgr_ViewerSelector::GetManager() +{ + return mySelectingVolumeMgr; } diff --git a/src/StdSelect/FILES b/src/StdSelect/FILES new file mode 100644 index 0000000000..9db0ac3f03 --- /dev/null +++ b/src/StdSelect/FILES @@ -0,0 +1,3 @@ +StdSelect_ViewerSelector3d.hxx +StdSelect_ViewerSelector3d.cxx +StdSelect_ViewerSelector3d.lxx diff --git a/src/StdSelect/StdSelect.cdl b/src/StdSelect/StdSelect.cdl index f9b5313b46..c59dda2607 100644 --- a/src/StdSelect/StdSelect.cdl +++ b/src/StdSelect/StdSelect.cdl @@ -51,7 +51,8 @@ uses TColStd, gp, Select3D, - Graphic3d,Visual3d, + Graphic3d, + Visual3d, Quantity, Prs3d, V3d, @@ -88,10 +89,8 @@ is ---Purpose: Selection sensitivity mode. SM_WINDOW mode uses the -- specified pixel tolerance to compute the sensitivity value, -- SM_VIEW mode allows to define the sensitivity manually. - - - class ViewerSelector3d; - + + class BRepSelectionTool; class BRepOwner; @@ -103,6 +102,8 @@ is class FaceFilter; class ShapeTypeFilter; + imported transient class ViewerSelector3d; + ---Category: Private Classes private class Prs; @@ -111,13 +112,10 @@ is private class IndexedDataMapOfOwnerPrs instantiates IndexedDataMap from TCollection (EntityOwner from SelectBasics,Prs from StdSelect,MapTransientHasher from TColStd); - - GetProjector (aView: View from V3d) returns Projector from Select3D; - ---Purpose: Returns the 3D projector for the view aView. - SetDrawerForBRepOwner(aSelection: Selection from SelectMgr; - aDrawer : Drawer from Prs3d); - ---Purpose: puts The same drawer in every BRepOwner Of SensitivePrimitive - -- Used Only for hilight Of BRepOwner... + SetDrawerForBRepOwner(aSelection: Selection from SelectMgr; + aDrawer : Drawer from Prs3d); + ---Purpose: puts The same drawer in every BRepOwner Of SensitivePrimitive + -- Used Only for hilight Of BRepOwner... end StdSelect; diff --git a/src/StdSelect/StdSelect.cxx b/src/StdSelect/StdSelect.cxx index 3b3f6ae830..3930c6ca58 100644 --- a/src/StdSelect/StdSelect.cxx +++ b/src/StdSelect/StdSelect.cxx @@ -31,29 +31,6 @@ #include #include -Handle(Select3D_Projector) StdSelect::GetProjector(const Handle(V3d_View)& aViou) -{ - Standard_Real Focale=0.,Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ; - Standard_Boolean Pers=Standard_False; - // NKV - 31/07/07 - Fix for perspective view - if ( aViou->Type() == V3d_PERSPECTIVE ) { - Pers = Standard_True; - Focale = aViou->Focale();} // must be replaced by the method Focale - - aViou->At(Xat,Yat,Zat); - aViou->Up(XUp,YUp,ZUp); - aViou->Proj(DX,DY,DZ); - gp_Pnt At (Xat,Yat,Zat); - gp_Dir Zpers (DX,DY,DZ); - gp_Dir Ypers (XUp,YUp,ZUp); - gp_Dir Xpers = Ypers.Crossed(Zpers); - gp_Ax3 Axe (At, Zpers, Xpers); - gp_Trsf T; - T.SetTransformation(Axe); - return new Select3D_Projector(T,Pers,Focale); - -} - //======================================================================= //function : SetDrawerForBRepOwner //purpose : @@ -65,7 +42,7 @@ void StdSelect::SetDrawerForBRepOwner(const Handle(SelectMgr_Selection)& /*Sel*/ // Handle(StdSelect_BRepOwner) BROWN; // for(Sel->Init();Sel->More();Sel->Next()){ -// BROWN = Handle(StdSelect_BRepOwner)::DownCast(Sel->Sensitive()->OwnerId()); +// BROWN = Handle(StdSelect_BRepOwner)::DownCast(Sel->Sensitive()->BaseSensitive()->OwnerId()); // if(!BROWN.IsNull()) // BROWN->SetDrawer(Drwr); // } diff --git a/src/StdSelect/StdSelect_BRepSelectionTool.cdl b/src/StdSelect/StdSelect_BRepSelectionTool.cdl index 1b8094fd05..b4a381b0b7 100644 --- a/src/StdSelect/StdSelect_BRepSelectionTool.cdl +++ b/src/StdSelect/StdSelect_BRepSelectionTool.cdl @@ -53,18 +53,18 @@ class BRepSelectionTool from StdSelect -- uses - Selection from SelectMgr, - Shape from TopoDS, - Face from TopoDS, - ShapeEnum from TopAbs, - SelectableObject from SelectMgr, - BRepOwner from StdSelect, - SensitiveEntity from Select3D, - ListOfSensitive from Select3D + Selection from SelectMgr, + Shape from TopoDS, + Face from TopoDS, + ShapeEnum from TopAbs, + SelectableObject from SelectMgr, + BRepOwner from StdSelect, + SensitiveEntity from Select3D, + EntitySequence from Select3D is Load(myclass; - aSelection : Selection from SelectMgr; + aSelection : Selection from SelectMgr; aShape : Shape from TopoDS; aType : ShapeEnum from TopAbs; theDeflection : Real from Standard; @@ -90,7 +90,7 @@ is Load(myclass; - aSelection : Selection from SelectMgr; + aSelection : Selection from SelectMgr; Origin : SelectableObject from SelectMgr; aShape : Shape from TopoDS; aType : ShapeEnum from TopAbs; @@ -152,6 +152,14 @@ is -- computed for the faces which have none. If it is false, -- sensitive entities on these faces will be calculated. + preBuildBVH (myclass; + theSelection : Selection from SelectMgr) + is private; + ---Level: Internal + ---Purpose: Traverses the selection given and pre-builds BVH trees for heavyweight + -- sensitive entities containing more than BVH_PRIMITIVE_LIMIT (defined in .cxx file) + -- sub-elements + GetEdgeSensitive(myclass; aShape : Shape from TopoDS; anOwner : BRepOwner from StdSelect; @@ -160,7 +168,7 @@ is theDeflectionAngle : Real from Standard; NbPOnEdge : Integer; MaximalParameter : Real from Standard; - aSensitive : in out SensitiveEntity from Select3D) + aSensitive : in out SensitiveEntity from Select3D) is private; ---Level: Internal ---Purpose: @@ -169,7 +177,7 @@ is GetSensitiveForFace(myclass; aFace : Face from TopoDS; anOwner : BRepOwner from StdSelect; - OutList : in out ListOfSensitive from Select3D; + OutList : in out EntitySequence from Select3D; AutoTriangulation : Boolean from Standard = Standard_True; NbPOnEdge : Integer = 9; MaxiParam : Real from Standard =500; diff --git a/src/StdSelect/StdSelect_BRepSelectionTool.cxx b/src/StdSelect/StdSelect_BRepSelectionTool.cxx index 5126512454..96e1d6370a 100644 --- a/src/StdSelect/StdSelect_BRepSelectionTool.cxx +++ b/src/StdSelect/StdSelect_BRepSelectionTool.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -40,9 +41,7 @@ #include #include #include - -#include -#include +#include #include #include #include @@ -61,6 +60,40 @@ #include #include +#define BVH_PRIMITIVE_LIMIT 800000 + +//================================================== +// function: preBuildBVH +// purpose : Pre-builds BVH tree for heavyweight +// sensitive entities with sub-elements +// amount more than BVH_PRIMITIVE_LIMIT +//================================================== +void StdSelect_BRepSelectionTool::preBuildBVH (const Handle(SelectMgr_Selection)& theSelection) +{ + for (theSelection->Init(); theSelection->More(); theSelection->Next()) + { + const Handle(SelectBasics_SensitiveEntity)& aSensitive = theSelection->Sensitive()->BaseSensitive(); + if (aSensitive->NbSubElements() >= BVH_PRIMITIVE_LIMIT) + { + aSensitive->BVH(); + } + + if (aSensitive->IsInstance ("Select3D_SensitiveGroup")) + { + const Handle(Select3D_SensitiveGroup)& aGroup = Handle(Select3D_SensitiveGroup)::DownCast (aSensitive); + const Select3D_EntitySequence& aSubEntities = aGroup->GetEntities(); + for (Select3D_EntitySequenceIter aSubEntitiesIter (aSubEntities); aSubEntitiesIter.More(); aSubEntitiesIter.Next()) + { + const Handle(Select3D_SensitiveEntity)& aSubEntity = aSubEntitiesIter.Value(); + if (aSubEntity->NbSubElements() >= BVH_PRIMITIVE_LIMIT) + { + aSubEntity->BVH(); + } + } + } + } +} + //================================================== // Function: Load // Purpose : @@ -156,9 +189,11 @@ void StdSelect_BRepSelectionTool for (theSelection->Init(); theSelection->More(); theSelection->Next()) { Handle(SelectMgr_EntityOwner) anOwner - = Handle(SelectMgr_EntityOwner)::DownCast (theSelection->Sensitive()->OwnerId()); + = Handle(SelectMgr_EntityOwner)::DownCast (theSelection->Sensitive()->BaseSensitive()->OwnerId()); anOwner->Set (theSelectableObj); } + + preBuildBVH (theSelection); } //================================================== @@ -217,11 +252,11 @@ void StdSelect_BRepSelectionTool case TopAbs_FACE: { const TopoDS_Face& aFace = TopoDS::Face (theShape); - Select3D_ListOfSensitive aSensitiveList; + Select3D_EntitySequence aSensitiveList; GetSensitiveForFace (aFace, theOwner, aSensitiveList, isAutoTriangulation, theNbPOnEdge, theMaxParam); - for (Select3D_ListIteratorOfListOfSensitive aSensIter (aSensitiveList); + for (Select3D_EntitySequenceIter aSensIter (aSensitiveList); aSensIter.More(); aSensIter.Next()) { theSelection->Add (aSensIter.Value()); @@ -575,7 +610,7 @@ Standard_Integer StdSelect_BRepSelectionTool::GetStandardPriority (const TopoDS_ Standard_Boolean StdSelect_BRepSelectionTool ::GetSensitiveForFace (const TopoDS_Face& theFace, const Handle(StdSelect_BRepOwner)& theOwner, - Select3D_ListOfSensitive& theSensitiveList, + Select3D_EntitySequence& theSensitiveList, const Standard_Boolean /*theAutoTriangulation*/, const Standard_Integer NbPOnEdge, const Standard_Real theMaxParam, diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cdl b/src/StdSelect/StdSelect_ViewerSelector3d.cdl deleted file mode 100644 index 7c45d5a4d8..0000000000 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cdl +++ /dev/null @@ -1,199 +0,0 @@ --- Created on: 1995-03-15 --- Created by: Robert COUBLANC --- Copyright (c) 1995-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - --- Modified by rob jun 25 98 : Add Method : Reactivate projector... - -class ViewerSelector3d from StdSelect inherits ViewerSelector from SelectMgr - - ---Purpose: Selector Usable by Viewers from V3d - -- Accepts Only Sensitive Entities inheriting Select3D entities... - -uses - View from V3d, - Selection from SelectMgr, - EntityOwner from SelectMgr, - Projector from Select3D, - Group from Graphic3d, - Structure from Graphic3d, - SequenceOfHClipPlane from Graphic3d, - Array1OfReal from TColStd, - Array1OfPnt2d from TColgp, - SensitivityMode from StdSelect, - Lin from gp, - Pnt from gp, - Dir from gp, - XYZ from gp - -is - - Create returns ViewerSelector3d from StdSelect; - ---Purpose: Constructs an empty 3D selector object. - - Create (theProj : Projector from Select3D) returns ViewerSelector3d from StdSelect; - ---Purpose: Constructs a 3D selector object defined by the projector . - - Convert (me : mutable; theSel : Selection from SelectMgr) - is redefined static; - ---Level: Public - ---Purpose: Processes the projection of the sensitive primitives - -- in the active view ; to be done before the selection action... - - Set (me : mutable; theProj : Projector from Select3D) is static; - ---Purpose: Sets the new projector to replace the one used at construction time. - - SetSensitivityMode (me : mutable; - theMode : SensitivityMode from StdSelect) is static; - ---Purpose: Sets the selection sensitivity mode. SM_WINDOW mode - -- uses the specified pixel tolerance to compute the sensitivity - -- value, SM_VIEW mode allows to define the sensitivity manually. - - SensitivityMode (me) returns SensitivityMode from StdSelect; - ---C++: inline - ---Purpose: Returns the selection sensitivity mode. - - SetPixelTolerance (me : mutable; - theTolerance : Integer) is static; - ---Purpose: Sets the pixel tolerance . - - PixelTolerance (me) returns Integer from Standard; - ---C++: inline - ---Purpose: Returns the pixel tolerance. - - Pick (me : mutable; theXPix, theYPix : Integer; - theView : View from V3d) is static; - ---Level: Public - ---Purpose: Picks the sensitive entity at the pixel coordinates of - -- the mouse and . The selector looks for touched areas and owners. - - Pick (me : mutable; theXPMin, theYPMin, theXPMax, theYPMax : Integer; theView : View from V3d) is static; - ---Purpose: Picks the sensitive entity according to the minimum - -- and maximum pixel values , , - -- and defining a 2D area for selection in the 3D view aView. - - Pick (me : mutable; thePolyline : Array1OfPnt2d from TColgp; theView : View from V3d) is static; - ---Level: Public - ---Purpose: pick action - input pixel values for polyline selection for selection. - - ---Category: Inquire Methods - - Projector (me) returns Projector from Select3D; - ---Level: Public - ---Purpose: Returns the current Projector. - ---C++: inline - ---C++: return const& - - ---Category: Internal Methods - -- ----------------- - - UpdateProj (me : mutable; - theView : View from V3d) returns Boolean is static private; - ---Level: Internal - - DisplayAreas (me : mutable; - theView : View from V3d) is static; - ---Purpose: Displays sensitive areas found in the view . - - ClearAreas (me : mutable; - theView : View from V3d) is static; - ---Purpose: Clears the view aView of sensitive areas found in it. - - DisplaySensitive (me : mutable; theView : View from V3d) is static; - --- Purpose: Displays sensitives in view . - - ClearSensitive (me : mutable; theView : View from V3d) is static; - - DisplaySensitive (me : mutable; - theSel : Selection from SelectMgr; - theView : View from V3d; - theToClearOthers : Boolean from Standard = Standard_True) - is static; - - DisplayAreas (me : mutable; - theSel : Selection from SelectMgr; - theView : View from V3d; - theToClearOthers : Boolean from Standard = Standard_True) - is static; - - ComputeSensitivePrs (me : mutable; theSel: Selection from SelectMgr) - is static private; - ---Level: Internal - - ComputeAreasPrs (me : mutable; theSel : Selection from SelectMgr) - is static private; - ---Level: Internal - - SetClipping (me : mutable; thePlanes : SequenceOfHClipPlane from Graphic3d) is protected; - ---Level: Internal - ---Purpose: Set view clipping for the selector. - -- @param thePlanes [in] the view planes. - - ComputeClipRange (me; thePlanes : SequenceOfHClipPlane from Graphic3d; - thePickLine : Lin from gp; - theDepthMin, theDepthMax : out Real from Standard) - is protected; - ---Level: Internal - ---Purpose: Computed depth boundaries for the passed set of clipping planes and picking line. - -- @param thePlanes [in] the planes. - -- @param thePickLine [in] the picking line. - -- @param theDepthMin [out] minimum depth limit. - -- @param theDepthMax [out] maximum depth limit. - - PickingLine (me; theX, theY : Real from Standard) - returns Lin from gp - is redefined protected; - ---Level: Internal - ---Purpose: For more details please refer to base class. - - DepthClipping (me; theX, theY : Real from Standard; - theMin, theMax : out Real from Standard) - is redefined protected; - ---Level: Internal - ---Purpose: For more details please refer to base class. - - DepthClipping (me; theX, theY : Real from Standard; - theOwner : EntityOwner from SelectMgr; - theMin, theMax : out Real from Standard) - is redefined protected; - ---Level: Internal - ---Purpose: For more details please refer to base class. - - HasDepthClipping (me; theOwner : EntityOwner from SelectMgr) - returns Boolean is redefined protected; - ---Level: Internal - ---Purpose: For more details please refer to base class. - -fields - - myProjector : Projector from Select3D; - myPrevAt : Real from Standard[3]; - myPrevUp : Real from Standard[3]; - myPrevProj : Real from Standard[3]; - myPrevAxialScale : Real from Standard[3]; - myPrevFOV : Real from Standard; - myPrevScale : Real from Standard; - myPrevOrthographic : Boolean from Standard; - mySensMode : SensitivityMode from StdSelect; - myPixelTolerance : Integer from Standard; - myToUpdateTolerance : Boolean from Standard; - - --areas verification... - - myareagroup : Group from Graphic3d; - mysensgroup : Group from Graphic3d; - mystruct : Structure from Graphic3d; - myClipPlanes : SequenceOfHClipPlane from Graphic3d; - -end ViewerSelector3d; diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cxx b/src/StdSelect/StdSelect_ViewerSelector3d.cxx index e7128bccac..b90c8974eb 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cxx @@ -14,7 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include +#include #include #include #include @@ -27,12 +27,13 @@ #include #include #include +#include #include +#include #include -#include -#include #include #include +#include #include #include #include @@ -42,17 +43,15 @@ #include #include #include -#include -#include #include -#include +#include +#include -#include #include #include +#include #include #include -#include #include #include @@ -64,6 +63,11 @@ #include #include +#include + +IMPLEMENT_STANDARD_HANDLE (StdSelect_ViewerSelector3d, SelectMgr_ViewerSelector) +IMPLEMENT_STANDARD_RTTIEXT(StdSelect_ViewerSelector3d, SelectMgr_ViewerSelector) + static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg) { Standard_Integer nFree = 0; @@ -83,105 +87,17 @@ static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulatio // Function : Constructor // Purpose : //======================================================================= -StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() -: myProjector (new Select3D_Projector()), - myPrevFOV (0.0), - myPrevScale (0.0), - myPrevOrthographic (Standard_True), - mySensMode (StdSelect_SM_WINDOW), - myPixelTolerance (2), - myToUpdateTolerance (Standard_True) -{ - myPrevAt[0] = 0.0; - myPrevAt[1] = 0.0; - myPrevAt[2] = 0.0; - myPrevUp[0] = 0.0; - myPrevUp[1] = 0.0; - myPrevUp[2] = 0.0; - myPrevProj[0] = 0.0; - myPrevProj[1] = 0.0; - myPrevProj[2] = 0.0; - myPrevAxialScale[0] = 0.0; - myPrevAxialScale[1] = 0.0; - myPrevAxialScale[2] = 0.0; -} - -//======================================================================= -// Function : Constructor -// Purpose : -//======================================================================= -StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d (const Handle(Select3D_Projector)& theProj) -: myProjector (theProj), - myPrevFOV (0.0), - myPrevScale (0.0), - myPrevOrthographic (Standard_True), - mySensMode (StdSelect_SM_WINDOW), - myPixelTolerance (2), - myToUpdateTolerance (Standard_True) -{ - myPrevAt[0] = 0.0; - myPrevAt[1] = 0.0; - myPrevAt[2] = 0.0; - myPrevUp[0] = 0.0; - myPrevUp[1] = 0.0; - myPrevUp[2] = 0.0; - myPrevProj[0] = 0.0; - myPrevProj[1] = 0.0; - myPrevProj[2] = 0.0; - myPrevAxialScale[0] = 0.0; - myPrevAxialScale[1] = 0.0; - myPrevAxialScale[2] = 0.0; -} - -//======================================================================= -// Function: Convert -// Purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::Convert (const Handle(SelectMgr_Selection)& theSel) -{ - for (theSel->Init(); theSel->More(); theSel->Next()) - { - if (theSel->Sensitive()->NeedsConversion()) - { - Handle(Select3D_SensitiveEntity) aSE = *((Handle(Select3D_SensitiveEntity)*) &(theSel->Sensitive())); - aSE->Project (myProjector); - if (!tosort) - { - tosort = Standard_True; - } - } - } -} - -//======================================================================= -// Function: Set -// Purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::Set (const Handle(Select3D_Projector)& theProj) -{ - myProjector = theProj; - toupdate = Standard_True; -} - -//======================================================================= -// Function: SetSensitivityMode -// Purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::SetSensitivityMode (const StdSelect_SensitivityMode theMode) -{ - mySensMode = theMode; - toupdate = Standard_True; -} +StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {} //======================================================================= // Function: SetPixelTolerance // Purpose : //======================================================================= -void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance) +void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theTolerance) { - if (myPixelTolerance != theTolerance) + if (mytolerance != theTolerance) { - myPixelTolerance = theTolerance; + mytolerance = theTolerance; myToUpdateTolerance = Standard_True; } } @@ -195,15 +111,23 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix, const Handle(V3d_View)& theView) { SetClipping (theView->GetClipPlanes()); - UpdateProj (theView); - Standard_Real aPnt3d[3]; - theView->Convert (theXPix, theYPix, - aPnt3d[0], aPnt3d[1], aPnt3d[2]); - gp_Pnt2d aPnt2d; - myProjector->Project (gp_Pnt (aPnt3d[0], aPnt3d[1], aPnt3d[2]), aPnt2d); + if(myToUpdateTolerance) + { + mySelectingVolumeMgr.SetPixelTolerance (mytolerance); + myToUpdateTolerance = Standard_False; + } - InitSelect (aPnt2d.X(), aPnt2d.Y()); + mySelectingVolumeMgr.SetCamera (theView->Camera()); + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Point); + Standard_Integer aWidth = 0, aHeight = 0; + theView->Window()->Size (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); + gp_Pnt2d aMousePos (static_cast (theXPix), + static_cast (theYPix)); + mySelectingVolumeMgr.BuildSelectingVolume (aMousePos); + + TraverseSensitives(); } //======================================================================= @@ -216,32 +140,19 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin, const Standard_Integer theYPMax, const Handle(V3d_View)& theView) { - if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) - { - SetSensitivity (theView->Convert (myPixelTolerance)); - myToUpdateTolerance = Standard_False; - } + mySelectingVolumeMgr.SetCamera (theView->Camera()); + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box); + Standard_Integer aWidth = 0, aHeight = 0; + theView->Window()->Size (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); + gp_Pnt2d aMinMousePos (static_cast (theXPMin), + static_cast (theYPMin)); + gp_Pnt2d aMaxMousePos (static_cast (theXPMax), + static_cast (theYPMax)); + mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos, + aMaxMousePos); - UpdateProj (theView); - - Standard_Real aX1 = 0.0; - Standard_Real aY1 = 0.0; - Standard_Real aZ1 = 0.0; - Standard_Real aX2 = 0.0; - Standard_Real aY2 = 0.0; - Standard_Real aZ2 = 0.0; - gp_Pnt2d aP2d1; - gp_Pnt2d aP2d2; - - theView->Convert (theXPMin, theYPMin, aX1, aY1, aZ1); - theView->Convert (theXPMax, theYPMax, aX2, aY2, aZ2); - myProjector->Project (gp_Pnt (aX1, aY1, aZ1), aP2d1); - myProjector->Project (gp_Pnt (aX2, aY2, aZ2), aP2d2); - - InitSelect (Min (aP2d1.X(), aP2d2.X()), - Min (aP2d1.Y(), aP2d2.Y()), - Max (aP2d1.X(), aP2d2.X()), - Max (aP2d1.Y(), aP2d2.Y())); + TraverseSensitives(); } //======================================================================= @@ -251,295 +162,22 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin, void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline, const Handle(V3d_View)& theView) { - if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) - { - SetSensitivity (theView->Convert (myPixelTolerance)); - myToUpdateTolerance = Standard_False; - } + mySelectingVolumeMgr.SetCamera (theView->Camera()); + mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline); + Standard_Integer aWidth = 0, aHeight = 0; + theView->Window()->Size (aWidth, aHeight); + mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight); + mySelectingVolumeMgr.BuildSelectingVolume (thePolyline); - UpdateProj (theView); - - Standard_Integer aNbPix = thePolyline.Length(); - - // Convert pixel - Handle(TColgp_HArray1OfPnt2d) aP2d = new TColgp_HArray1OfPnt2d (1, aNbPix); - - for (Standard_Integer aPntIt = 1; aPntIt <= aNbPix; ++aPntIt) - { - Standard_Integer aXP = (Standard_Integer)(thePolyline (aPntIt).X()); - Standard_Integer aYP = (Standard_Integer)(thePolyline (aPntIt).Y()); - - Standard_Real aX = 0.0; - Standard_Real aY = 0.0; - Standard_Real aZ = 0.0; - gp_Pnt2d aPnt2d; - - theView->Convert (aXP, aYP, aX, aY, aZ); - myProjector->Project (gp_Pnt (aX, aY, aZ), aPnt2d); - - aP2d->SetValue (aPntIt, aPnt2d); - } - - const TColgp_Array1OfPnt2d& aPolyConvert = aP2d->Array1(); - - InitSelect (aPolyConvert); + TraverseSensitives(); } -//======================================================================= -// Function: DisplayAreas -// Purpose : display the activated areas... -//======================================================================= -void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(V3d_View)& theView) -{ - if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) - { - SetSensitivity (theView->Convert (myPixelTolerance)); - myToUpdateTolerance = Standard_False; - } - - UpdateProj (theView); - UpdateSort(); // Updates the activated areas - - if (mystruct.IsNull()) - { - mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); - } - - if (myareagroup.IsNull()) - { - myareagroup = mystruct->NewGroup(); - } - - SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive anIt (myentities); - Handle(Select3D_Projector) aProjector = StdSelect::GetProjector (theView); - aProjector->SetView (theView); - - Standard_Real aXmin = 0.0; - Standard_Real aYmin = 0.0; - Standard_Real aXmax = 0.0; - Standard_Real aYmax = 0.0; - gp_Pnt aPbid; - SelectBasics_ListOfBox2d aBoxList; - - TColgp_SequenceOfPnt aSeqLines; - for (; anIt.More(); anIt.Next()) - { - anIt.Value()->Areas (aBoxList); - - for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next()) - { - aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax); - - aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0); - aProjector->Transform (aPbid, aProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0); - aProjector->Transform (aPbid, aProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0); - aProjector->Transform (aPbid, aProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0); - aProjector->Transform (aPbid, aProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - } - } - - if (aSeqLines.Length()) - { - Standard_Integer aN = 0; - Standard_Integer aNp = 0; - const Standard_Integer aNbl = aSeqLines.Length() / 4; - - Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNbl, aNbl); - for (aNp = 1, aN = 0; aN < aNbl; aN++) - { - aPrims->AddBound (5); - const gp_Pnt &aPnt1 = aSeqLines (aNp++); - aPrims->AddVertex (aPnt1); - aPrims->AddVertex (aSeqLines (aNp++)); - aPrims->AddVertex (aSeqLines (aNp++)); - aPrims->AddVertex (aSeqLines (aNp++)); - aPrims->AddVertex (aPnt1); - } - myareagroup->AddPrimitiveArray (aPrims); - } - - myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0)); - myareagroup->Structure()->SetDisplayPriority (10); - myareagroup->Structure()->Display(); - - theView->Update(); -} - -//======================================================================= -// Function: ClearAreas -// Purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::ClearAreas (const Handle(V3d_View)& theView) -{ - if (myareagroup.IsNull()) - { - return; - } - - myareagroup->Clear(); - - if (!theView.IsNull()) - { - theView->Update(); - } -} - -//======================================================================= -// Function: UpdateProj -// Purpose : -//======================================================================= -Standard_Boolean StdSelect_ViewerSelector3d::UpdateProj (const Handle(V3d_View)& theView) -{ - // Check common properties of camera - Standard_Real anUp[3]; - Standard_Real aProj[3]; - Standard_Real anAxialScale[3]; - theView->Up (anUp[0], anUp[1], anUp[2]); - theView->Proj (aProj[0], aProj[1], aProj[2]); - theView->AxialScale (anAxialScale[0], anAxialScale[1], anAxialScale[2]); - - Standard_Boolean isOrthographic = theView->Type() == V3d_ORTHOGRAPHIC; - Standard_Boolean toUpdateProjector = myPrevOrthographic != isOrthographic - || myPrevUp[0] != anUp[0] - || myPrevUp[1] != anUp[1] - || myPrevUp[2] != anUp[2] - || myPrevProj[0] != aProj[0] - || myPrevProj[1] != aProj[1] - || myPrevProj[2] != aProj[2] - || myPrevAxialScale[0] != anAxialScale[0] - || myPrevAxialScale[1] != anAxialScale[1] - || myPrevAxialScale[2] != anAxialScale[2]; - - // Check properties of perspective camera - Standard_Real anAt[3]; - Standard_Real aScale = theView->Scale(); - Standard_Real aFOV = theView->Camera()->FOVy(); - theView->At (anAt[0], anAt[1], anAt[2]); - if (!isOrthographic && !toUpdateProjector) - { - toUpdateProjector = myPrevAt[0] != anAt[0] - || myPrevAt[1] != anAt[1] - || myPrevAt[2] != anAt[2] - || myPrevScale != aScale - || myPrevFOV != aFOV; - } - - myToUpdateTolerance = aScale != myPrevScale; - - // Update projector if anything changed - if (toUpdateProjector) - { - toupdate = Standard_True; - - myToUpdateTolerance = Standard_True; - - if (isOrthographic) - { - // For orthographic view use only direction of projection and up vector - // Panning, and zooming has no effect on 2D selection sensitives. - Handle (Graphic3d_Camera) aCamera = new Graphic3d_Camera(); - - aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic); - aCamera->SetCenter (gp::Origin()); - aCamera->SetDirection (gp_Dir (-aProj[0], -aProj[1], -aProj[2])); - aCamera->SetUp (gp_Dir (anUp[0], anUp[1], anUp[2])); - aCamera->SetDistance (1.0); - aCamera->SetAxialScale (gp_XYZ (anAxialScale[0], anAxialScale[1], anAxialScale[2])); - - myProjector = new Select3D_Projector (aCamera->OrientationMatrix(), Graphic3d_Mat4d()); - } - else - { - // For perspective projection panning, zooming and location of view - // has effect. Thus, use current view and projection matrices from - // view camera. Exception is that the projection transformation - // is scaled from NDC to size of displaying frame of view space in order - // to maintain consistence with pixel tolerance conversion. - const Graphic3d_Mat4d& aMVMatrix = theView->Camera()->OrientationMatrix(); - const Graphic3d_Mat4d& aProjMatrix = theView->Camera()->ProjectionMatrix(); - gp_XYZ aViewDimensions = theView->Camera()->ViewDimensions(); - - Graphic3d_Mat4d aScaledProj; - aScaledProj.ChangeValue (0, 0) = aViewDimensions.X(); - aScaledProj.ChangeValue (1, 1) = aViewDimensions.Y(); - aScaledProj.ChangeValue (2, 2) = aViewDimensions.Z(); - Graphic3d_Mat4d aScaledProjMatrix = aScaledProj * aProjMatrix; - - Standard_Real aZNear = theView->Camera()->ZNear(); - Standard_Real aZFar = theView->Camera()->ZFar(); - - myProjector = new Select3D_Projector (aMVMatrix, aScaledProjMatrix, aZNear, aZFar); - } - } - - myPrevAt[0] = anAt[0]; - myPrevAt[1] = anAt[1]; - myPrevAt[2] = anAt[2]; - myPrevUp[0] = anUp[0]; - myPrevUp[1] = anUp[1]; - myPrevUp[2] = anUp[2]; - myPrevProj[0] = aProj[0]; - myPrevProj[1] = aProj[1]; - myPrevProj[2] = aProj[2]; - myPrevAxialScale[0] = anAxialScale[0]; - myPrevAxialScale[1] = anAxialScale[1]; - myPrevAxialScale[2] = anAxialScale[2]; - myPrevFOV = aFOV; - myPrevScale = aScale; - myPrevOrthographic = isOrthographic; - - if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) - { - SetSensitivity (theView->Convert (myPixelTolerance)); - myToUpdateTolerance = Standard_False; - } - - if (toupdate) - { - UpdateConversion(); - } - - if (tosort) - { - UpdateSort(); - } - - return Standard_True; -} - - //======================================================================= // Function: DisplaySensitive. // Purpose : Display active primitives. //======================================================================= void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView) { - if (myToUpdateTolerance && SensitivityMode() == StdSelect_SM_WINDOW) - { - SetSensitivity (theView->Convert (myPixelTolerance)); - myToUpdateTolerance = Standard_False; - } - - if (toupdate) - { - UpdateProj (theView); - } - - if (tosort) - { - UpdateSort(); // Updates the activated areas - } - // Preparation des structures if (mystruct.IsNull()) { @@ -559,14 +197,15 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theVi mysensgroup->SetPrimitivesAspect ( new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0)); - SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation anIt (myselections); - - for (; anIt.More(); anIt.Next()) + for (Standard_Integer anObjectIdx = 0; anObjectIdx <= mySelectableObjects->Size(); ++anObjectIdx) { - if (anIt.Value()==0) + const Handle (SelectMgr_SelectableObject)& anObject = mySelectableObjects->GetObjectById (anObjectIdx); + for (anObject->Init(); anObject->More(); anObject->Next()) { - const Handle(SelectMgr_Selection)& aSel = anIt.Key(); - ComputeSensitivePrs (aSel); + if (anObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) + { + ComputeSensitivePrs (anObject->CurrentSelection(), anObject->Transformation()); + } } } @@ -602,6 +241,7 @@ void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView //purpose : //======================================================================= void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel, + const gp_Trsf& theTrsf, const Handle(V3d_View)& theView, const Standard_Boolean theToClearOthers) { @@ -627,39 +267,7 @@ void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Select mysensgroup->Clear(); } - ComputeSensitivePrs (theSel); - - mystruct->SetDisplayPriority (10); - mystruct->Display(); - - theView->Update(); -} - -//======================================================================= -//function : DisplayAreas -//purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection)& theSel, - const Handle(V3d_View)& theView, - const Standard_Boolean theToClearOthers) -{ - if (mystruct.IsNull()) - { - mystruct = new Graphic3d_Structure (theView->Viewer()->Viewer()); - } - - if (mysensgroup.IsNull()) - { - myareagroup = mystruct->NewGroup(); - myareagroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0)); - } - - if (theToClearOthers) - { - myareagroup->Clear(); - } - - ComputeAreasPrs (theSel); + ComputeSensitivePrs (theSel, theTrsf); mystruct->SetDisplayPriority (10); mystruct->Display(); @@ -671,19 +279,17 @@ void StdSelect_ViewerSelector3d::DisplayAreas (const Handle(SelectMgr_Selection) //function : ComputeSensitivePrs //purpose : //======================================================================= -void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel) +void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel, + const gp_Trsf& theLoc) { TColgp_SequenceOfPnt aSeqLines, aSeqFree; TColStd_SequenceOfInteger aSeqBnds; for (theSel->Init(); theSel->More(); theSel->Next()) { - Handle(Select3D_SensitiveEntity) Ent = Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive()); - const Standard_Boolean hasloc = (Ent.IsNull()? Standard_False : Ent->HasLocation()); - - TopLoc_Location theloc; - if(hasloc) - theloc = Ent->Location(); + Handle(Select3D_SensitiveEntity) Ent = + Handle(Select3D_SensitiveEntity)::DownCast(theSel->Sensitive()->BaseSensitive()); + const Standard_Boolean hasloc = theLoc.Form() != gp_Identity; //============== // Box @@ -709,7 +315,7 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel if(hasloc) { for (i = 0; i <= 7; i++) - theboxpoint[i].Transform (theloc.Transformation()); + theboxpoint[i].Transform (theLoc); } aSeqBnds.Append(5); @@ -736,14 +342,14 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel { Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent); Handle(TColgp_HArray1OfPnt) TheHPts; - aFace->Points3D(TheHPts); + aFace->GetPoints(TheHPts); const TColgp_Array1OfPnt& ThePts = TheHPts->Array1(); aSeqBnds.Append(ThePts.Length()); for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) { if (hasloc) - aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); + aSeqLines.Append(ThePts(I).Transformed (theLoc)); else aSeqLines.Append(ThePts(I)); } @@ -762,7 +368,7 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) { if (hasloc) - aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); + aSeqLines.Append(ThePts(I).Transformed (theLoc)); else aSeqLines.Append(ThePts(I)); } @@ -773,12 +379,11 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire)) { Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent); - Select3D_SensitiveEntitySequence EntitySeq; - aWire->GetEdges (EntitySeq); + const NCollection_Vector& anEntities = aWire->GetEdges(); - for (int i = 1; i <= EntitySeq.Length(); i++) + for (int i = 0; i < anEntities.Length(); i++) { - Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(EntitySeq.Value(i)); + Handle(Select3D_SensitiveEntity) SubEnt = Handle(Select3D_SensitiveEntity)::DownCast(anEntities.Value(i)); //Segment if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment)) @@ -787,8 +392,8 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ()); if (hasloc) { - P1.Transform(theloc.Transformation()); - P2.Transform(theloc.Transformation()); + P1.Transform(theLoc); + P2.Transform(theLoc); } aSeqBnds.Append(2); aSeqLines.Append(P1); @@ -813,9 +418,9 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel if (hasloc) { - aPnts[0].Transform (theloc.Transformation()); - aPnts[1].Transform (theloc.Transformation()); - aPnts[2].Transform (theloc.Transformation()); + aPnts[0].Transform (theLoc); + aPnts[1].Transform (theLoc); + aPnts[2].Transform (theLoc); } aSeqBnds.Append (4); @@ -838,7 +443,7 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++) { if (hasloc) - aSeqLines.Append(ThePts(I).Transformed (theloc.Transformation())); + aSeqLines.Append(ThePts(I).Transformed (theLoc)); else aSeqLines.Append(ThePts(I)); } @@ -854,8 +459,8 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ()); if (hasloc) { - P1.Transform (theloc.Transformation()); - P2.Transform (theloc.Transformation()); + P1.Transform (theLoc); + P2.Transform (theLoc); } aSeqBnds.Append(2); aSeqLines.Append(P1); @@ -881,9 +486,9 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel if (hasloc) { - aPnts[0].Transform (theloc.Transformation()); - aPnts[1].Transform (theloc.Transformation()); - aPnts[2].Transform (theloc.Transformation()); + aPnts[0].Transform (theLoc); + aPnts[1].Transform (theLoc); + aPnts[2].Transform (theLoc); } aSeqBnds.Append (4); @@ -900,7 +505,7 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel { gp_Pnt P = hasloc ? Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() : - Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theloc.Transformation()); + Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theLoc); Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1); anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z()); mysensgroup->AddPrimitiveArray (anArrayOfPoints); @@ -922,9 +527,9 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel bidloc = (*((Handle(Select3D_SensitiveTriangulation)*) &Ent))->GetInitLocation(); if (bidloc.IsIdentity()) - iloc = theloc; + iloc = theLoc; else - iloc = theloc * bidloc; + iloc = theLoc * bidloc; Standard_Integer i; for (i = 1; i <= PT->NbTriangles(); i++) @@ -1026,66 +631,6 @@ void StdSelect_ViewerSelector3d::ComputeSensitivePrs (const Handle(SelectMgr_Sel } } -//======================================================================= -//function : ComputeAreaPrs -//purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selection)& theSel) -{ - Standard_Real aXmin = 0.0; - Standard_Real aYmin = 0.0; - Standard_Real aXmax = 0.0; - Standard_Real aYmax = 0.0; - - gp_Pnt aPbid; - SelectBasics_ListOfBox2d aBoxList; - - TColgp_SequenceOfPnt aSeqLines; - for (theSel->Init(); theSel->More(); theSel->Next()) - { - theSel->Sensitive()->Areas (aBoxList); - for (SelectBasics_ListIteratorOfListOfBox2d aBoxIt (aBoxList); aBoxIt.More(); aBoxIt.Next()) - { - aBoxIt.Value().Get (aXmin, aYmin, aXmax, aYmax); - - aPbid.SetCoord (aXmin - mytolerance, aYmin - mytolerance, 0.0); - myProjector->Transform (aPbid, myProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmax + mytolerance, aYmin - mytolerance, 0.0); - myProjector->Transform (aPbid, myProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmax + mytolerance, aYmax + mytolerance, 0.0); - myProjector->Transform (aPbid, myProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - - aPbid.SetCoord (aXmin - mytolerance, aYmax + mytolerance, 0.0); - myProjector->Transform (aPbid, myProjector->InvertedTransformation()); - aSeqLines.Append (aPbid); - } - } - - if (aSeqLines.Length()) - { - Standard_Integer aN = 0; - Standard_Integer aNP = 0; - const Standard_Integer aNBL = aSeqLines.Length() / 4; - Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines (5 * aNBL, aNBL); - for (aNP = 1, aN = 0; aN < aNBL; aN++) - { - aPrims->AddBound (5); - const gp_Pnt &aP1 = aSeqLines (aNP++); - aPrims->AddVertex (aP1); - aPrims->AddVertex (aSeqLines (aNP++)); - aPrims->AddVertex (aSeqLines (aNP++)); - aPrims->AddVertex (aSeqLines (aNP++)); - aPrims->AddVertex (aP1); - } - myareagroup->AddPrimitiveArray (aPrims); - } -} - //======================================================================= //function : SetClipping //purpose : @@ -1095,104 +640,6 @@ void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPla myClipPlanes = thePlanes; } -//======================================================================= -//function : ComputeClipRange -//purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SequenceOfHClipPlane& thePlanes, - const gp_Lin& thePickLine, - Standard_Real& theDepthMin, - Standard_Real& theDepthMax) const -{ - theDepthMin = RealFirst(); - theDepthMax = RealLast(); - Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD; - - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); - for (; aPlaneIt.More(); aPlaneIt.Next()) - { - const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value(); - if (!aClipPlane->IsOn()) - continue; - - gp_Pln aGeomPlane = aClipPlane->ToPlane(); - - aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD); - - const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction(); - const gp_Dir& aPickDir = thePickLine.Direction(); - const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ(); - const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ(); - - Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir); - Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD); - - // check whether the pick line is parallel to clip plane - if (Abs (aDotProduct) < Precision::Angular()) - { - if (aDistance > 0.0) - { - // line lies above the plane, thus no selection is possible - theDepthMin = 0.0; - theDepthMax = 0.0; - return; - } - - // line lies below the plane and is not clipped, skip - continue; - } - - // compute distance to point of pick line intersection with the plane - Standard_Real aIntDist = aDistance / aDotProduct; - - // change depth limits for case of opposite and directed planes - if (aDotProduct < 0.0) - { - theDepthMax = Min (aIntDist, theDepthMax); - } - else if (aIntDist > theDepthMin) - { - theDepthMin = Max (aIntDist, theDepthMin); - } - } -} - -//======================================================================= -//function : PickingLine -//purpose : -//======================================================================= -gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const -{ - return myProjector->Shoot (theX, theY); -} - -//======================================================================= -//function : DepthClipping -//purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, - const Standard_Real theY, - Standard_Real& theDepthMin, - Standard_Real& theDepthMax) const -{ - return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax); -} - -//======================================================================= -//function : DepthClipping -//purpose : -//======================================================================= -void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, - const Standard_Real theY, - const Handle(SelectMgr_EntityOwner)& theOwner, - Standard_Real& theDepthMin, - Standard_Real& theDepthMax) const -{ - return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(), - PickingLine (theX, theY), - theDepthMin, theDepthMax); -} - //======================================================================= //function : HasDepthClipping //purpose : @@ -1207,3 +654,13 @@ Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(Sele const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable(); return (aSelectable->GetClipPlanes().Size() > 0); } + +//======================================================================= +//function : ResetSelectionActivationStatus +//purpose : Marks all sensitive entities, stored in viewer selector, +// as inactive for selection +//======================================================================= +void StdSelect_ViewerSelector3d::ResetSelectionActivationStatus() +{ + resetSelectionActivationStatus(); +} diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.hxx b/src/StdSelect/StdSelect_ViewerSelector3d.hxx new file mode 100644 index 0000000000..8931f11962 --- /dev/null +++ b/src/StdSelect/StdSelect_ViewerSelector3d.hxx @@ -0,0 +1,112 @@ +// Created on: 1995-03-15 +// Created by: Robert COUBLANC +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _StdSelect_ViewerSelector3d_HeaderFile +#define _StdSelect_ViewerSelector3d_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class Graphic3d_Group; +class Graphic3d_Structure; +class V3d_View; +class TColgp_Array1OfPnt2d; +class SelectMgr_EntityOwner; +class SelectMgr_SelectableObjectSet; + + +//! Selector Usable by Viewers from V3d +class StdSelect_ViewerSelector3d : public SelectMgr_ViewerSelector +{ + +public: + + //! Constructs an empty 3D selector object. + Standard_EXPORT StdSelect_ViewerSelector3d(); + + //! Sets the pixel tolerance . + Standard_EXPORT void SetPixelTolerance (const Standard_Real theTolerance); + + //! Returns the pixel tolerance. + Standard_Real PixelTolerance() const; + + //! Picks the sensitive entity at the pixel coordinates of + //! the mouse and . The selector looks for touched areas and owners. + Standard_EXPORT void Pick (const Standard_Integer theXPix, + const Standard_Integer theYPix, + const Handle(V3d_View)& theView); + + //! Picks the sensitive entity according to the minimum + //! and maximum pixel values , , + //! and defining a 2D area for selection in the 3D view aView. + Standard_EXPORT void Pick (const Standard_Integer theXPMin, + const Standard_Integer theYPMin, + const Standard_Integer theXPMax, + const Standard_Integer theYPMax, + const Handle(V3d_View)& theView); + + //! pick action - input pixel values for polyline selection for selection. + Standard_EXPORT void Pick (const TColgp_Array1OfPnt2d& thePolyline, + const Handle(V3d_View)& theView); + + //! Displays sensitives in view . + Standard_EXPORT void DisplaySensitive (const Handle(V3d_View)& theView); + + Standard_EXPORT void ClearSensitive (const Handle(V3d_View)& theView); + + Standard_EXPORT void DisplaySensitive (const Handle(SelectMgr_Selection)& theSel, + const gp_Trsf& theTrsf, + const Handle(V3d_View)& theView, + const Standard_Boolean theToClearOthers = Standard_True); + + //! Marks all sensitive entities, stored in viewer selector, as inactive for selection + Standard_EXPORT void ResetSelectionActivationStatus(); + + Standard_EXPORT virtual Standard_Boolean HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI(StdSelect_ViewerSelector3d) + +protected: + + //! Set view clipping for the selector. + //! @param thePlanes [in] the view planes. + Standard_EXPORT void SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes); + +private: + + void ComputeSensitivePrs (const Handle(SelectMgr_Selection)& theSel, const gp_Trsf& theLoc); + + Handle_Graphic3d_Group myareagroup; + Handle_Graphic3d_Group mysensgroup; + Handle_Graphic3d_Structure mystruct; + Graphic3d_SequenceOfHClipPlane myClipPlanes; +}; + +DEFINE_STANDARD_HANDLE(StdSelect_ViewerSelector3d, SelectMgr_ViewerSelector) + +#include + +#endif diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.lxx b/src/StdSelect/StdSelect_ViewerSelector3d.lxx index 8c910c1e31..c29b733070 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.lxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.lxx @@ -12,17 +12,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -inline StdSelect_SensitivityMode StdSelect_ViewerSelector3d::SensitivityMode() const +inline Standard_Real StdSelect_ViewerSelector3d::PixelTolerance() const { - return mySensMode; -} - -inline Standard_Integer StdSelect_ViewerSelector3d::PixelTolerance() const -{ - return myPixelTolerance; -} - -inline const Handle(Select3D_Projector)& StdSelect_ViewerSelector3d::Projector() const -{ - return myProjector; + return mytolerance; } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 410cc3c066..87447f768d 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -65,7 +65,6 @@ #include #include #include -#include #include #include @@ -445,6 +444,7 @@ void ViewerTest::Clear() } it.Next(); } + TheAISContext()->RebuildSelectionStructs(); TheAISContext()->UpdateCurrentViewer(); // TheNISContext()->UpdateViews(); GetMapOfAIS().Clear(); @@ -625,51 +625,6 @@ static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv return 0; } -//============================================================================== -//function : VDispAreas,VDispSensitive,... -//purpose : -//============================================================================== -static Standard_Integer VDispAreas (Draw_Interpretor& , - Standard_Integer theArgNb, - Standard_CString* ) -{ - if (theArgNb > 1) - { - std::cout << "Error: wrong syntax!\n"; - return 1; - } - - Handle(AIS_InteractiveContext) aCtx; - Handle(V3d_View) aView; - if (!getCtxAndView (aCtx, aView)) - { - return 1; - } - - aCtx->DisplayActiveAreas (aView); - return 0; -} -static Standard_Integer VClearAreas (Draw_Interpretor& , - Standard_Integer theArgNb, - Standard_CString* ) -{ - if (theArgNb > 1) - { - std::cout << "Error: wrong syntax!\n"; - return 1; - } - - Handle(AIS_InteractiveContext) aCtx; - Handle(V3d_View) aView; - if (!getCtxAndView (aCtx, aView)) - { - return 1; - } - - aCtx->ClearActiveAreas (aView); - return 0; - -} static Standard_Integer VDispSensi (Draw_Interpretor& , Standard_Integer theArgNb, Standard_CString* ) @@ -735,17 +690,16 @@ static int VDir (Draw_Interpretor& theDI, //============================================================================== //function : VSelPrecision -//purpose : To set the selection precision mode and tolerance value -//Draw arg : Selection precision mode (0 for window, 1 for view) and tolerance -// value (integer number of pixel for window mode, double value of -// sensitivity for view mode). Without arguments the function just -// prints the current precision mode and the corresponding tolerance. +//purpose : To set the selection tolerance value +//Draw arg : Selection tolerance value (real value determining the width and +// height of selecting frustum bases). Without arguments the function +// just prints current tolerance. //============================================================================== static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { - if( argc > 3 ) + if( argc > 2 ) { - di << "Use: " << argv[0] << " [precision_mode [tolerance_value]]\n"; + di << "Use: " << argv[0] << " [tolerance_value]\n"; return 1; } @@ -755,38 +709,17 @@ static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char if( argc == 1 ) { - StdSelect_SensitivityMode aMode = aContext->SensitivityMode(); - if( aMode == StdSelect_SM_WINDOW ) - { - Standard_Integer aPixelTolerance = aContext->PixelTolerance(); - di << "Precision mode : 0 (window)\n"; - di << "Pixel tolerance : " << aPixelTolerance << "\n"; - } - else if( aMode == StdSelect_SM_VIEW ) - { - Standard_Real aSensitivity = aContext->Sensitivity(); - di << "Precision mode : 1 (view)\n"; - di << "Sensitivity : " << aSensitivity << "\n"; - } + Standard_Real aPixelTolerance = aContext->PixelTolerance(); + di << "Precision mode : 0 (window)\n"; + di << "Pixel tolerance : " << aPixelTolerance << "\n"; } - else if( argc > 1 ) + else if (argc == 2) { - StdSelect_SensitivityMode aMode = ( StdSelect_SensitivityMode )Draw::Atoi( argv[1] ); - aContext->SetSensitivityMode( aMode ); - if( argc > 2 ) - { - if( aMode == StdSelect_SM_WINDOW ) - { - Standard_Integer aPixelTolerance = Draw::Atoi( argv[2] ); - aContext->SetPixelTolerance( aPixelTolerance ); - } - else if( aMode == StdSelect_SM_VIEW ) - { - Standard_Real aSensitivity = Draw::Atof( argv[2] ); - aContext->SetSensitivity( aSensitivity ); - } - } + + Standard_Integer aPixelTolerance = Draw::Atoi (argv[1]); + aContext->SetPixelTolerance (aPixelTolerance); } + return 0; } @@ -4082,23 +4015,25 @@ static Standard_Integer VState (Draw_Interpretor& theDI, { theDI << "Detected entities:\n"; Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector(); - for (aSelector->Init(); aSelector->More(); aSelector->Next()) + for (aSelector->InitDetected(); aSelector->MoreDetected(); aSelector->NextDetected()) { - Handle(SelectBasics_SensitiveEntity) anEntity = aSelector->Primitive (0); - Standard_Real aMatchDMin = 0.0; - Standard_Real aMatchDepth = Precision::Infinite(); - anEntity->Matches (aSelector->LastPickingArguments(), aMatchDMin, aMatchDepth); - + const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity(); Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId()); Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()); - - const gp_Lin aLine = aSelector->LastPickingArguments().PickLine(); - const gp_Pnt aPnt = aLine.Location().Translated (gp_Vec (aLine.Direction()) * aMatchDepth); + SelectMgr_SelectingVolumeManager aMgr = anObj->HasTransformation() ? aSelector->GetManager().Transform (anObj->InversedTransformation()) + : aSelector->GetManager(); + SelectBasics_PickResult aResult; + anEntity->Matches (aMgr, aResult); + NCollection_Vec3 aDetectedPnt = aMgr.DetectedPoint (aResult.Depth()); TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj); aName.LeftJustify (20, ' '); char anInfoStr[512]; - Sprintf (anInfoStr, " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f", aMatchDepth, aMatchDMin, aPnt.X(), aPnt.Y(), aPnt.Z()); + Sprintf (anInfoStr, + " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f", + aResult.Depth(), + aResult.DistToGeomCenter(), + aDetectedPnt.x(), aDetectedPnt.y(), aDetectedPnt.z()); theDI << " " << aName << anInfoStr << " (" << anEntity->DynamicType()->Name() << ")" @@ -4815,6 +4750,129 @@ static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a return 0; } +//============================================================================== +//function : VLoadSelection +//purpose : Adds given objects to map of AIS and loads selection primitives for them +//============================================================================== +static Standard_Integer VLoadSelection (Draw_Interpretor& /*theDi*/, + Standard_Integer theArgNb, + const char** theArgVec) +{ + if (theArgNb < 2) + { + std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n"; + return 1; + } + + Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); + if (aCtx.IsNull()) + { + ViewerTest::ViewerInit(); + aCtx = ViewerTest::GetAISContext(); + } + + // Parse input arguments + TColStd_SequenceOfAsciiString aNamesOfIO; + Standard_Boolean isLocal = Standard_False; + for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) + { + const TCollection_AsciiString aName = theArgVec[anArgIter]; + TCollection_AsciiString aNameCase = aName; + aNameCase.LowerCase(); + if (aNameCase == "-local") + { + isLocal = Standard_True; + } + else + { + aNamesOfIO.Append (aName); + } + } + + if (aNamesOfIO.IsEmpty()) + { + std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n"; + return 1; + } + + // Prepare context + if (isLocal && !aCtx->HasOpenedContext()) + { + aCtx->OpenLocalContext (Standard_False); + } + else if (!isLocal && aCtx->HasOpenedContext()) + { + aCtx->CloseAllContexts (Standard_False); + } + + // Load selection of interactive objects + for (Standard_Integer anIter = 1; anIter <= aNamesOfIO.Length(); ++anIter) + { + const TCollection_AsciiString& aName = aNamesOfIO.Value (anIter); + + const Handle(AIS_InteractiveObject)& aShape = GetMapOfAIS().IsBound2 (aName) ? + Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName)) : GetAISShapeFromName (aName.ToCString()); + + if (!aShape.IsNull()) + { + if (!GetMapOfAIS().IsBound2 (aName)) + { + GetMapOfAIS().Bind (aShape, aName); + } + + aCtx->Load (aShape, -1, Standard_False); + aCtx->Activate (aShape, aShape->SelectionMode(), Standard_True); + } + } + + return 0; +} + +//============================================================================== +//function : VAutoActivateSelection +//purpose : Activates or deactivates auto computation of selection +//============================================================================== +static int VAutoActivateSelection (Draw_Interpretor& theDi, + Standard_Integer theArgNb, + const char** theArgVec) +{ + + if (theArgNb > 2) + { + std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n"; + return 1; + } + + Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); + if (aCtx.IsNull()) + { + ViewerTest::ViewerInit(); + aCtx = ViewerTest::GetAISContext(); + } + + if (theArgNb == 1) + { + TCollection_AsciiString aSelActivationString; + if (aCtx->GetAutoActivateSelection()) + { + aSelActivationString.Copy ("ON"); + } + else + { + aSelActivationString.Copy ("OFF"); + } + + theDi << "Auto activation of selection is: " << aSelActivationString << "\n"; + } + else + { + Standard_Boolean toActivate = Draw::Atoi (theArgVec[1]); + aCtx->SetAutoActivateSelection (toActivate); + } + + return 0; +} + //============================================================================== //function : ViewerTest::Commands //purpose : Add all the viewer command in the Draw_Interpretor @@ -5015,14 +5073,6 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) "\n\t\t: Where style is: 0 = EMPTY, 1 = HOLLOW, 2 = HATCH, 3 = SOLID, 4 = HIDDENLINE.", __FILE__,VSetInteriorStyle,group); - theCommands.Add("vardis", - "vardis : display activeareas", - __FILE__,VDispAreas,group); - - theCommands.Add("varera", - "varera : erase activeareas", - __FILE__,VClearAreas,group); - theCommands.Add("vsensdis", "vardisp : display active entities", __FILE__,VDispSensi,group); @@ -5031,7 +5081,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) __FILE__,VClearSensi,group); theCommands.Add("vselprecision", - "vselprecision : vselprecision [precision_mode [tolerance_value]]", + "vselprecision : vselprecision [tolerance_value]", __FILE__,VSelPrecision,group); theCommands.Add("vperf", @@ -5127,6 +5177,18 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) theCommands.Add("vpickselected", "vpickselected [name]: extract selected shape.", __FILE__, VPickSelected, group); + theCommands.Add ("vloadselection", + "vloadselection [-context] [name1] ... [nameN] : allows to load selection" + "\n\t\t: primitives for the shapes with names given without displaying them." + "\n\t\t: -local - open local context before selection computation", + __FILE__, VLoadSelection, group); + + theCommands.Add ("vautoactivatesel", + "vautoactivatesel [0|1] : manage or display the option to automatically" + "\n\t\t: activate selection for newly displayed objects" + "\n\t\t: [0|1] - turn off | on auto activation of selection", + __FILE__, VAutoActivateSelection, group); + } //===================================================================== diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index e422a01f6e..dc578081d1 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -1743,10 +1743,7 @@ static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection)); aPlane->SetSize (aSizeX, aSizeY); - if (isUpdate) - { - aContextAIS->Update (aPlane, Standard_True); - } + aContextAIS->Update (aPlane, isUpdate); return 0; } @@ -3842,7 +3839,7 @@ static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, return 1; // TCL_ERROR } // Check argumnets - if (argc != 6) + if (argc != 6 && argc != 7) { std::cout << "vconnect error: expect at least 5 arguments\n"; return 1; // TCL_ERROR @@ -3879,6 +3876,7 @@ static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, return 1; // TCL_ERROR } anOriginObject = new AIS_Shape (aTDShape); + GetMapOfAIS().Bind (anOriginObject, anOriginObjectName); } // Get location data @@ -3911,6 +3909,14 @@ static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, // Bind connected object to its name GetMapOfAIS().Bind (aConnected, aName); + if (argc == 7) + { + TCollection_AsciiString anArg = argv[6]; + anArg.LowerCase(); + if (anArg == "-nodisplay") + return 0; + } + // Display connected object TheAISContext()->Display (aConnected); @@ -3988,7 +3994,7 @@ static Standard_Integer VDisconnect (Draw_Interpretor& di, anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (anObject)); } - anAssembly->Disconnect (anIObj); + aContext->Disconnect (anAssembly, anIObj); aContext->UpdateCurrentViewer(); return 0; @@ -5999,8 +6005,9 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) __FILE__, VConnect, group); theCommands.Add("vconnectto", - "vconnectto : instance_name Xo Yo Zo object" - " Makes an instance 'instance_name' of 'object' with position (Xo Yo Zo).", + "vconnectto : instance_name Xo Yo Zo object [-nodisplay]" + " Makes an instance 'instance_name' of 'object' with position (Xo Yo Zo)." + "\n\t\t: -nodisplay - only creates interactive object, but not displays it", __FILE__, VConnectTo,group); theCommands.Add("vdisconnect", diff --git a/src/ViewerTest/ViewerTest_RelationCommands.cxx b/src/ViewerTest/ViewerTest_RelationCommands.cxx index 6f44d217b8..befd5d89f6 100644 --- a/src/ViewerTest/ViewerTest_RelationCommands.cxx +++ b/src/ViewerTest/ViewerTest_RelationCommands.cxx @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -90,8 +89,6 @@ extern Handle(AIS_InteractiveContext)& TheAISContext (); static gp_Pnt Get3DPointAtMousePosition() { Handle(V3d_View) aView = ViewerTest::CurrentView(); - static Select3D_Projector aProjector; - aProjector.SetView (aView); Standard_Real xv,yv,zv; aView->Proj (xv,yv,zv); diff --git a/src/Voxel/Voxel_Prs.cdl b/src/Voxel/Voxel_Prs.cdl index 3bdc3cdac1..af5eaea468 100644 --- a/src/Voxel/Voxel_Prs.cdl +++ b/src/Voxel/Voxel_Prs.cdl @@ -108,7 +108,7 @@ is protected; ComputeSelection(me : mutable; - theSelection : Selection from SelectMgr; + theSelection : Selection from SelectMgr; theMode : Integer from Standard) is private; diff --git a/tests/bugs/modalg_2/bug22781_2 b/tests/bugs/modalg_2/bug22781_2 index 1d2703a655..20d20f76da 100755 --- a/tests/bugs/modalg_2/bug22781_2 +++ b/tests/bugs/modalg_2/bug22781_2 @@ -15,7 +15,7 @@ vinit vdisplay result vfit vsetdispmode 0 -vselect 290 135 +vselect 289 135 set length 5.82393 -set only_screen 0 \ No newline at end of file +set only_screen 0 diff --git a/tests/bugs/modalg_2/bug22781_4 b/tests/bugs/modalg_2/bug22781_4 index 496fa0521f..ec128f56c2 100755 --- a/tests/bugs/modalg_2/bug22781_4 +++ b/tests/bugs/modalg_2/bug22781_4 @@ -15,7 +15,7 @@ vinit vdisplay result vfit vsetdispmode 1 -vselect 290 135 +vselect 289 135 set length 5.82393 set only_screen 0 diff --git a/tests/bugs/vis/bug23012 b/tests/bugs/vis/bug23012 index 84fbd1176c..143dc1a8f0 100755 --- a/tests/bugs/vis/bug23012 +++ b/tests/bugs/vis/bug23012 @@ -21,8 +21,7 @@ stepread [locate_data_file OCC23012-Sample_9.stp] b * vdisplay a_1 b_1 vsetdispmode a_1 1 vsetdispmode b_1 1 -vselprecision -vselprecision 1 0.1 +vselprecision 0 set ColorBefore [vreadpixel ${x1} ${y1} rgb] diff --git a/tests/bugs/vis/bug23539_2 b/tests/bugs/vis/bug23539_2 index a7c3ce6116..bb10a4e5d6 100644 --- a/tests/bugs/vis/bug23539_2 +++ b/tests/bugs/vis/bug23539_2 @@ -15,7 +15,7 @@ vdisplay a b vfit vselmode 2 1 vselect 0 0 -vselect 60 300 +vselect 58 300 vselect 300 200 300 60 400 60 407 150 1 set NbSelected1 [vnbselected] @@ -30,4 +30,4 @@ if { ${NbSelected1} != 12 } { puts "Error : (case 2)" } -set only_screen 1 \ No newline at end of file +set only_screen 1 diff --git a/tests/bugs/vis/bug23649_3 b/tests/bugs/vis/bug23649_3 index dced33d705..0b7cbb4b5a 100644 --- a/tests/bugs/vis/bug23649_3 +++ b/tests/bugs/vis/bug23649_3 @@ -21,7 +21,7 @@ vfit #select the first shape vselect 70 230 #select the second shape -vselect 200 360 1 +vselect 200 358 1 vmoveto 0 0 vdump ${anImage1} @@ -30,5 +30,5 @@ vmoveto 70 230 vdump ${anImage2} #highlight the second edge - it should NOT be highlightable by default -vmoveto 200 360 -vdump ${anImage3} \ No newline at end of file +vmoveto 200 358 +vdump ${anImage3} diff --git a/tests/bugs/vis/bug23649_4 b/tests/bugs/vis/bug23649_4 index 9292942e86..845286ff94 100644 --- a/tests/bugs/vis/bug23649_4 +++ b/tests/bugs/vis/bug23649_4 @@ -20,7 +20,7 @@ vfit #select the first shape vselect 70 230 #select the second shape -vselect 200 360 1 +vselect 200 358 1 vmoveto 0 0 #enable 'highlight selected' mode @@ -31,5 +31,5 @@ vmoveto 70 230 vdump ${anImage1} #highlight the second edge - it should be highlightable by default -vmoveto 200 360 -vdump ${anImage2} \ No newline at end of file +vmoveto 200 358 +vdump ${anImage2} diff --git a/tests/bugs/vis/bug24389 b/tests/bugs/vis/bug24389 index 1c6d69f85b..eaa670ffa4 100644 --- a/tests/bugs/vis/bug24389 +++ b/tests/bugs/vis/bug24389 @@ -192,7 +192,7 @@ check_picking $pick_coord $check_coord "diameter dimension (diam3)" check_cross_picking $pick_coord diam3 "diameter dimension (diam3)" # check sensitives "rad1" -set pick_coord { { 287 157 } { 326 165 } } +set pick_coord { { 287 157 } { 326 164 } } set check_coord { 287 157 } check_picking $pick_coord $check_coord "radius dimension (rad1)" check_cross_picking $pick_coord rad1 "radius dimension (rad1)" diff --git a/tests/bugs/vis/bug24564 b/tests/bugs/vis/bug24564 index 7d7f315e9c..85f09be384 100644 --- a/tests/bugs/vis/bug24564 +++ b/tests/bugs/vis/bug24564 @@ -33,7 +33,7 @@ puts "Testing box selection over the plane in axonometry projection:" vaxo vfit -vmoveto 199 200 +vmoveto 200 200 if { "[vreadpixel 199 200 rgb name]" != "CYAN1" } { puts "Error : The box is not selectable!" } diff --git a/tests/bugs/vis/bug24569 b/tests/bugs/vis/bug24569 index 0c8316268d..e3f081880e 100644 --- a/tests/bugs/vis/bug24569 +++ b/tests/bugs/vis/bug24569 @@ -30,6 +30,7 @@ puts "Testing of plane sensitivity update:" vchangeplane pl1 x=-150 y=150 z=0 sx=10 sy=10 vupdate pl1 +vzrange 230.36270740666069 409.91874112463427 vmoveto 200 240 checkcolor 199 23 0 1 0 diff --git a/tests/bugs/vis/bug24623_1 b/tests/bugs/vis/bug24623_1 new file mode 100644 index 0000000000..f83d251a06 --- /dev/null +++ b/tests/bugs/vis/bug24623_1 @@ -0,0 +1,95 @@ +puts "============" +puts "OCC24623_1" +puts "============" +puts "" +####################################################################### +puts "Visualization - improve selection mechanism" +# tests performance of selection algorithm. Creates a grid of spheres with +# size DISCRETISATION * DISCRETISATION. To get representative performance +# test results, increase the size of grid in DISCRETISATION and check time +# measurments in comparsion to previous OCCT versions. You may also check +# the time of selection when all BVH trees are built via uncommenting +# the code in "Start building all trees" section. +####################################################################### + +set DISCRETISATION 10 +set RADIUS 100 + +pload ALL + +set aStep [expr $RADIUS * 0.1] + +# unset aNames +list aNames +set aX 0 +set aY 0 +for {set i 0} {$i < $DISCRETISATION} {incr i} { + for {set j 0} {$j < $DISCRETISATION} {incr j} { + set aCurrName "sph" + append aCurrName [expr $i * $DISCRETISATION + $j] + lappend aNames $aCurrName + psphere $aCurrName $RADIUS + set aX [expr $i * ($aStep + $RADIUS)] + set aY [expr - $j * ($aStep + $RADIUS)] + ttranslate $aCurrName $aX $aY 0 + } +} + +set aSpheresNbInfo "Total spheres number:" +append aSpheresNbInfo [expr $DISCRETISATION * $DISCRETISATION] +puts $aSpheresNbInfo + +vinit +set aMemInit [meminfo h] +puts "Initial mem: [expr $aMemInit / (1024 * 1024)] MiB ([expr $aMemInit])" +vsetdispmode 1 +set aMemInit [meminfo h] +vdisplay {*}$aNames +vfit + +puts "Selection of spheres without BVH trees built:" +chrono aTimer reset +chrono aTimer start +vmoveto 224 269 +chrono aTimer stop +chrono aTimer show + +puts "" +puts "Applying the transformations..." +vtranslateview 1 0 0 +vrotate 100 100 100 + +puts "" +puts "Selection time with transformations applied without BVH built:" +chrono aTimer reset +chrono aTimer start +vmoveto 102 224 +chrono aTimer stop +chrono aTimer show + +# puts "" +# puts "Start building all trees..." +# vtop +# vfit +# set aStartPt [expr round(400 / double($DISCRETISATION)) + 5] +# set aPtStep [expr round(double(round(100*(400 / double($DISCRETISATION))))/100 * 2)] +# for {set i 0} {$i < $DISCRETISATION / 2} {incr i} { +# for {set j 0} {$j < $DISCRETISATION / 2} {incr j} { +# set aX [expr $aStartPt + $i * $aPtStep] +# set aY [expr $aStartPt + $j * $aPtStep] +# vmoveto $aX $aY 1 +# } +# } + +# puts "" +# puts "Selection time with all BVHs built:" +# chrono aTimer reset +# chrono aTimer start +# vmoveto 200 200 +# chrono aTimer stop +# chrono aTimer show + +set aMemSel [meminfo h] +puts "Selection mem: [expr $aMemSel / (1024 * 1024)] MiB ([expr $aMemSel])" + +checkcolor 115 221 0 1 1 diff --git a/tests/bugs/vis/bug24623_2 b/tests/bugs/vis/bug24623_2 new file mode 100644 index 0000000000..784cb7fee0 --- /dev/null +++ b/tests/bugs/vis/bug24623_2 @@ -0,0 +1,74 @@ +puts "============" +puts "OCC24623_2" +puts "============" +puts "" +####################################################################### +puts "Visualization - improve selection mechanism" +# tests performance of selection algorithm. Creates a spiral via polyline +# and checks its selection in neutral point. For representative result, +# increase the number of points in POINTS_NUM and check time measurments +# in comparsion to previous OCCT versions. +####################################################################### + +set POINTS_NUM 1000 +set STEP 0.3 + +pload ALL + +set aCoef 0.2 +set aZ 0 +# unset aPointCoords +list aPointCoords +for {set i 0} {$i < $POINTS_NUM} {incr i} { + set aX [expr $aCoef * $aZ * cos($aZ)] + set aY [expr $aCoef * $aZ * sin($aZ)] + set aZ [expr $aZ + $STEP] + lappend aPointCoords $aX + lappend aPointCoords $aY + lappend aPointCoords $aZ +} + +vinit +set aMemInit [meminfo h] +puts "Initial mem: [expr $aMemInit / (1024 * 1024)] MiB ([expr $aMemInit])" +polyline p {*}$aPointCoords +vdisplay p + +vfit + +puts "Selection time before the transformations:" +chrono aTimer reset +chrono aTimer start +vmoveto 223 236 +chrono aTimer stop +chrono aTimer show +vmoveto 0 0 +chrono aTimer reset +chrono aTimer start +vmoveto 223 236 +chrono aTimer stop +chrono aTimer show + +puts "" +puts "Applying transformations..." +vtranslateview 1 0 0 +vrotate 100 100 100 + +puts "" +puts "Selection time after the transformations:" +chrono aTimer reset +chrono aTimer start +vmoveto 115 160 +chrono aTimer stop +chrono aTimer show +vmoveto 0 0 +chrono aTimer reset +chrono aTimer start +vmoveto 115 160 +chrono aTimer stop +chrono aTimer show + +set aMemSel [meminfo h] +puts "Selection mem: [expr $aMemSel / (1024 * 1024)] MiB ([expr $aMemSel])" + +checkcolor 131 195 0 1 1 diff --git a/tests/bugs/vis/bug24623_3 b/tests/bugs/vis/bug24623_3 new file mode 100644 index 0000000000..451488e55a --- /dev/null +++ b/tests/bugs/vis/bug24623_3 @@ -0,0 +1,51 @@ +puts "============" +puts "OCC24623_3" +puts "============" +puts "" +####################################################################### +puts "Visualization - improve selection mechanism" +# tests memory leaks in creation of selection primitives for connected +# interactive objects: checks that there is no "dead links" in removing +# Select3D_BVHPrimitiveContent +####################################################################### + +puts "" +pload MODELING VISUALIZATION +psphere s 0.5 +tclean s +incmesh s 0.001 +trinfo s + +set aMemInit [meminfo h] + +set aNb 1000 + +# display as copies +eval compound [lrepeat $aNb s] ss +explode ss +for {set i 1} {$i <= $aNb} {incr i} { vloadselection ss_${i}; vsetlocation -noupdate ss_${i} 0 0 s } +vfit +set aMemSel1 [meminfo h] +vclear +set aMemClear1 [meminfo h] + +# display as connected instances of single presentation +vconnectto i_1 0 0 0 s -nodisplay +vloadselection i_1 +for {set i 2} {$i < $aNb} {incr i} { vconnectto i_${i} ${i} 0 0 i_1 -nodisplay; vloadselection i_${i} } +set aMemSel2 [meminfo h] +vclear +set aMemClear2 [meminfo h] + +puts "Initial memory : [expr $aMemInit / (1024 * 1024)] MiB" +puts "Compute selection (simple) : [expr $aMemSel1 / (1024 * 1024)] MiB" +puts "Clearing (simple) : [expr $aMemClear1 / (1024 * 1024)] MiB" +puts "Compute selection (connected): [expr $aMemSel2 / (1024 * 1024)] MiB" +puts "Clearing (connected) : [expr $aMemClear2 / (1024 * 1024)] MiB" + +set aRatio [expr $aMemClear2 / double($aMemClear1)] + +# check if the memory difference is greater than 10% +if {[expr $aRatio > 1.1]} { + puts "Error : TEST FAILED" +} diff --git a/tests/bugs/vis/bug24623_4 b/tests/bugs/vis/bug24623_4 new file mode 100644 index 0000000000..2f1615d262 --- /dev/null +++ b/tests/bugs/vis/bug24623_4 @@ -0,0 +1,43 @@ +puts "============" +puts "OCC24623_4" +puts "============" +puts "" +####################################################################### +puts "Visualization - improve selection mechanism" +# tests memory leaks in creation of selection primitives for connected +# interactive objects: checks that there is no "dead links" to reference +# interactives after its clearing +####################################################################### + +puts "" +pload MODELING VISUALIZATION +psphere s 0.5 +tclean s +incmesh s 0.001 +trinfo s +vinit +vclear + +set aMemInit [meminfo h] +set anIterNb 100 + +for {set anIterCount 0} {$anIterCount < $anIterNb} {incr anIterCount} { + set aNb 11 + + vconnectto i_1 0 0 0 s -nodisplay + vloadselection i_1 + for {set i 2} {$i < $aNb} {incr i} { vconnectto i_${i} ${i} 0 0 i_1 -nodisplay; vloadselection i_${i} } + vclear +} + +set aMemClear [meminfo h] + +puts "Initial memory : [expr $aMemInit / (1024 * 1024)] MiB" +puts "Clearing : [expr $aMemClear / (1024 * 1024)] MiB" + +set aRatio [expr $aMemClear / double($aMemInit)] + +# check if the memory difference is greater than 20% +if {[expr $aRatio > 1.2]} { + puts "Error : TEST FAILED" +} diff --git a/tests/bugs/vis/bug25098 b/tests/bugs/vis/bug25098 index 60b59351d7..dec8510ac4 100644 --- a/tests/bugs/vis/bug25098 +++ b/tests/bugs/vis/bug25098 @@ -8,17 +8,17 @@ puts "" proc ParseEntityInfo {theInfoString} { set aStringArr [split $theInfoString " "] + set isEdgeInfo 0 set aDepth "" - set aDistance "" set aPoint "" set aType "" set aSize [llength $aStringArr] for {set aIdx 0} {$aIdx < $aSize} {incr aIdx} { set aItem [lindex $theInfoString $aIdx] - if {[string compare $aItem "Depth:"] == 0} { - set aDepth [string trim [lindex $theInfoString [expr $aIdx + 1]]] - } elseif {[string compare $aItem "Distance:"] == 0} { - set aDistance [string trim [lindex $theInfoString [expr $aIdx + 1]]] + if {[string compare $aItem "e"] == 0} { + set isEdgeInfo 1 + } elseif {[string compare $aItem "Depth:"] == 0} { + set aDepth [string trim [lindex $theInfoString [expr $aIdx + 1]]] } elseif {[string compare $aItem "Point:"] == 0} { set aPoint [string trim [lindex $theInfoString [expr $aIdx + 1]]] append aPoint " " @@ -30,7 +30,7 @@ proc ParseEntityInfo {theInfoString} { } } - return [list $aDepth $aDistance $aPoint $aType] + return [list $isEdgeInfo $aDepth $aPoint $aType] } pload VISUALIZATION MODELING @@ -53,33 +53,56 @@ vmoveto 240 300 set aOut [split [vstate -entities] "\n"] # compare parameters of detected match: depth, distance and point -set aEdgeInfoList [ParseEntityInfo [lindex $aOut 1]] -set aWireInfoList [ParseEntityInfo [lindex $aOut 3]] -for {set aIdx 0} {$aIdx < 3} {incr aIdx} { - if {[string equal [lindex $aEdgeInfoList $aIdx] [lindex $aWireInfoList $aIdx]] == 0} { +set anInfoList1Idx 1 +set anInfoList2Idx -1 +set anInfoList1 [ParseEntityInfo [lindex $aOut $anInfoList1Idx]] +if {[string equal [lindex $anInfoList1 0] "1"]} { + set anInfoList2Idx 3 +} else { + set anInfoList2Idx 4 +} +set anInfoList2 [ParseEntityInfo [lindex $aOut $anInfoList2Idx]] +for {set aIdx 1} {$aIdx < 3} {incr aIdx} { + if {[string equal [lindex $anInfoList1 $aIdx] [lindex $anInfoList2 $aIdx]] == 0} { set aDebugInfo "Characteristics are not equal at value nb: " append aDebugInfo [expr $aIdx + 1] puts $aDebugInfo set aDebugInfo "The values are: " - append aDebugInfo [lindex $aEdgeInfoList $aIdx] + append aDebugInfo [lindex $anInfoList1 $aIdx] append aDebugInfo " and " - append aDebugInfo [lindex $aWireInfoList $aIdx] + append aDebugInfo [lindex $anInfoList2 $aIdx] puts $aDebugInfo puts "ERROR" puts "" } } +set anEdgeSensitiveType "" +set aWireSensitiveType "" +set anEdgeTypeStringNb -1 +set aWireTypeStringNb -1 +if {[string equal [lindex $anInfoList1 0] "1"]} { + set anEdgeTypeStringNb 2 + set anEdgeSensitiveType [lindex $anInfoList1 3] + set aWireTypeStringNb 4 + set aWireSensitiveType [lindex $anInfoList2 3] +} else { + set anEdgeTypeStringNb 5 + set anEdgeSensitiveType [lindex $anInfoList2 3] + set aWireTypeStringNb 2 + set aWireSensitiveType [lindex $anInfoList1 3] +} + # checks that edge e is represented by correct shape and sensitive entity -if {[string equal [lindex $aEdgeInfoList 3] "(Select3D_SensitiveSegment)"] == 0} { +if {[string equal $anEdgeSensitiveType "(Select3D_SensitiveSegment)"] == 0} { puts "Wrong sensitive for segment! Value is: " - puts [lindex $aEdgeInfoList 3] + puts $anEdgeSensitiveType puts "Must be: (Select3D_SensitiveSegment)" puts "ERROR" puts "" } -set aEdgeType [string trim [lindex $aOut 2]] +set aEdgeType [string trim [lindex $aOut $anEdgeTypeStringNb]] if {[string equal $aEdgeType "Detected Shape: BRep_TEdge"] == 0} { puts "Wrong type of edge! Value is: " puts $aEdgeType @@ -89,15 +112,15 @@ if {[string equal $aEdgeType "Detected Shape: BRep_TEdge"] == 0} { } # checks that wire b_5 is represented by correct shape and sensitive entity -if {[string equal [lindex $aWireInfoList 3] "(Select3D_SensitiveWire)"] == 0} { +if {[string equal $aWireSensitiveType "(Select3D_SensitiveWire)"] == 0} { puts "Wrong sensitive for wire! Value is: " - puts [lindex $aWireInfoList 3] + puts $aWireSensitiveType puts "Must be: (Select3D_SensitiveWire)" puts "ERROR" puts "" } -set aWireType [string trim [lindex $aOut 4]] +set aWireType [string trim [lindex $aOut $aWireTypeStringNb]] if {[string equal $aWireType "Detected Shape: TopoDS_TWire"] == 0} { puts "Wrong type of wire! Value is: " puts $aWireType @@ -106,10 +129,10 @@ if {[string equal $aWireType "Detected Shape: TopoDS_TWire"] == 0} { puts "" } -set aWireSensitiveType [string trim [lindex $aOut 5]] -if {[string equal $aWireSensitiveType "Detected Child: Select3D_SensitiveCurve"] == 0} { +set aWireChildSensitiveType [string trim [lindex $aOut [expr $aWireTypeStringNb + 1]]] +if {[string equal $aWireChildSensitiveType "Detected Child: Select3D_SensitiveCurve"] == 0} { puts "Wrong type of wire's inner sensitive! Value is: " - puts $aWireSensitiveType + puts $aWireChildSensitiveType puts "Must be: Detected Child: Select3D_SensitiveCurve" puts "ERROR" } diff --git a/tests/bugs/vis/bug25532 b/tests/bugs/vis/bug25532 index fbcf94a6ab..14d888e409 100644 --- a/tests/bugs/vis/bug25532 +++ b/tests/bugs/vis/bug25532 @@ -19,6 +19,7 @@ vaxo vcaps -vbo 0 vsetdispmode 1 vdefaults absDefl=1.0 +vautoactivatesel 0 set aMemInit [meminfo h] set aNb 1000 diff --git a/tests/bugs/vis/bug25552 b/tests/bugs/vis/bug25552 index 1a518e5fff..673506af9e 100644 --- a/tests/bugs/vis/bug25552 +++ b/tests/bugs/vis/bug25552 @@ -31,7 +31,7 @@ vaspects -noupdate b2 -setcolor GREEN vfit # b1 should be displayed only in View1 verase -inview b1 -vmoveto 250 350 +vmoveto 250 347 set aColorV2B1 [vreadpixel 50 250 rgb name] if { $aColorV2B1 != "BLACK" } { diff --git a/tests/bugs/vis/bug25723 b/tests/bugs/vis/bug25723 index f725c5e85c..dd3e7f25ed 100644 --- a/tests/bugs/vis/bug25723 +++ b/tests/bugs/vis/bug25723 @@ -5,7 +5,7 @@ puts "============" puts "" set x_start_sel_coord 100 -set y_start_sel_coord 100 +set y_start_sel_coord 104 set x_end_sel_coord 400 set y_end_sel_coord 400 diff --git a/tests/bugs/vis/bug25935 b/tests/bugs/vis/bug25935 index 8eeeb401bf..640146b626 100644 --- a/tests/bugs/vis/bug25935 +++ b/tests/bugs/vis/bug25935 @@ -1,6 +1,5 @@ puts "============" puts "CR25935" -puts "Visualization, TKV3d, Exception when displaying shell in the viewer" puts "============" puts "" diff --git a/tests/v3d/edge_face/E2 b/tests/v3d/edge_face/E2 index 771fabf979..5f32178310 100644 --- a/tests/v3d/edge_face/E2 +++ b/tests/v3d/edge_face/E2 @@ -42,5 +42,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_face/E9 b/tests/v3d/edge_face/E9 index 4344ea8f5a..0eea14ffa1 100644 --- a/tests/v3d/edge_face/E9 +++ b/tests/v3d/edge_face/E9 @@ -42,7 +42,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -53,6 +53,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 +vselect 237 95 vmoveto 0 0 diff --git a/tests/v3d/edge_face/J4 b/tests/v3d/edge_face/J4 index fa7a6560fb..2de1363779 100644 --- a/tests/v3d/edge_face/J4 +++ b/tests/v3d/edge_face/J4 @@ -43,5 +43,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_face/K2 b/tests/v3d/edge_face/K2 index 7d81c1e88d..6f85b8c792 100644 --- a/tests/v3d/edge_face/K2 +++ b/tests/v3d/edge_face/K2 @@ -43,7 +43,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -54,6 +54,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 +vselect 237 95 vmoveto 0 0 diff --git a/tests/v3d/edge_face/O6 b/tests/v3d/edge_face/O6 index cef19cee5a..2d063c7487 100644 --- a/tests/v3d/edge_face/O6 +++ b/tests/v3d/edge_face/O6 @@ -45,5 +45,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_face/P4 b/tests/v3d/edge_face/P4 index b3fcd32a7d..a97ca75f27 100644 --- a/tests/v3d/edge_face/P4 +++ b/tests/v3d/edge_face/P4 @@ -45,7 +45,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 270 326 1 vmoveto 0 0 @@ -56,6 +56,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 1 +vselect 237 95 1 vmoveto 0 0 diff --git a/tests/v3d/edge_solid/E2 b/tests/v3d/edge_solid/E2 index 53f8cd8e1a..1c003ffb3e 100644 --- a/tests/v3d/edge_solid/E2 +++ b/tests/v3d/edge_solid/E2 @@ -42,5 +42,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_solid/E9 b/tests/v3d/edge_solid/E9 index 1c9fc7178a..9396cf4ae7 100644 --- a/tests/v3d/edge_solid/E9 +++ b/tests/v3d/edge_solid/E9 @@ -42,7 +42,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -53,6 +53,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 +vselect 237 100 vmoveto 0 0 diff --git a/tests/v3d/edge_solid/J4 b/tests/v3d/edge_solid/J4 index fa9eff5695..7198c4f797 100644 --- a/tests/v3d/edge_solid/J4 +++ b/tests/v3d/edge_solid/J4 @@ -43,5 +43,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_solid/K2 b/tests/v3d/edge_solid/K2 index 1c52ccc36b..47ff98d83e 100644 --- a/tests/v3d/edge_solid/K2 +++ b/tests/v3d/edge_solid/K2 @@ -43,7 +43,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -54,6 +54,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 +vselect 237 100 vmoveto 0 0 diff --git a/tests/v3d/edge_solid/O6 b/tests/v3d/edge_solid/O6 index 8042caa787..a6143b51c8 100644 --- a/tests/v3d/edge_solid/O6 +++ b/tests/v3d/edge_solid/O6 @@ -45,5 +45,5 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 diff --git a/tests/v3d/edge_solid/P4 b/tests/v3d/edge_solid/P4 index b4396bb43e..065f006d50 100644 --- a/tests/v3d/edge_solid/P4 +++ b/tests/v3d/edge_solid/P4 @@ -45,7 +45,7 @@ vmoveto 225 98 vmoveto 0 0 vmoveto 270 326 vmoveto 0 0 -vmoveto 341 111 +vmoveto 342 111 vmoveto 0 0 vselect 270 326 1 vmoveto 0 0 @@ -56,6 +56,6 @@ vfit vmoveto 0 0 vmoveto 310 87 vmoveto 0 0 -vselect 237 99 1 +vselect 237 100 1 vmoveto 0 0 diff --git a/tests/v3d/vertex_edge/E7 b/tests/v3d/vertex_edge/E7 index 75d8b4fea0..3cccf769a7 100644 --- a/tests/v3d/vertex_edge/E7 +++ b/tests/v3d/vertex_edge/E7 @@ -56,5 +56,5 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_edge/F1 b/tests/v3d/vertex_edge/F1 index 0218a6413a..c3fca24ff1 100644 --- a/tests/v3d/vertex_edge/F1 +++ b/tests/v3d/vertex_edge/F1 @@ -56,10 +56,10 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 vselect 406 44 vmoveto 0 0 -vselect 140 11 +vselect 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_edge/J9 b/tests/v3d/vertex_edge/J9 index 0b3a9dfab0..38d7f64693 100644 --- a/tests/v3d/vertex_edge/J9 +++ b/tests/v3d/vertex_edge/J9 @@ -58,5 +58,5 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_edge/K1 b/tests/v3d/vertex_edge/K1 index e793b7d8e8..6446e2b25e 100644 --- a/tests/v3d/vertex_edge/K1 +++ b/tests/v3d/vertex_edge/K1 @@ -58,6 +58,6 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_edge/K3 b/tests/v3d/vertex_edge/K3 index 91d4f80684..54ce7086a9 100644 --- a/tests/v3d/vertex_edge/K3 +++ b/tests/v3d/vertex_edge/K3 @@ -58,12 +58,12 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 -vselect 140 11 1 +vselect 141 11 1 vmoveto 0 0 diff --git a/tests/v3d/vertex_face/E7 b/tests/v3d/vertex_face/E7 index 6c8ff2ff54..c6cecddeb0 100644 --- a/tests/v3d/vertex_face/E7 +++ b/tests/v3d/vertex_face/E7 @@ -52,5 +52,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_face/F1 b/tests/v3d/vertex_face/F1 index 7d68360a3b..f1604cff6d 100644 --- a/tests/v3d/vertex_face/F1 +++ b/tests/v3d/vertex_face/F1 @@ -56,6 +56,6 @@ vmoveto 140 11 vmoveto 0 0 vselect 406 44 vmoveto 0 0 -vselect 140 11 +vselect 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_face/J9 b/tests/v3d/vertex_face/J9 index 686934edaf..6fdd582626 100644 --- a/tests/v3d/vertex_face/J9 +++ b/tests/v3d/vertex_face/J9 @@ -54,5 +54,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_face/K1 b/tests/v3d/vertex_face/K1 index 50d00873e9..e96419c95b 100644 --- a/tests/v3d/vertex_face/K1 +++ b/tests/v3d/vertex_face/K1 @@ -54,6 +54,6 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_face/K3 b/tests/v3d/vertex_face/K3 index 8a7e0e1c7f..576182cb20 100644 --- a/tests/v3d/vertex_face/K3 +++ b/tests/v3d/vertex_face/K3 @@ -54,12 +54,12 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 -vselect 140 11 1 +vselect 141 11 1 vmoveto 0 0 diff --git a/tests/v3d/vertex_solid/E7 b/tests/v3d/vertex_solid/E7 index a7c42f93a1..66a6229982 100644 --- a/tests/v3d/vertex_solid/E7 +++ b/tests/v3d/vertex_solid/E7 @@ -52,5 +52,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_solid/F1 b/tests/v3d/vertex_solid/F1 index a32a485d65..c4fb4a46af 100644 --- a/tests/v3d/vertex_solid/F1 +++ b/tests/v3d/vertex_solid/F1 @@ -52,10 +52,10 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 vselect 406 44 vmoveto 0 0 -vselect 140 11 +vselect 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_solid/J9 b/tests/v3d/vertex_solid/J9 index f9dbdf553e..8cccc59a30 100644 --- a/tests/v3d/vertex_solid/J9 +++ b/tests/v3d/vertex_solid/J9 @@ -54,5 +54,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_solid/K3 b/tests/v3d/vertex_solid/K3 index 6fe215e743..83971d9233 100644 --- a/tests/v3d/vertex_solid/K3 +++ b/tests/v3d/vertex_solid/K3 @@ -59,7 +59,7 @@ vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 vselect 406 44 1 -vmoveto 140 11 -vselect 140 11 1 +vmoveto 141 11 +vselect 141 11 1 vmoveto 0 0 diff --git a/tests/v3d/vertex_wire/E7 b/tests/v3d/vertex_wire/E7 index b11b981521..9038808e89 100644 --- a/tests/v3d/vertex_wire/E7 +++ b/tests/v3d/vertex_wire/E7 @@ -56,5 +56,5 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_wire/F1 b/tests/v3d/vertex_wire/F1 index 154f1d1fe9..3eda4d2e54 100644 --- a/tests/v3d/vertex_wire/F1 +++ b/tests/v3d/vertex_wire/F1 @@ -60,6 +60,6 @@ vmoveto 140 11 vmoveto 0 0 vselect 406 44 vmoveto 0 0 -vselect 140 11 +vselect 141 11 vmoveto 0 0 diff --git a/tests/v3d/vertex_wire/J9 b/tests/v3d/vertex_wire/J9 index be8a923a9c..59353e0760 100644 --- a/tests/v3d/vertex_wire/J9 +++ b/tests/v3d/vertex_wire/J9 @@ -58,5 +58,5 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 diff --git a/tests/v3d/vertex_wire/K3 b/tests/v3d/vertex_wire/K3 index be875aa50a..d26f3729ac 100644 --- a/tests/v3d/vertex_wire/K3 +++ b/tests/v3d/vertex_wire/K3 @@ -58,12 +58,12 @@ vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.88 vfit vmoveto 0 0 vmoveto 96 211 -vmoveto 140 11 +vmoveto 141 11 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 vselect 406 44 1 vmoveto 0 0 -vselect 140 11 1 +vselect 141 11 1 vmoveto 0 0 diff --git a/tests/v3d/wire/E9 b/tests/v3d/wire/E9 index e0ad8cc9f8..84392054c2 100644 --- a/tests/v3d/wire/E9 +++ b/tests/v3d/wire/E9 @@ -56,6 +56,6 @@ vmoveto 0 0 vmoveto 200 200 vmoveto 404 210 vmoveto 0 0 -vselect 220 97 +vselect 221 97 vmoveto 0 0 diff --git a/tests/v3d/wire/F1 b/tests/v3d/wire/F1 index 62c9f471c5..9f53647ab7 100644 --- a/tests/v3d/wire/F1 +++ b/tests/v3d/wire/F1 @@ -56,7 +56,7 @@ vmoveto 0 0 vmoveto 200 200 vmoveto 404 210 vmoveto 0 0 -vselect 220 97 +vselect 221 97 vmoveto 0 0 vselect 404 210 vmoveto 0 0 diff --git a/tests/v3d/wire/F2 b/tests/v3d/wire/F2 index 81b16c69e6..5253e7faff 100644 --- a/tests/v3d/wire/F2 +++ b/tests/v3d/wire/F2 @@ -56,7 +56,7 @@ vmoveto 0 0 vmoveto 200 200 vmoveto 404 210 vmoveto 0 0 -vselect 220 97 +vselect 221 97 vmoveto 0 0 vselect 404 210 vmoveto 0 0 diff --git a/tests/v3d/wire_solid/E2 b/tests/v3d/wire_solid/E2 index 9b88d6dd02..c93f4f8174 100644 --- a/tests/v3d/wire_solid/E2 +++ b/tests/v3d/wire_solid/E2 @@ -43,5 +43,5 @@ vmoveto 214 112 vmoveto 0 0 vmoveto 104 203 vmoveto 0 0 -vmoveto 209 35 +vmoveto 209 34 diff --git a/tests/v3d/wire_solid/E7 b/tests/v3d/wire_solid/E7 index 43afe2e59b..8c74847aee 100644 --- a/tests/v3d/wire_solid/E7 +++ b/tests/v3d/wire_solid/E7 @@ -43,7 +43,7 @@ vmoveto 214 112 vmoveto 0 0 vmoveto 104 203 vmoveto 0 0 -vmoveto 209 35 +vmoveto 209 34 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -52,5 +52,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 404 210 +vmoveto 405 210 diff --git a/tests/v3d/wire_solid/F1 b/tests/v3d/wire_solid/F1 index 4136dbe2d9..c050bf999d 100644 --- a/tests/v3d/wire_solid/F1 +++ b/tests/v3d/wire_solid/F1 @@ -43,7 +43,7 @@ vmoveto 214 112 vmoveto 0 0 vmoveto 104 203 vmoveto 0 0 -vmoveto 209 35 +vmoveto 209 34 vmoveto 0 0 vselect 0 0 vmoveto 0 0 @@ -52,10 +52,10 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 404 210 +vmoveto 405 210 vmoveto 0 0 vselect 220 97 vmoveto 0 0 -vselect 404 210 +vselect 405 210 vmoveto 0 0 diff --git a/tests/v3d/wire_solid/J4 b/tests/v3d/wire_solid/J4 index daa03cd486..0c24fe0e24 100644 --- a/tests/v3d/wire_solid/J4 +++ b/tests/v3d/wire_solid/J4 @@ -45,5 +45,5 @@ vmoveto 214 112 vmoveto 0 0 vmoveto 104 203 vmoveto 0 0 -vmoveto 209 35 +vmoveto 209 34 diff --git a/tests/v3d/wire_solid/J9 b/tests/v3d/wire_solid/J9 index 245893217c..56c072d065 100644 --- a/tests/v3d/wire_solid/J9 +++ b/tests/v3d/wire_solid/J9 @@ -45,7 +45,7 @@ vmoveto 214 112 vmoveto 0 0 vmoveto 104 203 vmoveto 0 0 -vmoveto 209 35 +vmoveto 209 34 vmoveto 0 0 vselect 104 203 1 vmoveto 0 0 @@ -54,5 +54,5 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 404 210 +vmoveto 405 210 diff --git a/tests/v3d/wire_solid/K3 b/tests/v3d/wire_solid/K3 index d568745431..54a045ad73 100644 --- a/tests/v3d/wire_solid/K3 +++ b/tests/v3d/wire_solid/K3 @@ -54,12 +54,12 @@ vmoveto 0 0 vviewparams -scale 6.063093 -proj -0.444872 -0.214876 0.86866 -up 0.109494 -0.886324 -0.185966 -at 71.8115798514333 53.1349971091326 8.4539251074103 vfit vmoveto 0 0 -vmoveto 404 210 +vmoveto 405 210 vmoveto 0 0 vselect 220 97 1 vmoveto 0 0 vselect 220 97 1 vmoveto 0 0 -vselect 404 210 1 +vselect 405 210 1 vmoveto 0 0