0024623: Visualization - improve selection mechanism
authorvpa <vpa@opencascade.com>
Mon, 6 Apr 2015 09:31:00 +0000 (12:31 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 6 Apr 2015 14:27:38 +0000 (17:27 +0300)
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.

271 files changed:
samples/mfc/standard/01_Geometry/CMakeLists.txt
samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj
samples/mfc/standard/01_Geometry/adm/win/vc10/Geometry.vcxproj.filters
samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.cpp [deleted file]
samples/mfc/standard/01_Geometry/src/ISession2D/ISession2D_SensitiveCurve.h [deleted file]
samples/mfc/standard/01_Geometry/src/StdAfx.h
samples/mfc/standard/03_Viewer2d/src/StdAfx.h
samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp
samples/mfc/standard/05_ImportExport/src/StdAfx.h
samples/mfc/standard/06_Ocaf/src/StdAfx.h
samples/mfc/standard/08_HLR/src/StdAfx.h
samples/mfc/standard/09_Animation/src/AnimationView3D.cpp
samples/mfc/standard/09_Animation/src/StdAfx.h
samples/mfc/standard/10_Convert/src/WNT/OCCDemoView.cpp
samples/mfc/standard/Common/OCC_2dView.cpp
samples/mfc/standard/Common/OCC_3dView.cpp
samples/mfc/standard/Common/StdAfx.h
src/AIS/AIS_Axis.cxx
src/AIS/AIS_Chamf2dDimension.cxx
src/AIS/AIS_Chamf3dDimension.cxx
src/AIS/AIS_Circle.cxx
src/AIS/AIS_ConcentricRelation.cxx
src/AIS/AIS_ConnectedInteractive.cxx
src/AIS/AIS_Dimension.cxx
src/AIS/AIS_Dimension.hxx
src/AIS/AIS_EqualRadiusRelation.cxx
src/AIS/AIS_FixRelation.cxx
src/AIS/AIS_IdenticRelation.cxx
src/AIS/AIS_InteractiveContext.cdl
src/AIS/AIS_InteractiveContext.cxx
src/AIS/AIS_InteractiveContext_1.cxx
src/AIS/AIS_InteractiveContext_2.cxx
src/AIS/AIS_InteractiveObject.cdl
src/AIS/AIS_InteractiveObject.cxx
src/AIS/AIS_Line.cxx
src/AIS/AIS_LocalContext.cdl
src/AIS/AIS_LocalContext.cxx
src/AIS/AIS_LocalContext_1.cxx
src/AIS/AIS_MaxRadiusDimension.cxx
src/AIS/AIS_MidPointRelation.cxx
src/AIS/AIS_MinRadiusDimension.cxx
src/AIS/AIS_MultipleConnectedInteractive.cxx
src/AIS/AIS_OffsetDimension.cxx
src/AIS/AIS_ParallelRelation.cxx
src/AIS/AIS_PerpendicularRelation.cxx
src/AIS/AIS_Plane.lxx
src/AIS/AIS_PlaneTrihedron.cxx
src/AIS/AIS_SymmetricRelation.cxx
src/AIS/AIS_TangentRelation.cxx
src/BVH/BVH_BinnedBuilder.hxx
src/BVH/BVH_BinnedBuilder.lxx
src/BVH/BVH_SpatialMedianBuilder.hxx
src/BVH/BVH_SpatialMedianBuilder.lxx
src/IVtk/IVtk_IShapePickerAlgo.hxx
src/IVtk/IVtk_IView.hxx
src/IVtkOCC/IVtkOCC_SelectableObject.cxx
src/IVtkOCC/IVtkOCC_SelectableObject.hxx
src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx
src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx
src/IVtkOCC/IVtkOCC_ViewerSelector.cxx
src/IVtkOCC/IVtkOCC_ViewerSelector.hxx
src/IVtkVTK/IVtkVTK_View.cxx
src/IVtkVTK/IVtkVTK_View.hxx
src/MeshVS/FILES
src/MeshVS/MeshVS.cdl
src/MeshVS/MeshVS_DummySensitiveEntity.cdl [deleted file]
src/MeshVS/MeshVS_DummySensitiveEntity.cxx
src/MeshVS/MeshVS_DummySensitiveEntity.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_Mesh.cdl
src/MeshVS/MeshVS_SensitiveFace.cdl [deleted file]
src/MeshVS/MeshVS_SensitiveFace.cxx
src/MeshVS/MeshVS_SensitiveFace.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_SensitiveMesh.cdl [deleted file]
src/MeshVS/MeshVS_SensitiveMesh.cxx
src/MeshVS/MeshVS_SensitiveMesh.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_SensitivePolyhedron.cdl [deleted file]
src/MeshVS/MeshVS_SensitivePolyhedron.cxx
src/MeshVS/MeshVS_SensitivePolyhedron.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_SensitiveSegment.cdl [deleted file]
src/MeshVS/MeshVS_SensitiveSegment.cxx
src/MeshVS/MeshVS_SensitiveSegment.hxx [new file with mode: 0644]
src/PrsMgr/PrsMgr_PresentableObject.cdl
src/PrsMgr/PrsMgr_PresentableObject.cxx
src/PrsMgr/PrsMgr_PresentableObject.lxx
src/QABugs/QABugs_11.cxx
src/QABugs/QABugs_9.cxx
src/QABugs/QABugs_MyText.cdl
src/QABugs/QABugs_MyText.cxx
src/Select3D/FILES
src/Select3D/Select3D.cdl
src/Select3D/Select3D_BVHPrimitiveContent.cxx [new file with mode: 0644]
src/Select3D/Select3D_BVHPrimitiveContent.hxx [new file with mode: 0644]
src/Select3D/Select3D_BndBox3d.hxx [new file with mode: 0644]
src/Select3D/Select3D_BoundarySensitivePointSet.cxx [new file with mode: 0644]
src/Select3D/Select3D_BoundarySensitivePointSet.hxx [new file with mode: 0644]
src/Select3D/Select3D_Box2d.hxx [deleted file]
src/Select3D/Select3D_EntitySequence.hxx [new file with mode: 0644]
src/Select3D/Select3D_ISensitivePointSet.hxx [new file with mode: 0644]
src/Select3D/Select3D_InteriorSensitivePointSet.cxx [new file with mode: 0644]
src/Select3D/Select3D_InteriorSensitivePointSet.hxx [new file with mode: 0644]
src/Select3D/Select3D_Pnt2d.hxx [deleted file]
src/Select3D/Select3D_PointData.hxx
src/Select3D/Select3D_Projector.cdl [deleted file]
src/Select3D/Select3D_Projector.cxx [deleted file]
src/Select3D/Select3D_Projector.lxx [deleted file]
src/Select3D/Select3D_SensitiveBox.cdl [deleted file]
src/Select3D/Select3D_SensitiveBox.cxx
src/Select3D/Select3D_SensitiveBox.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveBox.lxx [deleted file]
src/Select3D/Select3D_SensitiveCircle.cdl [deleted file]
src/Select3D/Select3D_SensitiveCircle.cxx
src/Select3D/Select3D_SensitiveCircle.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveCurve.cdl [deleted file]
src/Select3D/Select3D_SensitiveCurve.cxx
src/Select3D/Select3D_SensitiveCurve.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveCurve.lxx [deleted file]
src/Select3D/Select3D_SensitiveEntity.cdl [deleted file]
src/Select3D/Select3D_SensitiveEntity.cxx
src/Select3D/Select3D_SensitiveEntity.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveEntity.lxx [deleted file]
src/Select3D/Select3D_SensitiveFace.cdl [deleted file]
src/Select3D/Select3D_SensitiveFace.cxx
src/Select3D/Select3D_SensitiveFace.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveGroup.cdl [deleted file]
src/Select3D/Select3D_SensitiveGroup.cxx
src/Select3D/Select3D_SensitiveGroup.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveGroup.lxx
src/Select3D/Select3D_SensitivePoint.cdl [deleted file]
src/Select3D/Select3D_SensitivePoint.cxx
src/Select3D/Select3D_SensitivePoint.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitivePoly.cdl [deleted file]
src/Select3D/Select3D_SensitivePoly.cxx
src/Select3D/Select3D_SensitivePoly.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitivePoly.lxx
src/Select3D/Select3D_SensitiveSegment.cdl [deleted file]
src/Select3D/Select3D_SensitiveSegment.cxx
src/Select3D/Select3D_SensitiveSegment.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveSegment.lxx
src/Select3D/Select3D_SensitiveSet.cxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveSet.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveTriangle.cdl [deleted file]
src/Select3D/Select3D_SensitiveTriangle.cxx
src/Select3D/Select3D_SensitiveTriangle.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveTriangulation.cdl [deleted file]
src/Select3D/Select3D_SensitiveTriangulation.cxx
src/Select3D/Select3D_SensitiveTriangulation.hxx [new file with mode: 0644]
src/Select3D/Select3D_SensitiveTriangulation.lxx
src/Select3D/Select3D_SensitiveWire.cdl [deleted file]
src/Select3D/Select3D_SensitiveWire.cxx
src/Select3D/Select3D_SensitiveWire.hxx [new file with mode: 0644]
src/Select3D/Select3D_TypeOfSensitivity.hxx [new file with mode: 0644]
src/SelectBasics/FILES
src/SelectBasics/SelectBasics.cdl
src/SelectBasics/SelectBasics_BasicTool.cdl [deleted file]
src/SelectBasics/SelectBasics_BasicTool.cxx [deleted file]
src/SelectBasics/SelectBasics_EntityOwner.cxx
src/SelectBasics/SelectBasics_PickArgs.hxx [deleted file]
src/SelectBasics/SelectBasics_PickResult.hxx [new file with mode: 0644]
src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx [new file with mode: 0644]
src/SelectBasics/SelectBasics_SensitiveEntity.cdl
src/SelectBasics/SelectBasics_SensitiveEntity.cxx
src/SelectBasics/SelectBasics_SensitiveEntity.lxx
src/SelectBasics/SelectBasics_SortAlgo.cdl [deleted file]
src/SelectBasics/SelectBasics_SortAlgo.cxx [deleted file]
src/SelectMgr/FILES
src/SelectMgr/SelectMgr.cdl
src/SelectMgr/SelectMgr_BaseFrustum.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_BaseFrustum.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_EntityOwner.cxx
src/SelectMgr/SelectMgr_Frustum.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_Frustum.lxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_FrustumBuilder.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_FrustumBuilder.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_RectangularFrustum.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_RectangularFrustum.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectableObject.cdl
src/SelectMgr/SelectMgr_SelectableObject.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectableObjectSet.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_Selection.cdl [deleted file]
src/SelectMgr/SelectMgr_Selection.cxx
src/SelectMgr/SelectMgr_Selection.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_Selection.lxx
src/SelectMgr/SelectMgr_SelectionManager.cdl
src/SelectMgr/SelectMgr_SelectionManager.cxx
src/SelectMgr/SelectMgr_SensitiveEntity.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SensitiveEntity.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SequenceOfSelection.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_TriangularFrustum.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_TriangularFrustum.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_VectorTypes.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_ViewerSelector.cdl [deleted file]
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.hxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_ViewerSelector.lxx
src/StdSelect/FILES [new file with mode: 0644]
src/StdSelect/StdSelect.cdl
src/StdSelect/StdSelect.cxx
src/StdSelect/StdSelect_BRepSelectionTool.cdl
src/StdSelect/StdSelect_BRepSelectionTool.cxx
src/StdSelect/StdSelect_ViewerSelector3d.cdl [deleted file]
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/StdSelect/StdSelect_ViewerSelector3d.hxx [new file with mode: 0644]
src/StdSelect/StdSelect_ViewerSelector3d.lxx
src/ViewerTest/ViewerTest.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
src/ViewerTest/ViewerTest_RelationCommands.cxx
src/Voxel/Voxel_Prs.cdl
tests/bugs/modalg_2/bug22781_2
tests/bugs/modalg_2/bug22781_4
tests/bugs/vis/bug23012
tests/bugs/vis/bug23539_2
tests/bugs/vis/bug23649_3
tests/bugs/vis/bug23649_4
tests/bugs/vis/bug24389
tests/bugs/vis/bug24564
tests/bugs/vis/bug24569
tests/bugs/vis/bug24623_1 [new file with mode: 0644]
tests/bugs/vis/bug24623_2 [new file with mode: 0644]
tests/bugs/vis/bug24623_3 [new file with mode: 0644]
tests/bugs/vis/bug24623_4 [new file with mode: 0644]
tests/bugs/vis/bug25098
tests/bugs/vis/bug25532
tests/bugs/vis/bug25552
tests/bugs/vis/bug25723
tests/bugs/vis/bug25935
tests/v3d/edge_face/E2
tests/v3d/edge_face/E9
tests/v3d/edge_face/J4
tests/v3d/edge_face/K2
tests/v3d/edge_face/O6
tests/v3d/edge_face/P4
tests/v3d/edge_solid/E2
tests/v3d/edge_solid/E9
tests/v3d/edge_solid/J4
tests/v3d/edge_solid/K2
tests/v3d/edge_solid/O6
tests/v3d/edge_solid/P4
tests/v3d/vertex_edge/E7
tests/v3d/vertex_edge/F1
tests/v3d/vertex_edge/J9
tests/v3d/vertex_edge/K1
tests/v3d/vertex_edge/K3
tests/v3d/vertex_face/E7
tests/v3d/vertex_face/F1
tests/v3d/vertex_face/J9
tests/v3d/vertex_face/K1
tests/v3d/vertex_face/K3
tests/v3d/vertex_solid/E7
tests/v3d/vertex_solid/F1
tests/v3d/vertex_solid/J9
tests/v3d/vertex_solid/K3
tests/v3d/vertex_wire/E7
tests/v3d/vertex_wire/F1
tests/v3d/vertex_wire/J9
tests/v3d/vertex_wire/K3
tests/v3d/wire/E9
tests/v3d/wire/F1
tests/v3d/wire/F2
tests/v3d/wire_solid/E2
tests/v3d/wire_solid/E7
tests/v3d/wire_solid/F1
tests/v3d/wire_solid/J4
tests/v3d/wire_solid/J9
tests/v3d/wire_solid/K3

index fbe3267..051970a 100644 (file)
@@ -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)
index 7788b35..512ec89 100644 (file)
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
-    <ClCompile Include="..\..\..\src\ISession2D\ISession2D_SensitiveCurve.cpp">
-      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
-      <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
-      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
-      <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</BrowseInformation>
-      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
     <ClCompile Include="..\..\..\src\ISession2D\ISession_Curve.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     <ClInclude Include="..\..\..\src\GeometryView2D.h" />
     <ClInclude Include="..\..\..\src\GeomSources.h" />
     <ClInclude Include="..\..\..\src\ISession2D\ISession2D_Curve.h" />
-    <ClInclude Include="..\..\..\src\ISession2D\ISession2D_SensitiveCurve.h" />
     <ClInclude Include="..\..\..\src\ISession2D\ISession_Curve.h" />
     <ClInclude Include="..\..\..\src\ISession2D\ISession_Direction.h" />
     <ClInclude Include="..\..\..\src\ISession2D\ISession_Point.h" />
index 812b3b1..185f27e 100644 (file)
@@ -54,9 +54,6 @@
     <ClCompile Include="..\..\..\src\ISession2D\ISession2D_Curve.cpp">
       <Filter>Source Files\ISession2d</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\src\ISession2D\ISession2D_SensitiveCurve.cpp">
-      <Filter>Source Files\ISession2d</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\..\src\ISession2D\ISession_Curve.cpp">
       <Filter>Source Files\ISession2d</Filter>
     </ClCompile>
     <ClInclude Include="..\..\..\src\ISession2D\ISession2D_Curve.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\src\ISession2D\ISession2D_SensitiveCurve.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\..\src\ISession2D\ISession_Curve.h">
       <Filter>Header Files</Filter>
     </ClInclude>
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 (executable)
index 01a5c84..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright:  Matra-Datavision 1995
-
-#include "stdafx.h"
-
-#include <ISession2D_SensitiveCurve.h>
-#include <GCPnts_TangentialDeflection.hxx>
-#include <SelectBasics_BasicTool.hxx>
-
-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 (executable)
index 6daa3b4..0000000
+++ /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 <Standard_Macro.hxx>
-#include <Standard_DefineHandle.hxx>
-
-
-#include <Standard_Integer.hxx>
-#include <gp_Pnt2d.hxx>
-#include <Select3D_SensitiveEntity.hxx>
-#include <SelectBasics_EntityOwner.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_Real.hxx>
-class SelectBasics_EntityOwner;
-class gp_Pnt2d;
-#include <SelectBasics_ListOfBox2d.hxx>
-#include "TColgp_HArray1OfPnt2d.hxx"
-#include <Geom2d_Curve.hxx>
-
-
-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
index 0a91b8f..50c8ddd 100755 (executable)
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SelectionManager.hxx>
-#include <SelectBasics_BasicTool.hxx>
 #include <ShapeAnalysis_FreeBounds.hxx>
 #include <ShapeFix_Shape.hxx>
 #include <StdSelect_ViewerSelector3d.hxx>
index 257f72d..25e3a10 100755 (executable)
 #include <Quantity_Factor.hxx>
 #include <Quantity_Length.hxx>
 #include <Quantity_PlaneAngle.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
-#include <SelectBasics_BasicTool.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SelectableObject.hxx>
index 1a019cf..785de91 100755 (executable)
@@ -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
     {
index debe0e2..7eee7ac 100755 (executable)
@@ -99,8 +99,6 @@
 #include <Quantity_PhysicalQuantity.hxx>
 #include <Quantity_PlaneAngle.hxx>
 #include <Quantity_TypeOfColor.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
index 89edb6e..6b2e5a3 100755 (executable)
@@ -96,8 +96,6 @@
 #include <Quantity_PhysicalQuantity.hxx>
 #include <Quantity_PlaneAngle.hxx>
 #include <Quantity_TypeOfColor.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
index 540aa5a..32c76a5 100755 (executable)
 #include <Quantity_PhysicalQuantity.hxx>
 #include <Quantity_PlaneAngle.hxx>
 #include <Quantity_TypeOfColor.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
index 09f8aec..ec6d921 100755 (executable)
@@ -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
     {
index 4e70e4c..a2a7663 100755 (executable)
@@ -164,8 +164,6 @@ enum CurrentAction3d {
 #include <Quantity_PhysicalQuantity.hxx>
 #include <Quantity_PlaneAngle.hxx>
 #include <Quantity_TypeOfColor.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_Selection.hxx>
index 3cd62d5..cd2c43c 100755 (executable)
@@ -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
   {
index 439c7e0..8209ab8 100755 (executable)
@@ -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
   {
index a8e1093..3f4a882 100755 (executable)
@@ -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
     {
index 2415a82..122108e 100755 (executable)
@@ -83,7 +83,6 @@
 #include <Prs3d_TextAspect.hxx>
 #include <Prs3d_Text.hxx>
 
-#include <Select3D_ListOfSensitive.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveGroup.hxx>
index 9202253..f7ad1d1 100644 (file)
@@ -23,6 +23,7 @@
 #include <Graphic3d_Structure.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <SelectBasics_EntityOwner.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <StdPrs_Curve.hxx>
index 4a36258..878843a 100644 (file)
@@ -25,6 +25,7 @@
 #include <Prs3d_Drawer.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 
 #include <TopoDS.hxx>
index 0405edc..3d7d183 100644 (file)
@@ -25,6 +25,7 @@
 #include <Prs3d_Drawer.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 
 #include <TopoDS.hxx>
index f7c4ac3..e2dae1d 100644 (file)
@@ -22,6 +22,7 @@
 #include <Graphic3d_Structure.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveCircle.hxx>
 #include <StdPrs_DeflectionCurve.hxx>
 #include <TopoDS.hxx>
index 9fb1036..f209345 100644 (file)
@@ -19,6 +19,7 @@
 #include <AIS_ConcentricRelation.ixx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveCircle.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 
index 9a4fef7..79e1228 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <AIS_ConnectedInteractive.ixx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <Geom_Transformation.hxx>
 
@@ -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);
     }
index 34cf02b..a09e1a1 100755 (executable)
@@ -50,8 +50,6 @@
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SequenceOfOwner.hxx>
-#include <Select3D_ListIteratorOfListOfSensitive.hxx>
-#include <Select3D_ListOfSensitive.hxx>
 #include <Select3D_SensitiveCircle.hxx>
 #include <Select3D_SensitiveGroup.hxx>
 #include <Select3D_SensitiveCurve.hxx>
index 03ad7d0..6992339 100755 (executable)
@@ -32,7 +32,6 @@
 #include <Prs3d_LineAspect.hxx>
 #include <Prs3d_Presentation.hxx>
 #include <Prs3d_TextAspect.hxx>
-#include <Select3D_ListOfSensitive.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <Standard.hxx>
 #include <TCollection_ExtendedString.hxx>
index ff6e431..553cd05 100644 (file)
@@ -26,6 +26,7 @@
 #include <Geom_Circle.hxx>
 #include <ElCLib.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <Precision.hxx>
index 57d1236..f9ae72a 100644 (file)
@@ -23,6 +23,7 @@
 #include <TopAbs_ShapeEnum.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 
 #include <BRep_Tool.hxx>
index 9947d35..6031f37 100644 (file)
@@ -40,6 +40,7 @@
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 
 #include <TColStd_ListIteratorOfListOfTransient.hxx>
 
index 6398d8c..2270226 100644 (file)
@@ -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;
index ffe89cf..3c3d400 100644 (file)
@@ -43,6 +43,7 @@
 #include <Prs3d_PlaneAspect.hxx>
 #include <PrsMgr_PresentableObject.hxx>
 #include <Standard_Atomic.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
 #include <UnitsAPI.hxx>
 
 #include <AIS_Trihedron.hxx>
@@ -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;
+}
index b8423a9..d82f767 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <AIS_InteractiveContext.jxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
 #include <AIS_Selection.hxx>
 #include <AIS_StatusOfDetection.hxx>
 #include <AIS_StatusOfPick.hxx>
@@ -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;
 
index 10c9c5f..0fef964 100644 (file)
@@ -29,6 +29,8 @@
 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
 #include <AIS_Selection.hxx>
 
+#include <StdSelect_ViewerSelector3d.hxx>
+
 //=======================================================================
 //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 "<<myCurLocalIndex<<endl;
@@ -123,17 +115,11 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index,
  // the only open local context is closed...
  if(myLocalContexts.Extent()==1 && GoodIndex == myCurLocalIndex){
    
-   Standard_Boolean updateproj = !(myLocalContexts(myCurLocalIndex)->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 "<<endl;
  }
@@ -146,11 +132,6 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index,
    // the current is closed...
    if(GoodIndex==myCurLocalIndex){
      myCurLocalIndex = HighestIndex();
-     const Handle(AIS_LocalContext)& LocCtx = myLocalContexts(myCurLocalIndex);
-     if (!LocCtx->HasSameProjector (VS->Projector()))
-     {
-       LocCtx->MainSelector()->UpdateConversion();
-     }
    }
    else if(debugmode)
      cout<<"a No Current Local Context WasClosed"<<endl;
@@ -177,7 +158,6 @@ void AIS_InteractiveContext::CloseAllContexts(const Standard_Boolean updateviewe
   
   ResetOriginalState(Standard_False);
 
-  myMainSel->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();
index 5134ed6..601a008 100644 (file)
@@ -581,6 +581,12 @@ is
        ---Purpose: Retrieves current polygon offsets settings from <myDrawer>.
        ---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;
index 639c75c..0256b6e 100644 (file)
@@ -33,6 +33,8 @@
 #include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <Graphic3d_AspectText3d.hxx>
+#include <Graphic3d_BndBox4f.hxx>
+#include <Graphic3d_CStructure.hxx>
 #include <Graphic3d_Group.hxx>
 #include <Graphic3d_Structure.hxx>
 
@@ -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<Standard_Real> (aBndBox.CornerMin().x()),
+                        static_cast<Standard_Real> (aBndBox.CornerMin().y()),
+                        static_cast<Standard_Real> (aBndBox.CornerMin().z()),
+                        static_cast<Standard_Real> (aBndBox.CornerMax().x()),
+                        static_cast<Standard_Real> (aBndBox.CornerMax().y()),
+                        static_cast<Standard_Real> (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<Standard_Real> (aBndBox.CornerMin().x()),
+                          static_cast<Standard_Real> (aBndBox.CornerMin().y()),
+                          static_cast<Standard_Real> (aBndBox.CornerMin().z()),
+                          static_cast<Standard_Real> (aBndBox.CornerMax().x()),
+                          static_cast<Standard_Real> (aBndBox.CornerMax().y()),
+                          static_cast<Standard_Real> (aBndBox.CornerMax().z()));
+        return;
+      }
+    }
+  }
+}
index 08e5a03..8cc19f8 100644 (file)
@@ -23,6 +23,7 @@
 #include <Graphic3d_Structure.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <StdPrs_Curve.hxx>
 #include <Geom_Line.hxx>
index 2177f65..5a9b104 100644 (file)
@@ -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 <aPrj>
-    --          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&
 
index c62f846..6549e9a 100644 (file)
@@ -33,6 +33,7 @@
 #include <Prs3d_Presentation.hxx>
 #include <Aspect_TypeOfMarker.hxx>
 #include <StdSelect_ShapeTypeFilter.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
 #include <AIS_Selection.hxx>
 #include <V3d_Viewer.hxx>
 #include <V3d_View.hxx>
@@ -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();
 }
index cbf86d8..c5a9217 100644 (file)
 #include <Graphic3d_ArrayOfTriangles.hxx>
 #include <Graphic3d_Group.hxx>
 #include <Select3D_SensitiveTriangulation.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <NCollection_Map.hxx>
 #include <Visual3d_View.hxx>
 
-#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SequenceOfOwner.hxx>
 #include <OSD_Environment.hxx>
@@ -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<Handle(SelectBasics_EntityOwner)>::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;
index 6ef3c3a..695ec44 100644 (file)
@@ -30,6 +30,7 @@
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
index 8ec70b4..f17c0cf 100644 (file)
@@ -38,6 +38,7 @@
 #include <Geom_TrimmedCurve.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 
index 39f8426..861f2d0 100644 (file)
@@ -31,6 +31,7 @@
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
index 4cde3df..82ac598 100644 (file)
@@ -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 <Handle(SelectMgr_EntityOwner), Handle(SelectMgr_EntityOwner)> 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);
     }
   }
 }
index a799327..376bf99 100644 (file)
@@ -35,6 +35,7 @@
 #include <Select3D_SensitiveBox.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <StdPrs_WFDeflectionShape.hxx>
 #include <TColStd_Array2OfReal.hxx>
 #include <TCollection_ExtendedString.hxx>
index 7b47bb2..0a9fbe7 100644 (file)
@@ -33,6 +33,7 @@
 #include <AIS.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveBox.hxx>
 
index 5ef137a..d964b2f 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <Select3D_SensitiveSegment.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
index 8d955d4..90df732 100644 (file)
@@ -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;
 }
index dfc50e8..b9b5795 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <DsgPrs_DatumPrs.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitivePoint.hxx>
 #include <Geom_Axis1Placement.hxx>
index dc822b5..0f51dce 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <gce_MakeLin.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <Precision.hxx>
index a86fa6a..e656533 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <Select3D_SensitiveSegment.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
 
 #include <BRep_Tool.hxx>
 #include <TopoDS.hxx>
index 06a3228..ee2c447 100644 (file)
@@ -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 <BVH_BinnedBuilder.lxx>
index 7ad8c22..9ab554b 100644 (file)
 // =======================================================================
 template<class T, int N, int Bins>
 BVH_BinnedBuilder<T, N, Bins>::BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize,
-                                                  const Standard_Integer theMaxTreeDepth)
+                                                  const Standard_Integer theMaxTreeDepth,
+                                                  const Standard_Boolean theToUseMainAxis)
 : BVH_QueueBuilder<T, N> (theLeafNodeSize,
-                          theMaxTreeDepth)
+                          theMaxTreeDepth),
+  myUseMainAxis (theToUseMainAxis)
 {
   //
 }
@@ -129,6 +131,46 @@ namespace BVH
 
 #include <limits>
 
+namespace BVH
+{
+  template<class T, int N>
+  struct BVH_AxisSelector
+  {
+    typedef typename BVH::VectorType<T, N>::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<class T>
+  struct BVH_AxisSelector<T, 2>
+  {
+    typedef typename BVH::VectorType<T, 2>::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<T, N, Bins>::BuildNode (BVH_Set<T, N>*         theSet,
 
   Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
 
+  Standard_Integer aMainAxis = BVH::BVH_AxisSelector<T, N>::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<T, N>::Get (aSize, anAxis) <= BVH::THE_NODE_MIN_SIZE)
       continue;
index 9b4e148..5c7726a 100644 (file)
@@ -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();
index 69d26a9..7be3a73 100644 (file)
 // =======================================================================
 template<class T, int N>
 BVH_SpatialMedianBuilder<T, N>::BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize,
-                                                          const Standard_Integer theMaxTreeDepth)
+                                                          const Standard_Integer theMaxTreeDepth,
+                                                          const Standard_Boolean theToUseMainAxis)
 : BVH_BinnedBuilder<T, N, 2> (theLeafNodeSize,
-                              theMaxTreeDepth)
+                              theMaxTreeDepth,
+                              theToUseMainAxis)
 {
   //
 }
index aa36105..6b94213 100644 (file)
@@ -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.
index c974e5f..b123016 100644 (file)
@@ -19,6 +19,8 @@
 #include <IVtk_Interface.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
+#include <gp_Pnt.hxx>
+#include <Graphic3d_Mat4d.hxx>
 
 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 )
 };
 
index 7fb153e..57f2790 100644 (file)
@@ -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;
+}
index cfab9de..b344cf4 100644 (file)
@@ -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: 
index f3c1f65..24255ce 100644 (file)
@@ -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;
         }
index f25621c..93a79a1 100644 (file)
@@ -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();
 
index 94b93ce..c3fb9e5 100644 (file)
@@ -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<Standard_Real> (theXPix),
+                      static_cast<Standard_Real> (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();
+
+  mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box);
+  theView->GetCamera (aProj, anOrient, isOrthographic);
+  mySelectingVolumeMgr.SetCamera (aProj, anOrient, isOrthographic);
 
-  gp_Pnt2d aP2d_1, aP2d_2;
-  theView->DisplayToWorld (aDispPnt1, aWorldPnt1);
-  theView->DisplayToWorld (aDispPnt2, aWorldPnt2);
+  theView->GetWindowSize (aWidth, aHeight);
+  mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
 
-  myPrj->Project (gp_Pnt (aWorldPnt1), aP2d_1);
-  myPrj->Project (gp_Pnt (aWorldPnt2), aP2d_2);
+  theView->GetViewport (aX, aY, aVpWidth, aVpHeight);
+  mySelectingVolumeMgr.SetViewport (aX, aY, aVpWidth, aVpHeight);
 
-  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()));
+  gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXMin),
+                         static_cast<Standard_Real> (theYMin));
+  gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXMax),
+                         static_cast<Standard_Real> (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: 
-
-  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));
+  mySelectingVolumeMgr.BuildSelectingVolume (aPolyline);
 
-    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;
-
-  if (!myselections.IsBound (theSelection))
-  {
-    myselections.Bind (theSelection, 0);
-  } 
-  else if (myselections (theSelection) != 0)
-  {
-    myselections (theSelection) = 0;
-  }
-  if (theIsAutomaticProj)
+  for (theSelection->Init(); theSelection->More(); theSelection->Next())
   {
-    Convert (theSelection);
+    theSelection->Sensitive()->SetActiveForSelection();
   }
+
+  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;
 }
index 4f54853..e1b36fd 100644 (file)
@@ -17,7 +17,6 @@
 #define __IVTKOCC_VIEWERSELECTOR_H__
 
 #include <IVtk_IView.hxx>
-#include <Select3D_Projector.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_ViewerSelector.hxx>
 
@@ -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;
 };
 
index e7db1cf..39cff7c 100644 (file)
@@ -18,6 +18,7 @@
 #include <vtkAutoInit.h>
 #include <vtkCamera.h>
 #include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
 #include <vtkTransform.h>
 
 // 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];
+}
index b66af7f..7f62fe3 100644 (file)
@@ -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
index d85be04..fbc8f8c 100755 (executable)
@@ -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
index 1e0d85c..2835b67 100644 (file)
@@ -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 (file)
index f419867..0000000
+++ /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;
index 17d08f3..16c53ea 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_DummySensitiveEntity.ixx>
+#include <MeshVS_DummySensitiveEntity.hxx>
 
-//================================================================
-// Function : Constructor MeshVS_DummySensitiveEntity
-// Purpose  :
-//================================================================
-MeshVS_DummySensitiveEntity::MeshVS_DummySensitiveEntity
-  ( const Handle(SelectBasics_EntityOwner)& OwnerId )
-: SelectBasics_SensitiveEntity( OwnerId )
-{
-}
+#include <Bnd_Box2d.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
 
-//================================================================
-// Function : Areas
-// Purpose  :
-//================================================================
-void MeshVS_DummySensitiveEntity::Areas( SelectBasics_ListOfBox2d& )
-{
-}
+IMPLEMENT_STANDARD_HANDLE (MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity)
 
 //================================================================
-// Function : Matches
+// Function : Constructor MeshVS_DummySensitiveEntity
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const SelectBasics_PickArgs&,
-                                                       Standard_Real&,
-                                                       Standard_Real& )
-{
-  return Standard_False;
-}
+MeshVS_DummySensitiveEntity::MeshVS_DummySensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId)
+: SelectBasics_SensitiveEntity (theOwnerId)
+{}
 
 //================================================================
-// Function : Matches
+// Function : NbSubElements
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const Standard_Real,
-                                                       const Standard_Real,
-                                                       const Standard_Real,
-                                                       const Standard_Real,
-                                                       const Standard_Real )
+Standard_Integer MeshVS_DummySensitiveEntity::NbSubElements()
 {
-  return Standard_False;
+  return -1;
 }
 
 //================================================================
 // Function : Matches
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const TColgp_Array1OfPnt2d&,
-                                                       const Bnd_Box2d&,
-                                                       const Standard_Real )
+Standard_Boolean MeshVS_DummySensitiveEntity::Matches (SelectBasics_SelectingVolumeManager& /*theMgr*/,
+                                                       SelectBasics_PickResult& /*thePickResult*/)
 {
   return Standard_False;
 }
 
 //================================================================
-// Function : NeedsConversion
+// Function : BoundingBox
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::NeedsConversion() const
+Select3D_BndBox3d MeshVS_DummySensitiveEntity::BoundingBox()
 {
-  return Standard_False;
+  return Select3D_BndBox3d();
 }
 
 //================================================================
-// Function : Is3D
+// Function : ElementsNb
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::Is3D() const
-{
-  return Standard_True;
-}
+void MeshVS_DummySensitiveEntity::BVH()
+{}
 
 //================================================================
-// Function : MaxBoxes
+// Function : Clear
 // 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 (file)
index 0000000..6e74020
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+#include <SelectBasics_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <SelectBasics_SelectingVolumeManager.hxx>
+
+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
index 043d884..63c83be 100644 (file)
@@ -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 (file)
index 554327f..0000000
+++ /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;
index 872ff53..2a26ae7 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_SensitiveFace.ixx>
-
+#include <MeshVS_SensitiveFace.hxx>
+#include <SelectBasics_EntityOwner.hxx>
 #include <TColgp_Array1OfPnt.hxx>
-#include <Select3D_Projector.hxx>
-#include <CSLib_Class2d.hxx>
-#include <TopLoc_Location.hxx>
-
-//=======================================================================
-// 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 )
-{
-  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 );
-}
-
-//=======================================================================
-// 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 );
-}
+IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveFace, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveFace, Select3D_SensitiveEntity)
 
 //=======================================================================
-// name    : MeshVS_SensitiveFace::Matches
+// name    : MeshVS_SensitiveFace::MeshVS_SensitiveFace
 // Purpose :
 //=======================================================================
-Standard_Boolean MeshVS_SensitiveFace::Matches( const TColgp_Array1OfPnt2d& Polyline,
-                                                const Bnd_Box2d&            aBox,
-                                                const Standard_Real         aTol )
+MeshVS_SensitiveFace::MeshVS_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                            const TColgp_Array1OfPnt&               thePnts,
+                                            const Select3D_TypeOfSensitivity        theSensitivity)
+: Select3D_SensitiveFace (theOwnerId, thePnts, theSensitivity)
 {
-  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 );
+  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();
 
-  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 (file)
index 0000000..d7464e5
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <gp_Pnt.hxx>
+#include <Select3D_SensitiveFace.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Select3D_TypeOfSensitivity.hxx>
+
+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 (file)
index f96826a..0000000
+++ /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;
index 193b1b6..714ffa4 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_SensitiveMesh.ixx>
+#include <MeshVS_SensitiveMesh.hxx>
 
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HPackedMapOfInteger.hxx>
-#include <Select3D_Projector.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_EntityOwner.hxx>
 #include <TopLoc_Location.hxx>
 #include <MeshVS_DataSource.hxx>
 #include <MeshVS_MeshOwner.hxx>
+#include <NCollection_Vec4.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveMesh, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveMesh, Select3D_SensitiveEntity)
 
 //=======================================================================
 // name    : MeshVS_SensitiveMesh::MeshVS_SensitiveMesh
 //=======================================================================
 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
+// name    : GetConnected
 // Purpose :
 //=======================================================================
-Standard_Boolean MeshVS_SensitiveMesh::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                Standard_Real& theMatchDMin,
-                                                Standard_Real& theMatchDepth)
+Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected()
 {
-  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;
+  Handle(MeshVS_SensitiveMesh) aMeshEnt = new MeshVS_SensitiveMesh (myOwnerId);
+  return aMeshEnt;
 }
 
 //=======================================================================
-// name    : Matches
-// Purpose :
+// function : NbSubElements
+// purpose  : Returns the amount of mesh nodes
 //=======================================================================
-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)
+Standard_Integer MeshVS_SensitiveMesh::NbSubElements()
 {
-  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;
+  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();
 }
 
 //=======================================================================
-// name    : Matches
-// Purpose :
+// function : BoundingBox
+// purpose  : Returns bounding box of mesh
 //=======================================================================
-Standard_Boolean MeshVS_SensitiveMesh::Matches(const TColgp_Array1OfPnt2d& Polyline,
-                                              const Bnd_Box2d&            aBox,
-                                              const Standard_Real         aTol)
+Select3D_BndBox3d MeshVS_SensitiveMesh::BoundingBox()
 {
-  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;
+  return myBndBox;
 }
 
 //=======================================================================
-// name    : GetConnected
-// Purpose :
+// function : CenterOfGeometry
+// purpose  : Returns center of mesh
 //=======================================================================
-Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected( const TopLoc_Location& aLoc ) 
+gp_Pnt MeshVS_SensitiveMesh::CenterOfGeometry() const
 {
-  Handle(MeshVS_SensitiveMesh) aMeshEnt = new MeshVS_SensitiveMesh( myOwnerId );
-  if(HasLocation()) aMeshEnt->SetLocation( Location() );
-  aMeshEnt->UpdateLocation( aLoc );
-  return aMeshEnt;
-}
+  if (!myBndBox.IsValid())
+    return gp_Pnt (0.0, 0.0, 0.0);
 
-//==================================================
-// Function: ProjectOneCorner
-// Purpose :
-//==================================================
-void MeshVS_SensitiveMesh::ProjectOneCorner(const Handle(Select3D_Projector)& theProj,
-                                           const Standard_Real theX, 
-                                           const Standard_Real theY, 
-                                           const Standard_Real theZ)
-{
-  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 );
-}
-
-//==================================================
-// Function: Project
-// Purpose :
-//==================================================
-void MeshVS_SensitiveMesh::Project(const Handle(Select3D_Projector)& aProj)
-{
-  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);
-}
-
-//==================================================
-// Function: Areas 
-// Purpose :
-//==================================================
-void MeshVS_SensitiveMesh::Areas( SelectBasics_ListOfBox2d& aSeq )
-{
-  aSeq.Append(mybox2d);
+  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 (file)
index 0000000..f8a01f0
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <Bnd_Box.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Select3D_BndBox3d.hxx>
+
+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 (file)
index 20325d6..0000000
+++ /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;
-
index 80c443c..b2013e5 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_SensitivePolyhedron.ixx>
+#include <MeshVS_SensitivePolyhedron.hxx>
 
+#include <gp_Lin.hxx>
+#include <MeshVS_HArray1OfSequenceOfInteger.hxx>
 #include <MeshVS_Tool.hxx>
-#include <CSLib_Class2d.hxx>
-#include <ElCLib.hxx>
+#include <NCollection_Vec4.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
 
-//================================================================
-// 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 )
-{
-  Standard_Integer low = Nodes.Lower(), up = Nodes.Upper(), i;
-
-  myNodes   = new TColgp_HArray1OfPnt  ( low, up );
-  for( i=low; i<=up; i++ )
-    myNodes->SetValue( i, Nodes.Value( i ) );
-
-  myNodes2d = new TColgp_HArray1OfPnt2d( low, up );
-}
+IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitivePolyhedron, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitivePolyhedron, Select3D_SensitiveEntity)
 
 //================================================================
-// Function : Project
+// Function : Constructor MeshVS_SensitivePolyhedron
 // Purpose  :
 //================================================================
-void MeshVS_SensitivePolyhedron::Project( const Handle(Select3D_Projector)& aProjector )
+MeshVS_SensitivePolyhedron::MeshVS_SensitivePolyhedron (const Handle(SelectBasics_EntityOwner)& theOwner,
+                                                        const TColgp_Array1OfPnt& theNodes,
+                                                        const Handle(MeshVS_HArray1OfSequenceOfInteger)& theTopo)
+: Select3D_SensitiveEntity (theOwner),
+  myTopo (theTopo)
 {
-  if( myNodes.IsNull() || myNodes2d.IsNull() )
-    return;
-
-  Standard_Integer low = myNodes->Lower(),
-                   up  = myNodes->Upper();
-
-  gp_Pnt   pnt;
-  gp_Pnt2d proj;
+  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);
 
-  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 );
-
-  if( HasLocation() )
-    NewEnt->SetLocation( Location() );
-
-  NewEnt->UpdateLocation( aLocation );
+  Handle(MeshVS_SensitivePolyhedron) aNewEnt = new
+    MeshVS_SensitivePolyhedron (myOwnerId, myNodes->Array1(), myTopo);
 
-  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 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_Real aDepthMin = RealLast();
+  Standard_Real aDistToCOG = RealLast();
 
-  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++ )
+  for (MeshVS_PolyhedronVertsIter aIter (myTopology); aIter.More(); aIter.Next())
   {
-    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( j<C2 ? j+1 : C1 );
-
-      x1 = myNodes2d->Value( 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 )<Precision::Confusion() )
-      {
-        //vertical edge!!!
-
-        sort( y1, y2 );
-        if ( thePickArgs.Y() >= 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++;
-        }
-      }
+      aDepthMin = Min (aDepth, aDepthMin);
     }
-    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();
+  aDistToCOG = aDepthMin == RealLast() ? RealLast() : theMgr.DistToGeometryCenter (myCenter);
+  thePickResult = SelectBasics_PickResult (aDepthMin, aDistToCOG);
 
-  return myCenter.X()>=XMin-rTol && myCenter.X()<=XMax+rTol &&
-         myCenter.Y()>=YMin-rTol && myCenter.Y()<=YMax+rTol;
+  return aDepthMin != RealLast();
 }
 
-//================================================================
-// Function : Matches
-// Purpose  :
-//================================================================
-Standard_Boolean MeshVS_SensitivePolyhedron::Matches
-    ( const TColgp_Array1OfPnt2d& Polyline,
-      const Bnd_Box2d& aBox,
-      const Standard_Real aTol )
+//=======================================================================
+// function : NbSubElements
+// purpose  : Returns the amount of nodes of polyhedron
+//=======================================================================
+Standard_Integer MeshVS_SensitivePolyhedron::NbSubElements()
 {
-  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 );
+  return myNodes->Length();
 }
 
-//================================================================
-// Function : FindIntersection
-// Purpose  :
-//================================================================
-Standard_Real MeshVS_SensitivePolyhedron::FindIntersection
-    ( const TColStd_SequenceOfInteger& NodesIndices,
-      const gp_Lin& EyeLine) const
+//=======================================================================
+// function : BoundingBox
+// purpose  :
+//=======================================================================
+Select3D_BndBox3d MeshVS_SensitivePolyhedron::BoundingBox()
 {
-  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;
+  return myBndBox;
 }
 
-//================================================================
-// Function : ComputeDepth
-// Purpose  :
-//================================================================
-Standard_Real MeshVS_SensitivePolyhedron::ComputeDepth( const gp_Lin& EyeLine ) const
+//=======================================================================
+// function : CenterOfGeometry
+// purpose  :
+//=======================================================================
+gp_Pnt MeshVS_SensitivePolyhedron::CenterOfGeometry() 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( x<xmin )
-        xmin = x;
-      if( y>ymax )
-        ymax = y;
-      else if( y<ymin )
-        ymin = y;
-    }
-  }
-
-  aBox.Update( xmin, ymin, xmax, ymax );
+  return myCenter;
 }
diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.hxx b/src/MeshVS/MeshVS_SensitivePolyhedron.hxx
new file mode 100644 (file)
index 0000000..fff3c49
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <Handle_TColgp_HArray1OfPnt2d.hxx>
+#include <Handle_MeshVS_HArray1OfSequenceOfInteger.hxx>
+#include <gp_XY.hxx>
+#include <NCollection_List.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Select3D_BndBox3d.hxx>
+
+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<Handle(TColgp_HArray1OfPnt)> MeshVS_PolyhedronVerts;
+typedef NCollection_List<Handle(TColgp_HArray1OfPnt)>::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 (file)
index 917cf03..0000000
+++ /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;
index 804fb72..5297843 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <MeshVS_SensitiveSegment.ixx>
-#include <Select3D_Projector.hxx>
-#include <Bnd_Box2d.hxx>
-#include <CSLib_Class2d.hxx>
-#include <TopLoc_Location.hxx>
+#include <MeshVS_SensitiveSegment.hxx>
 
-//=======================================================================
-// 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 );
-}
+#include <SelectBasics_EntityOwner.hxx>
 
-//=======================================================================
-// 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 );
-}
+IMPLEMENT_STANDARD_HANDLE (MeshVS_SensitiveSegment, Select3D_SensitiveSegment)
+IMPLEMENT_STANDARD_RTTIEXT(MeshVS_SensitiveSegment, Select3D_SensitiveSegment)
 
 //=======================================================================
-// 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
+// name    : MeshVS_SensitiveSegment::MeshVS_SensitiveSegment
 // 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 (file)
index 0000000..d28137a
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <gp_Pnt.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+
+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
index c3c4b3b..3dbfeb4 100644 (file)
@@ -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.
index be68dd8..d21b658 100644 (file)
@@ -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)
index 86f3492..7beaf60 100644 (file)
@@ -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;
index 568d41d..31b2467 100644 (file)
@@ -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
 }
index 37dd222..3ee165d 100644 (file)
@@ -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]));
         }
       }
index 9176177..4b2131d 100644 (file)
@@ -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;
index c1f5bf8..20f5c8f 100644 (file)
@@ -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;
-}
-
index 866330e..9ca3ccf 100755 (executable)
@@ -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
index 840afa5..981d712 100644 (file)
@@ -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 (file)
index 0000000..61aaec5
--- /dev/null
@@ -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 <BVH_LinearBuilder.hxx>
+
+#include <Select3D_SensitiveSet.hxx>
+#include <Select3D_BVHPrimitiveContent.hxx>
+
+//=======================================================================
+// 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<Standard_Real, 3> (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<BVH_Tree<Standard_Real, 3> >& Select3D_BVHPrimitiveContent::GetBVH()
+{
+  return BVH();
+}
diff --git a/src/Select3D/Select3D_BVHPrimitiveContent.hxx b/src/Select3D/Select3D_BVHPrimitiveContent.hxx
new file mode 100644 (file)
index 0000000..210c436
--- /dev/null
@@ -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 <BVH_PrimitiveSet.hxx>
+
+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<Standard_Real, 3>
+{
+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<BVH_Tree<Standard_Real, 3> >& GetBVH();
+
+protected:
+  Handle(Select3D_SensitiveSet) mySensitiveSet;     //!< Set of sensitive entities
+};
+
+#endif // _Select3D_BVHPrimitiveContent_Header
diff --git a/src/Select3D/Select3D_BndBox3d.hxx b/src/Select3D/Select3D_BndBox3d.hxx
new file mode 100644 (file)
index 0000000..0ccbf33
--- /dev/null
@@ -0,0 +1,29 @@
+// 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.
+//
+// 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_BndBox3d_Header
+#define _Select3D_BndBox3d_Header
+
+#include <BVH_Box.hxx>
+#include <BVH_Types.hxx>
+
+#include <gp_Trsf.hxx>
+
+#include <NCollection_Vector.hxx>
+
+typedef BVH_Box<Standard_Real, 3> Select3D_BndBox3d;
+typedef NCollection_Vec3<Standard_Real> Select3D_Vec3;
+
+#endif // _Select3D_BndBox3d_Header
diff --git a/src/Select3D/Select3D_BoundarySensitivePointSet.cxx b/src/Select3D/Select3D_BoundarySensitivePointSet.cxx
new file mode 100644 (file)
index 0000000..7a34c12
--- /dev/null
@@ -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 <Select3D_BoundarySensitivePointSet.hxx>
+
+//=======================================================================
+// 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 (file)
index 0000000..f04c613
--- /dev/null
@@ -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 <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+
+#include <Select3D_ISensitivePointSet.hxx>
+#include <Select3D_SensitivePoly.hxx>
+
+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 (file)
index 79eab85..0000000
+++ /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<Bnd_Box2d.hxx>
-#include<Standard_ShortReal.hxx>
-#include<Select3D_Macro.hxx>
-
-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 (file)
index 0000000..68e4e3a
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _Select3D_EntitySequence_Header
+#define _Select3D_EntitySequence_Header
+
+#include <NCollection_Sequence.hxx>
+
+class Handle(Select3D_SensitiveEntity);
+
+typedef NCollection_Sequence<Handle(Select3D_SensitiveEntity)> Select3D_EntitySequence;
+typedef NCollection_Sequence<Handle(Select3D_SensitiveEntity)>::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 (file)
index 0000000..7cb0564
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_OStream.hxx>
+#include <Standard_Real.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <SelectBasics_PickResult.hxx>
+#include <SelectBasics_SelectingVolumeManager.hxx>
+
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+
+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 (file)
index 0000000..1ea7e35
--- /dev/null
@@ -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 <gp_Pnt.hxx>
+#include <gp_XYZ.hxx>
+
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+
+#include <Select3D_InteriorSensitivePointSet.hxx>
+
+// 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<Standard_Real> (aDir.X(), aDir.Y(), aDir.Z(), aD);
+    myIsInitialized = Standard_True;
+  }
+
+  void Invalidate()
+  {
+    myIsInitialized = Standard_False;
+  }
+
+  Standard_Boolean IsValid() const
+  {
+    return myIsInitialized;
+  }
+
+private:
+  NCollection_Vec4<Standard_Real> 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 (file)
index 0000000..2e1dab0
--- /dev/null
@@ -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 <NCollection_Vector.hxx>
+
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <Handle_TColStd_HArray1OfInteger.hxx>
+
+#include <Select3D_ISensitivePointSet.hxx>
+#include <Select3D_SensitivePoly.hxx>
+#include <Select3D_SensitiveSet.hxx>
+
+class gp_Pnt;
+class SelectBasics_EntityOwner;
+class TColgp_Array1OfPnt;
+class TColgp_HArray1OfPnt;
+class TColStd_HArray1OfInteger;
+
+typedef NCollection_Vector<Handle(Select3D_SensitivePoly)> 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 (file)
index d8658d0..0000000
+++ /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<gp_Pnt2d.hxx>
-#include<Standard_ShortReal.hxx>
-#include<Select3D_Macro.hxx>
-
-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
-
index 4773ee8..0193ef7 100644 (file)
 #define _Select3D_PointData_HeaderFile
 
 #include <Select3D_Pnt.hxx>
-#include <Select3D_Pnt2d.hxx>
 
-// 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 (file)
index ca37598..0000000
+++ /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.
-
---        <cma@sdsun2> 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 <theCS>. 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 <theCS> and simplified perspective
-    -- projection transformation defined by <theFocus> parameter.
-    -- The viewing coordinate system could be constructed from x direction,
-    -- view plane normal direction, and focal point location in world-coordinate
-    -- space. <theFocus> 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 <theViewTrsf> and simplified perspective projection transformation
-    -- parameters passed as <theIsPersp> and <theFocus>.
-    -- In case, when <theViewTrsf> 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.
-    -- <theViewTrsf> 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 <theFocus> 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 <theViewTrsf> and projection transformation for <theIsPersp> and
-    -- <theFocus> parameters.
-    -- In case, when <theViewTrsf> 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 <theFocus> 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 <theViewTrsf> 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 <theViewTrsf>
-    -- and projection <theProjTrsf> transformation matrices. Parameters <theZNear>
-    -- and <theZFar> 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 <theToCheckOptimized> 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 <theX, theY>
-    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 (file)
index f7975cb..0000000
+++ /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 <Select3D_Projector.ixx>
-#include <Precision.hxx>
-#include <gp_Ax3.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-#include <gp_Mat.hxx>
-#include <Graphic3d_Vec4.hxx>
-
-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 (file)
index f62cf41..0000000
+++ /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 <Graphic3d_Mat4d.hxx>
-#include <Standard_Assert.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Lin.hxx>
-
-//=======================================================================
-//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 (file)
index e92cacb..0000000
+++ /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;
-
-
-
-
-
-
-
-
-
-
index 8ccf511..114de8a 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveBox.ixx>
+#include <Select3D_SensitiveBox.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Pnt.hxx>
 #include <Bnd_Box.hxx>
 #include <ElCLib.hxx>
 
-
-
-//==================================================
-// Function: Constructor
-// Purpose :
-//==================================================
-
-Select3D_SensitiveBox::Select3D_SensitiveBox(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                                             const Bnd_Box& BBox):
-Select3D_SensitiveEntity(OwnerId),
-mybox3d(BBox){}
+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 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);
 
-//==================================================
-// Function: Matches
-// Purpose :
-//==================================================
+  return aNewEntity;
+}
 
-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;
-}
-
-//==================================================
-// Function: Matches
-// Purpose :
-//==================================================
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
 
-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)
-{
-  Bnd_Box2d BoundBox;
-  BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
-  return(!BoundBox.IsOut(mybox2d));
+  return isMatched;
 }
 
 //=======================================================================
-//function : Matches
-//purpose  : 
+// function : CenterOfGeometry
+// purpose  : Returns center 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*/)
+gp_Pnt Select3D_SensitiveBox::CenterOfGeometry() const
 {
-  return(!aBox.IsOut(mybox2d));
+  return myCenter3d;
 }
 
 //=======================================================================
-//function : Dump
-//purpose  : 
+// function : BoundingBox
+// purpose  : Returns coordinates of the box. If location transformation
+//            is set, it will be applied
 //=======================================================================
-
-void Select3D_SensitiveBox::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
+Select3D_BndBox3d Select3D_SensitiveBox::BoundingBox()
 {
-  S<<"\tSensitiveBox 3D :\n";
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-  
-  Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax;
-  mybox3d.Get(XMin,YMin,ZMin,XMax,YMax,ZMax);
-  
-  S<<"\t\t PMin [ "<<XMin<<" , "<<YMin<<" , "<<ZMin<<" ]";
-  S<<"\t\t PMax [ "<<XMax<<" , "<<YMax<<" , "<<ZMax<<" ]"<<endl;
-
-  if(FullDump)
-  {
-//    S<<"\t\t\tOwner:"<<myOwnerId<<endl;
-    Select3D_SensitiveEntity::DumpBox(S,mybox2d);
-  }
+  return myBox;
 }
 
-
 //=======================================================================
-//function : ProjectBox
-//purpose  : 
+// function : Box
+// purpose  :
 //=======================================================================
-
-void Select3D_SensitiveBox::ProjectBox(const Handle(Select3D_Projector)& aPrj,
-                                       const Bnd_Box& aBox) 
+Bnd_Box Select3D_SensitiveBox::Box() const
 {
-  mybox2d.SetVoid();
-  gp_Pnt2d curp2d;
-  Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax;
-  aBox.Get(XMin,YMin,ZMin,XMax,YMax,ZMax);
-
-  aPrj->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());
-}
+  Bnd_Box aBox;
+  aBox.Update (myBox.CornerMin().x(), myBox.CornerMin().y(), myBox.CornerMin().z(),
+               myBox.CornerMax().x(), myBox.CornerMax().y(), myBox.CornerMax().z());
 
-//=======================================================================
-//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 (file)
index 0000000..0692e7f
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Bnd_Box.hxx>
+#include <gp_Pnt.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_OStream.hxx>
+
+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_SensitiveBox.lxx b/src/Select3D/Select3D_SensitiveBox.lxx
deleted file mode 100644 (file)
index 2b79709..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Created on: 1997-07-16
-// 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.
-
-inline const Bnd_Box& Select3D_SensitiveBox::Box() const
-{return mybox3d;}
diff --git a/src/Select3D/Select3D_SensitiveCircle.cdl b/src/Select3D/Select3D_SensitiveCircle.cdl
deleted file mode 100644 (file)
index a2af4fe..0000000
+++ /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;
-
index d7883b4..53a246c 100644 (file)
 // 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 <Geom_Circle.hxx>
 
-#include <Select3D_SensitiveCircle.ixx>
+#include <Select3D_Pnt.hxx>
+#include <Select3D_SensitiveTriangle.hxx>
 #include <Precision.hxx>
-#include <gp_Lin2d.hxx>
 
-#include <CSLib_Class2d.hxx>
-#include <Select3D_SensitiveTriangle.hxx>
-#include <ElCLib.hxx>
-#include <Select3D_Pnt.hxx>
-#include <Select3D_Pnt2d.hxx>
-#include <Select3D_Projector.hxx>
+#include <Select3D_SensitiveCircle.hxx>
 
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCircle, Select3D_SensitivePoly)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitivePoly)
 
-static Standard_Integer S3D_GetCircleNBPoints(const Handle(Geom_Circle)& C,
-                                              const Standard_Integer anInputNumber)
+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);
-
-      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->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;
     }
 
-    // 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,319 +116,172 @@ 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)
-  {
-    gp_Pnt p1,p2;
-    gp_Vec v1;
+  mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
 
-    if (u1 > u2)
-    {
-      mystart = u2;
-      myend = u1;
-    }
+  if (myPolyg.Size() != 1)
+  {
+    gp_Pnt aP1, aP2;
+    gp_Vec aV1;
 
-    Standard_Real du = (myend-mystart)/(NbPoints-1);
-    Standard_Real R = TheCircle->Radius();
-    Standard_Integer rank = 1;
-    Standard_Real curu = mystart;
+    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<=NbPoints-1;anIndex++)
+    for (Standard_Integer anIndex = 1; anIndex <= theNbPnts - 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->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;
     }
-    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);
   }
-}
 
-//=======================================================================
-//function : Select3D_SensitiveCircle
-//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)
-{
-  if (mypolyg.Size() != 1)
-    ComputeCenter3D();
-  else
-    myCenter3D = mypolyg.Pnt(0);
+  if (mySensType == Select3D_TOS_BOUNDARY)
+  {
+    SetSensitivityFactor (6.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)
+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)
 {
-  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);
+
+  if (mySensType == Select3D_TOS_BOUNDARY)
+  {
+    SetSensitivityFactor (6.0);
+  }
 }
 
 //=======================================================================
-//function : Matches
+//function : Select3D_SensitiveCircle
 //purpose  :
 //=======================================================================
 
-Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                    Standard_Real& theMatchDMin,
-                                                    Standard_Real& theMatchDepth)
+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)
 {
-  Standard_Integer aSize = mypolyg.Size();
-  Standard_Integer aDetectedIndex = -1;
-  gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y());
-  if (aSize != 1)
-  {
-    Standard_Boolean Found = Standard_False;
-    Standard_Integer anIndex = 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;
-        }
-
-        anIndex += 2;
-      }
-    }
-    else
-    {
-      Standard_Real Xmin,Ymin,Xmax,Ymax;
-
-      // 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);
-      }
+  mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
 
-      return Standard_False;
-    }
-
-    if (Found)
-    {
-      theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
-
-      return !thePickArgs.IsClipped (theMatchDepth);
-    }
-
-    return Standard_False;
-  }
+  if (myPolyg.Size() != 1)
+    computeCenter3D();
+  else
+    myCenter3D = myPolyg.Pnt (0);
 
-  // Circle degenerates into point
-  theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0));
-  if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor())
+  if (mySensType == Select3D_TOS_BOUNDARY)
   {
-    theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
-
-    return !thePickArgs.IsClipped (theMatchDepth);
+    SetSensitivityFactor (6.0);
   }
-
-  return Standard_False;
 }
 
 //=======================================================================
-//function : Matches
-//purpose  :
+// function : BVH
+// purpose  : Builds BVH tree for a circle's edge segments if needed
 //=======================================================================
-
-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::BVH()
 {
-  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<mypolyg.Size();anIndex++)
+  if (mySensType == Select3D_TOS_BOUNDARY)
   {
-    if(abox.IsOut(mypolyg.Pnt2d(anIndex)))
-      return Standard_False;
+    Select3D_SensitivePoly::BVH();
   }
-  return Standard_True;
 }
 
 //=======================================================================
-//function : Matches
-//purpose  :
+// function : Matches
+// purpose  : Checks whether the circle overlaps current selecting volume
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveCircle::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
-         const Bnd_Box2d& aBox,
-         const Standard_Real aTol)
+Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                    SelectBasics_PickResult& thePickResult)
 {
-  Standard_Real Umin,Vmin,Umax,Vmax;
-  aBox.Get(Umin,Vmin,Umax,Vmax);
-  CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
+  Standard_Real aDepth     = RealLast();
+  Standard_Real aDistToCOG = RealLast();
 
-  for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
+  Standard_Boolean isCollisionDetected = Standard_False;
+  if (mySensType == Select3D_TOS_BOUNDARY)
   {
-    Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
-    if(RES!=1)
-      return Standard_False;
+    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);
   }
-  return Standard_True;
-}
-
-//=======================================================================
-//function : ArrayBounds
-//purpose  :
-//=======================================================================
 
-void Select3D_SensitiveCircle::
-ArrayBounds(Standard_Integer & Low,
-            Standard_Integer & Up) const
-{
-    Low = 0;
-    Up = mypolyg.Size()-1;
-}
+  if (isCollisionDetected)
+  {
+    aDistToCOG = theMgr.DistToGeometryCenter (myCenter3D);
+  }
 
-//=======================================================================
-//function : GetPoint3d
-//purpose  :
-//=======================================================================
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
 
-gp_Pnt Select3D_SensitiveCircle::
-GetPoint3d(const Standard_Integer Rank) const
-{
-  if(Rank>=0 && Rank<mypolyg.Size())
-    return mypolyg.Pnt(Rank);
-  return gp_Pnt();
+  return isCollisionDetected;
 }
 
-
-//=======================================================================
-//function : Dump
-//purpose  :
-//=======================================================================
-
-void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
+void Select3D_SensitiveCircle::ArrayBounds (Standard_Integer & theLow,
+                                            Standard_Integer & theUp) const
 {
-  Standard_Integer aSize = mypolyg.Size();
-
-  S<<"\tSensitiveCircle 3D :";
-
-  Standard_Boolean isclosed = 1== aSize;
-  if(isclosed)
-    S<<"(Closed Circle)"<<endl;
-  else
-    S<<"(Arc Of Circle)"<<endl;
-
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-
-
-  if(FullDump)
-  {
-    gp_XYZ aCenter = myCenter3D;
-    Standard_Real R = (aCenter-mypolyg.Pnt(0)).Modulus();
-
-    S<<"\t\t Center : ("<<aCenter.X()<<" , "<<aCenter.Y()<<" , "<<aCenter.Z()<<" )"<<endl;
-    S<<"\t\t Radius :"<<R<<endl;
-  }
+    theLow = 0;
+    theUp = myPolyg.Size() - 1;
 }
 
 //=======================================================================
-//function : ComputeDepth
+//function : GetPoint3d
 //purpose  :
 //=======================================================================
-
-Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine,
-                                                      const Standard_Integer theDetectedIndex) const
+gp_Pnt Select3D_SensitiveCircle::GetPoint3d (const Standard_Integer thePntIdx) const
 {
-  gp_XYZ aCDG;
-  if (theDetectedIndex == -1)
-  {
-    aCDG = myCenter3D;
-  }
-  else
-  {
-    aCDG += mypolyg.Pnt (theDetectedIndex);
-    aCDG += mypolyg.Pnt (theDetectedIndex + 1);
-    aCDG += mypolyg.Pnt (theDetectedIndex + 2);
-    aCDG /= 3.;
-  }
+  if (thePntIdx >= 0 && thePntIdx < myPolyg.Size())
+    return myPolyg.Pnt (thePntIdx);
 
-  return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
+  return gp_Pnt();
 }
 
 //=======================================================================
@@ -434,79 +289,71 @@ Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine,
 //purpose  :
 //=======================================================================
 
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected(const TopLoc_Location& theLocation)
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected()
 {
+  Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR;
   // Create a copy of this
   Handle(Select3D_SensitiveEntity) aNewEntity;
   // this was constructed using Handle(Geom_Circle)
   if(!myCircle.IsNull())
   {
-    if((myend-mystart) > 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 (file)
index 0000000..65c06b0
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_SensitivePoly.hxx>
+#include <Select3D_Pnt.hxx>
+#include <Handle_Geom_Circle.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Select3D_TypeOfSensitivity.hxx>
+
+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 (file)
index c5ddfed..0000000
+++ /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 <theP1, theP2> and
-    --          the eye-line <thePickLine>.
-    returns Boolean from Standard
-    is protected;
-
-fields
-    mylastseg : Integer        from Standard;
-    myCurve  : Curve from Geom;
-end SensitiveCurve;
-
index 9c31446..149b8a8 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveCurve.ixx>
-#include <SelectBasics_BasicTool.hxx>
-#include <gp_Lin2d.hxx>
+#include <Select3D_SensitiveCurve.hxx>
 #include <Precision.hxx>
-#include <ElCLib.hxx>
-#include <CSLib_Class2d.hxx>
-#include <Extrema_ExtElC.hxx>
+#include <TColgp_Array1OfPnt.hxx>
 
-//==================================================
-// 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)
-{
-  LoadPoints(C,NbPoints);
-}
+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(TColgp_HArray1OfPnt)& ThePoints):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mylastseg(0)
+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 (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 TColgp_Array1OfPnt& ThePoints):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mylastseg(0)
 {
+  SetSensitivityFactor (3.0);
 }
 
 //==================================================
-// Function: Matches
+// Function: Creation
 // Purpose :
 //==================================================
-
-Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                   Standard_Real& theMatchDMin,
-                                                   Standard_Real& theMatchDepth)
-{
-  Standard_Integer Rank;
-  TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
-  Points2D(aArrayOf2dPnt);
-  if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
-                                            thePickArgs.X(), thePickArgs.Y(),
-                                            thePickArgs.Tolerance(),
-                                            theMatchDMin,
-                                            Rank))
-  {
-    // remember detected segment (for GetLastDetected)
-    mylastseg = Rank;
-
-    theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
-
-    return !thePickArgs.IsClipped (theMatchDepth);
-  }
-
-  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)
+Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                                  const TColgp_Array1OfPnt& thePoints)
+: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints.Length() > 2)
 {
-  Bnd_Box2d BoundBox;
-  BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
-
-  for(Standard_Integer anIndex=0; anIndex<mypolyg.Size(); ++anIndex)
-    {
-      if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
-        return Standard_False;
-    }
-  return Standard_True;
-}
-
-//=======================================================================
-//function : Matches
-//purpose  :
-//=======================================================================
-
-Standard_Boolean Select3D_SensitiveCurve::
-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 anIndex=0;anIndex<mypolyg.Size();++anIndex)
-  {
-    Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
-    if(RES!=1)
-      return Standard_False;
-  }
-  return Standard_True;
+  SetSensitivityFactor (3.0);
 }
 
 //==================================================
-// Function: LoadPoints
+// Function: loadPoints
 // Purpose :
 //==================================================
-
-void Select3D_SensitiveCurve
-::LoadPoints (const Handle(Geom_Curve)& aCurve,const Standard_Integer NbP)
+void Select3D_SensitiveCurve::loadPoints (const Handle(Geom_Curve)& theCurve, const Standard_Integer theNbPnts)
 {
-  /*this method is private and it used only inside of constructor.
-    That's why check !NbP==mypolyg3d->Length() was removed*/
-
-  Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1);
-  Standard_Real Curparam = aCurve->FirstParameter();
-  for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
+  Standard_Real aStep = (theCurve->LastParameter() - theCurve->FirstParameter()) / (theNbPnts - 1);
+  Standard_Real aParam = theCurve->FirstParameter();
+  for (Standard_Integer aPntIdx = 0; aPntIdx < myPolyg.Size(); ++aPntIdx)
   {
-    mypolyg.SetPnt(anIndex, aCurve->Value(Curparam));
-    Curparam+=Step;
+    myPolyg.SetPnt (aPntIdx, theCurve->Value (aParam));
+    aParam += aStep;
   }
 }
 
-//=======================================================================
-//function : Dump
-//purpose  :
-//=======================================================================
-
-void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
-{
-  S<<"\tSensitiveCurve 3D :"<<endl;
-  if (HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-
-  S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
-
-  if(FullDump)
-  {
-    Select3D_SensitiveEntity::DumpBox(S,mybox2d);
-  }
-}
-
-//=======================================================================
-//function : ComputeDepth
-//purpose  :
-//=======================================================================
-
-Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
-                                                     const Standard_Integer theSegment) const
-{
-  Standard_Real aDepth = Precision::Infinite();
-  if (theSegment == 0)
-  {
-    return aDepth;
-  }
-
-  // In case if theSegment and theSegment + 1 are not valid
-  // the depth will be infinite
-  if (theSegment >= 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 <theP1, theP2> and
-//           the eye-line <thePickLine>.
+// 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 (file)
index 0000000..ca265cc
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Geom_Curve.hxx>
+#include <Handle_Geom_Curve.hxx>
+#include <Select3D_SensitivePoly.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <Standard_Boolean.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_OStream.hxx>
+
+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 (file)
index bb17bef..0000000
+++ /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 (file)
index 8669543..0000000
+++ /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 :
-    --          <FullDump> = False -> general information
-    --         <FullDump> = True  -> whole informtion 3D +2d ...
-
-    DumpBox(myclass; S: in out OStream;abox:Box2d from Bnd) ;
-
-    UpdateLocation(me:mutable;aLoc:Location from TopLoc);
-
-end SensitiveEntity;
-
-
-
-
-
-
index 913e715..19f73a5 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveEntity.ixx>
+#include <Select3D_SensitiveEntity.hxx>
 #include <Precision.hxx>
 #include <SelectBasics_EntityOwner.hxx>
 #include <Select3D_Macro.hxx>
+#include <TopLoc_Location.hxx>
 
-//=======================================================================
-//function : Select3D_SensitiveEntity
-//purpose  : 
-//=======================================================================
-
-Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId):
-SelectBasics_SensitiveEntity(OwnerId)
-{}
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
 
 //=======================================================================
-//function : Matches
+//function : Select3D_SensitiveEntity
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real,
-                                                   const Standard_Real,
-                                                   const Standard_Real,
-                                                   const Standard_Real,
-                                                   const Standard_Real)
-{
-  return Standard_False;
-}
+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 TColgp_Array1OfPnt2d&,
-                                                   const Bnd_Box2d&,
-                                                   const Standard_Real)
+Standard_Boolean Select3D_SensitiveEntity::Matches (SelectBasics_SelectingVolumeManager& /*theMgr*/,
+                                                    SelectBasics_PickResult& /*thePickResult*/)
 {
   return Standard_False;
 }
 
 //=======================================================================
-//function : Dump
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::Dump(Standard_OStream& S, const Standard_Boolean) const
-{
-  S<<"\tSensitive Entity 3D"<<endl;
-}
-
-//=======================================================================
-//function : DumpBox
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::DumpBox(Standard_OStream& S,const Bnd_Box2d& b2d) 
-{
-  if(!b2d.IsVoid())
-  {
-    Standard_Real xmin,ymin,xmax,ymax;
-    b2d.Get(xmin,ymin,xmax,ymax);
-    S<<"\t\t\tBox2d: PMIN ["<<xmin<<" , "<<ymin<<"]"<<endl;
-    S<<"\t\t\t       PMAX ["<<xmax<<" , "<<ymax<<"]"<<endl;
-  }
-}
-
-//=======================================================================
-//function : ResetLocation
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::ResetLocation()
-{
-}
-
-//=======================================================================
-//function : SetLocation
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::SetLocation(const TopLoc_Location&)
-{
-}
-
-//=======================================================================
-//function : UpdateLocation
+//function : GetConnected
 //purpose  : 
 //=======================================================================
 
-void Select3D_SensitiveEntity::UpdateLocation(const TopLoc_Location& aLoc)
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected()
 {
-  if(aLoc.IsIdentity() || aLoc == Location()) return;
-  if(!HasLocation())
-    SetLocation(aLoc);
-  else 
-  {
-    TopLoc_Location compLoc = aLoc * Location();
-    SetLocation(compLoc);
-  }
+  Handle(Select3D_SensitiveEntity) aNewEntity;
+  return aNewEntity;
 }
 
 //=======================================================================
-//function : Location
-//purpose  : 
+// function : BVH
+// purpose  : Builds BVH tree for a sensitive if needed
 //=======================================================================
-
-const TopLoc_Location Select3D_SensitiveEntity::Location() const 
+void Select3D_SensitiveEntity::BVH()
 {
-  TopLoc_Location anIdentity;  
-  Handle(SelectBasics_EntityOwner) anOwner = OwnerId();
-  return anOwner.IsNull() ? anIdentity : anOwner->Location();
-}
-
-//=======================================================================
-//function : HasLocation
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Select3D_SensitiveEntity::HasLocation() const
-{ 
-  Handle(SelectBasics_EntityOwner) anOwner = OwnerId();
-  return (!anOwner.IsNull() && anOwner->HasLocation());
+  return;
 }
 
 //=======================================================================
-//function : Is3D
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Select3D_SensitiveEntity::Is3D() const
-{return Standard_True;}
-
-//=======================================================================
-//function : MaxBoxes
-//purpose  : 
+// function : Clear
+// purpose  : Cleans up resources and memory
 //=======================================================================
-
-Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const 
-{return 1;}
-
-//=======================================================================
-//function : GetConnected
-//purpose  : 
-//=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const TopLoc_Location&)  
+void Select3D_SensitiveEntity::Clear()
 {
-  Handle(Select3D_SensitiveEntity) NiouEnt;
-  return NiouEnt;
+  Set (NULL);
 }
diff --git a/src/Select3D/Select3D_SensitiveEntity.hxx b/src/Select3D/Select3D_SensitiveEntity.hxx
new file mode 100644 (file)
index 0000000..a235f15
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <SelectBasics_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_Integer.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_OStream.hxx>
+
+#include <TopLoc_Location.hxx>
+
+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_SensitiveEntity.lxx b/src/Select3D/Select3D_SensitiveEntity.lxx
deleted file mode 100644 (file)
index 47c57a6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-inline Standard_Boolean Select3D_SensitiveEntity::NeedsConversion() const
-{return Standard_True;}
-
diff --git a/src/Select3D/Select3D_SensitiveFace.cdl b/src/Select3D/Select3D_SensitiveFace.cdl
deleted file mode 100644 (file)
index e6e6628..0000000
+++ /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;
index 87454db..5fdd578 100644 (file)
 //                     pour teste si on est dedans ou dehors...
 //Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ...
 
-#include <Select3D_SensitiveFace.ixx>
-#include <Select3D_Projector.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <gp_Pnt2d.hxx>
+#include <Select3D_SensitiveFace.hxx>
 #include <gp_Pnt.hxx>
 #include <Precision.hxx>
-#include <ElCLib.hxx>
 
-#include <CSLib_Class2d.hxx>
+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)
-{
-}
-
-//==================================================
-// Function: Matches
-// Purpose :
-//==================================================
-
-Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                  Standard_Real& theMatchDMin,
-                                                  Standard_Real& theMatchDepth)
+Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                                const Handle(TColgp_HArray1OfPnt)& thePoints,
+                                                const Select3D_TypeOfSensitivity theType)
+: Select3D_SensitiveEntity (theOwnerId),
+  mySensType (theType)
 {
-  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;anIndex<aSize;++anIndex)
+  else
   {
-    CDG+=mypolyg.Pnt2d(anIndex);
+    myFacePoints = new Select3D_BoundarySensitivePointSet (theOwnerId, thePoints);
   }
-
-  if(aSize>1)
-  {
-    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<aSize;++anIndex)
-  {
-    gp_XY V1(mypolyg.Pnt2d(anIndex)),V(thePickArgs.X(), thePickArgs.Y());
-    V1-=mypolyg.Pnt2d(anIndex-1);
-    V-=mypolyg.Pnt2d(anIndex-1);
-    Standard_Real Vector = V1^V;
-    Standard_Real V1V1 = V1.SquareModulus();
-    DMin2 =
-      (V1V1 <=aTol2) ?
-    Min(DMin2,V.SquareModulus()): // if the segment is too small...
-      Min(DMin2,Vector*Vector/V1V1);
-    //cdg ...
-    gp_XY PlaneTest(CDG);
-    PlaneTest-=mypolyg.Pnt2d(anIndex-1);
-    Standard_Real valtst = PlaneTest^V1;
-    if(isplane2d && Abs(valtst) > 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  :
+// function : GetPoints
+// purpose  : Initializes the given array theHArrayOfPnt by 3d
+//            coordinates of vertices of the face
 //=======================================================================
-
-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)
+void Select3D_SensitiveFace::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
 {
-  Bnd_Box2d BoundBox;
-  BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
-
-  for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
-  {
-    if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
-      return Standard_False;
-  }
-  return Standard_True;
+  myFacePoints->GetPoints (theHArrayOfPnt);
 }
 
 //=======================================================================
-//function : Matches
-//purpose  :
+// function : BVH
+// purpose  : Builds BVH tree for the face
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveFace::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
-         const Bnd_Box2d& aBox,
-         const Standard_Real aTol)
+void Select3D_SensitiveFace::BVH()
 {
-  Standard_Real Umin,Vmin,Umax,Vmax;
-  aBox.Get(Umin,Vmin,Umax,Vmax);
-  CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
+  myFacePoints->BVH();
+}
 
-  gp_Pnt2d aPnt2d;
-  for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
-  {
-    Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
-    if(RES!=1)
-      return Standard_False;
-  }
-  return Standard_True;
+//=======================================================================
+// 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 : Dump
+//function : GetConnected
 //purpose  :
 //=======================================================================
-
-void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected()
 {
-  S<<"\tSensitiveFace 3D :"<<endl;;
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
+  // Create a copy of this
+  Handle(TColgp_HArray1OfPnt) aPoints;
+  myFacePoints->GetPoints (aPoints);
 
-  if(mytype==Select3D_TOS_BOUNDARY)
-    S<<"\t\tSelection Of Bounding Polyline Only"<<endl;
+  Handle(Select3D_SensitiveEntity) aNewEntity =
+    new Select3D_SensitiveFace (myOwnerId, aPoints, mySensType);
 
-  if(FullDump)
-  {
-    S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
-    Select3D_SensitiveEntity::DumpBox(S,mybox2d);
-  }
+  return aNewEntity;
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
+// function : BoundingBox
+// purpose  : Returns bounding box of the face. If location transformation
+//            is set, it will be applied
 //=======================================================================
-
-Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine,
-                                                    const Standard_Real theDepthMin,
-                                                    const Standard_Real theDepthMax) const
+Select3D_BndBox3d Select3D_SensitiveFace::BoundingBox()
 {
-  Standard_Real aDepth = Precision::Infinite();
-  Standard_Real aPointDepth;
-
-  for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
-  {
-    aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex));
-    if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax))
-    {
-      aDepth = aPointDepth;
-    }
-  }
-  return aDepth;
+  return myFacePoints->BoundingBox();
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
+// function : CenterOfGeometry
+// purpose  : Returns center of the face. If location transformation
+//            is set, it will be applied
 //=======================================================================
-
-void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const
+gp_Pnt Select3D_SensitiveFace::CenterOfGeometry() const
 {
-  // this method is obsolete.
+  return myFacePoints->CenterOfGeometry();
 }
 
 //=======================================================================
-//function : GetConnected
-//purpose  :
+// function : NbSubElements
+// purpose  : Returns the amount of sub-entities (points or planar convex
+//            polygons)
 //=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected(const TopLoc_Location &theLocation)
+Standard_Integer Select3D_SensitiveFace::NbSubElements()
 {
-  // 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(Select3D_SensitiveEntity) aNewEntity =
-    new Select3D_SensitiveFace(myOwnerId, aPoints, mytype);
-
-  if (HasLocation())
-    aNewEntity->SetLocation(Location());
-
-  aNewEntity->UpdateLocation(theLocation);
-
-  return aNewEntity;
+  return myFacePoints->NbSubElements();
 }
diff --git a/src/Select3D/Select3D_SensitiveFace.hxx b/src/Select3D/Select3D_SensitiveFace.hxx
new file mode 100644 (file)
index 0000000..82e08ca
--- /dev/null
@@ -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 <NCollection_Handle.hxx>
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_TypeOfSensitivity.hxx>
+#include <Select3D_SensitivePoly.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <Standard_Boolean.hxx>
+#include <SelectBasics_SelectingVolumeManager.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_OStream.hxx>
+
+#include <Select3D_ISensitivePointSet.hxx>
+#include <Select3D_BoundarySensitivePointSet.hxx>
+#include <Select3D_InteriorSensitivePointSet.hxx>
+
+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<Select3D_ISensitivePointSet> 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 (file)
index 7e8a0e1..0000000
+++ /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;
-
index 07e9be2..583edf0 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveGroup.ixx>
-#include <Select3D_ListIteratorOfListOfSensitive.hxx>
 #include <Precision.hxx>
+#include <Select3D_SensitiveGroup.hxx>
+#include <TopLoc_Location.hxx>
+
+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);
+
+  for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
+  {
+    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<Standard_Real> (myEntities.Size()));
+
+  MarkDirty();
 }
 
 //=======================================================================
 //function : Add
-//purpose  : No control of  entities inside 
+//purpose  : No control of entities inside
 //=======================================================================
-
-void Select3D_SensitiveGroup::Add(Select3D_ListOfSensitive& LL) 
-{myList.Append(LL);}
+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  : 
+//purpose  :
 //=======================================================================
-
-void Select3D_SensitiveGroup::Add(const Handle(Select3D_SensitiveEntity)& aSensitive) 
+void Select3D_SensitiveGroup::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
 {
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
+  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())
   {
-    if(It.Value()==aSensitive) return;
+    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<Standard_Real> (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;
+  aNewEntity->Add (aConnectedEnt);
+  return aNewEntity;
 }
 
 //=======================================================================
-//function : SetLocation
-//purpose  : 
+//function : Matches
+//purpose  :
 //=======================================================================
-
-void Select3D_SensitiveGroup::SetLocation(const TopLoc_Location& aLoc) 
+Standard_Boolean Select3D_SensitiveGroup::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                   SelectBasics_PickResult& thePickResult)
 {
-  if(aLoc.IsIdentity()) return;
+  if (!myMustMatchAll
+    || theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
+    return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
 
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
-  {
-    It.Value()->SetLocation(aLoc);
-  }
+  Standard_Real aDepth     = RealLast();
+  Standard_Real aDistToCOG = RealLast();
 
-  if(HasLocation())
-    if(aLoc == Location()) return;
-  
-  Select3D_SensitiveEntity::SetLocation(aLoc);
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
+  for (Select3D_EntitySequenceIter anIt (myEntities); anIt.More(); anIt.Next())
   {
-    if(It.Value()->HasLocation())
+    SelectBasics_PickResult aMatchResult;
+    Handle(SelectBasics_SensitiveEntity)& aChild = anIt.ChangeValue();
+    if (!aChild->Matches (theMgr, aMatchResult))
     {
-      if(It.Value()->Location()!=aLoc) 
-        It.Value()->SetLocation(It.Value()->Location()*aLoc);
+      aMatchResult = SelectBasics_PickResult (RealLast(), RealLast());
+      return Standard_False;
     }
-    else
-      It.Value()->SetLocation(aLoc);
+
+    aDepth = Min (aMatchResult.Depth(), aDepth);
   }
+
+  aDistToCOG = theMgr.DistToGeometryCenter (CenterOfGeometry());
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
+
+  return Standard_True;
 }
 
 //=======================================================================
-//function : ResetLocation
-//purpose  : 
+//function : Set
+//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();
+void Select3D_SensitiveGroup::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
+{ 
+  Select3D_SensitiveEntity::Set (theOwnerId);
+  // set TheOwnerId for each element of sensitive group
+  for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
+    anIter.Value()->Set (theOwnerId);
 }
 
 //=======================================================================
-//function : Matches
-//purpose  : 
+// function : BoundingBox
+// purpose  : Returns bounding box of the group. If location
+//            transformation is set, it will be applied
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                   Standard_Real& theMatchDMin,
-                                                   Standard_Real& theMatchDepth)
+Select3D_BndBox3d Select3D_SensitiveGroup::BoundingBox()
 {
-  theMatchDMin = RealLast();
-  theMatchDepth = RealLast();
-  Standard_Real aChildDMin, aChildDepth;
-  Standard_Boolean isMatched = Standard_False;
+  if (myBndBox.IsValid())
+    return myBndBox;
 
-  Select3D_ListIteratorOfListOfSensitive anIt (myList);
-  for (; anIt.More(); anIt.Next())
+  // do not apply the transformation because sensitives AABBs
+  // are already transformed
+  for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
   {
-    Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value();
-    if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth))
-    {
-      continue;
-    }
-
-    if (!isMatched)
-    {
-      theMatchDMin = aChildDMin;
-      isMatched = Standard_True;
-    }
-
-    theMatchDepth = Min (aChildDepth, theMatchDepth);
+    myBndBox.Combine (anIter.Value()->BoundingBox());
   }
 
-  return isMatched;
+  return myBndBox;
 }
 
 //=======================================================================
-//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) 
+// function : CenterOfGeometry
+// purpose  : Returns center of group. If location transformation
+//            is set, it will be applied
+//=======================================================================
+gp_Pnt Select3D_SensitiveGroup::CenterOfGeometry() const
 {
-  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;
+  return myCenter;
 }
 
 //=======================================================================
-//function : Matches
-//purpose  : 
+// function : Box
+// purpose  : Returns bounding box of sensitive entity with index theIdx
 //=======================================================================
-
-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;
+Select3D_BndBox3d Select3D_SensitiveGroup::Box (const Standard_Integer theIdx) const
+{
+  const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
+  return myEntities.Value (anElemIdx)->BoundingBox();
 }
 
 //=======================================================================
-//function : MaxBoxes
-//purpose  : 
+// 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());
+}
 
-Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
+//=======================================================================
+// 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)
 {
-  Standard_Integer nbboxes(0);
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
-    nbboxes+=It.Value()->MaxBoxes();
-  }
-  return nbboxes;
+  const Standard_Integer anEntIdx1 = myBVHPrimIndexes.Value (theIdx1);
+  const Standard_Integer anEntIdx2 = myBVHPrimIndexes.Value (theIdx2);
+
+  myBVHPrimIndexes.ChangeValue (theIdx1) = anEntIdx2;
+  myBVHPrimIndexes.ChangeValue (theIdx2) = anEntIdx1;
 }
 
 //=======================================================================
-//function : Set
-//purpose  : 
+// function : Size
+// purpose  : Returns the length of vector of sensitive entities
 //=======================================================================
+Standard_Integer Select3D_SensitiveGroup::Size() const
+{
+  return myBVHPrimIndexes.Size();
+}
 
-void Select3D_SensitiveGroup::Set 
-  (const Handle(SelectBasics_EntityOwner)& 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);
+// =======================================================================
+// 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 (file)
index 0000000..bb6b681
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_EntitySequence.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Select3D_SensitiveSet.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+
+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<Standard_Integer> myBVHPrimIndexes;     //!< Vector of sub-entities indexes for BVH tree build
+};
+
+DEFINE_STANDARD_HANDLE(Select3D_SensitiveGroup, Select3D_SensitiveEntity)
+
+#include <Select3D_SensitiveGroup.lxx>
+
+#endif // _Select3D_SensitiveGroup_HeaderFile
index 488d2c1..1dda86a 100644 (file)
 // 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 (file)
index 5615542..0000000
+++ /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 <aProjector> ; 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 <aresult> 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;
-
-
index 95047ee..8c5acb6 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitivePoint.ixx>
+#include <Select3D_SensitivePoint.hxx>
 
-#include <Select3D_Projector.hxx>
-#include <Bnd_Box2d.hxx>
-#include <ElCLib.hxx>
-#include <CSLib_Class2d.hxx>
+#include <TopLoc_Location.hxx>
 
-//==================================================
-// Function: Creation
-// Purpose :
-//==================================================
-
-Select3D_SensitivePoint
-::Select3D_SensitivePoint(const Handle(SelectBasics_EntityOwner)& anOwner,
-                          const gp_Pnt& aPoint):
-Select3D_SensitiveEntity(anOwner)
-{
-  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;
-}
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitivePoint, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoint, Select3D_SensitiveEntity)
 
 //==================================================
-// Function: Areas
+// Function: Creation
 // Purpose :
 //==================================================
-
-void Select3D_SensitivePoint
-::Areas(SelectBasics_ListOfBox2d& boxes)
+Select3D_SensitivePoint::Select3D_SensitivePoint (const Handle(SelectBasics_EntityOwner)& theOwner,
+                                                  const gp_Pnt& thePoint)
+: Select3D_SensitiveEntity (theOwner)
 {
-  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;
-  }
-
-  theMatchDMin = aDist;
-  theMatchDepth = aDepth;
-  return Standard_True;
-}
-
-//==================================================
-// Function: Matches
-// Purpose :
-//==================================================
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
 
-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);
+  return isMatched;
 }
 
 //=======================================================================
-//function : Matches
+//function : Point
 //purpose  :
 //=======================================================================
-
-Standard_Boolean Select3D_SensitivePoint::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
-         const Bnd_Box2d& aBox,
-         const Standard_Real aTol)
+gp_Pnt Select3D_SensitivePoint::Point() const
 {
-  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 myPoint;
 }
 
 //=======================================================================
-//function : Point
+//function : GetConnected
 //purpose  :
 //=======================================================================
-
-gp_Pnt Select3D_SensitivePoint::Point() const
-{return mypoint;}
+Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected()
+{
+  Handle(Select3D_SensitivePoint) aNewEntity = new Select3D_SensitivePoint (myOwnerId, myPoint);
+  return aNewEntity;
+}
 
 //=======================================================================
-//function : GetConnected
-//purpose  :
+// function : CenterOfGeometry
+// purpose  : Returns center of point. If location transformation
+//            is set, it will be applied
 //=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected(const TopLoc_Location& aLoc)
+gp_Pnt Select3D_SensitivePoint::CenterOfGeometry() const
 {
-  Handle(Select3D_SensitivePoint) NiouEnt = new Select3D_SensitivePoint(myOwnerId,mypoint);
-  if(HasLocation()) NiouEnt->SetLocation(Location());
-  NiouEnt->UpdateLocation(aLoc);
-  return NiouEnt;
+  return myPoint;
 }
 
 //=======================================================================
-//function : Dump
-//purpose  :
+// function : BoundingBox
+// purpose  : Returns bounding box of the point. If location
+//            transformation is set, it will be applied
 //=======================================================================
-
-void Select3D_SensitivePoint::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const
+Select3D_BndBox3d Select3D_SensitivePoint::BoundingBox()
 {
-  S<<"\tSensitivePoint 3D :";
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-
-  S<<"\t\t P3d [ "<<mypoint.x<<" , "<<mypoint.y<<" , "<<mypoint.z<<" ]"<<endl;
-  S<<"\t\t P2d [ "<<myprojpt.x<<" , "<<myprojpt.y<<" ]"<<endl;
+  return Select3D_BndBox3d (SelectMgr_Vec3 (myPoint.X(), myPoint.Y(), myPoint.Z()),
+                            SelectMgr_Vec3 (myPoint.X(), myPoint.Y(), myPoint.Z()));
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
+// function : NbSubElements
+// purpose  : Returns the amount of sub-entities in sensitive
 //=======================================================================
-
-Standard_Real Select3D_SensitivePoint::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Integer Select3D_SensitivePoint::NbSubElements()
 {
-  return ElCLib::Parameter(EyeLine,mypoint);
+  return 1;
 }
diff --git a/src/Select3D/Select3D_SensitivePoint.hxx b/src/Select3D/Select3D_SensitivePoint.hxx
new file mode 100644 (file)
index 0000000..74a4620
--- /dev/null
@@ -0,0 +1,74 @@
+// 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.
+
+#ifndef _Select3D_SensitivePoint_HeaderFile
+#define _Select3D_SensitivePoint_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_Pnt.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Standard_Boolean.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_OStream.hxx>
+
+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 (file)
index d31a1f5..0000000
+++ /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 <boxes> 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;
index 6847e2d..3a161fd 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitivePoly.ixx>
-#include <gp_Pnt2d.hxx>
 #include <gp_Pnt.hxx>
-#include <Select3D_Pnt.hxx>
-#include <Select3D_Pnt2d.hxx>
-#include <Select3D_Box2d.hxx>
 #include <TopLoc_Location.hxx>
 
+#include <Select3D_Pnt.hxx>
+
+#include <Select3D_SensitivePoly.hxx>
+
+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
+// Function: Select3D_SensitivePoly
+// Purpose :
 //==================================================
+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)
+{
+  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();
 
-Select3D_SensitivePoly::
-Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                       const TColgp_Array1OfPnt& ThePoints):
-Select3D_SensitiveEntity(OwnerId),
-mypolyg(ThePoints.Upper()-ThePoints.Lower()+1)
+  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: Select3D_SensitivePoly
+// Purpose :
+//==================================================
+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)
 {
-  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);
+
+  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());
+}
 
-Select3D_SensitivePoly::
-Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                       const Handle(TColgp_HArray1OfPnt)& ThePoints):
-Select3D_SensitiveEntity(OwnerId),
-mypolyg(ThePoints->Upper()-ThePoints->Lower()+1)
+//==================================================
+// function : BoundingBox
+// purpose  : Returns bounding box of a polygon. If location
+//            transformation is set, it will be applied
+//==================================================
+Select3D_BndBox3d Select3D_SensitivePoly::BoundingBox()
 {
-  for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); theIndex++)
-    mypolyg.SetPnt(theIndex, ThePoints->Value(ThePoints->Lower()+theIndex));
+  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: Creation
-// Purpose :
+// Function: Size
+// Purpose : Returns the amount of segments of
+//           the poly
 //==================================================
+Standard_Integer Select3D_SensitivePoly::Size() const
+{
+  if (!mySegmentIndexes.IsNull())
+    return mySegmentIndexes->Length();
 
-Select3D_SensitivePoly::
-Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId, 
-                       const Standard_Integer NbPoints):
-Select3D_SensitiveEntity(OwnerId),
-mypolyg(NbPoints)
+  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: Project
-// Purpose :
+// 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;
+}
 
-void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj)
+//==================================================
+// 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)
 {
-  mybox2d.SetVoid();
+  if (mySegmentIndexes.IsNull())
+    return Standard_False;
 
-  Standard_Boolean hasloc = HasLocation();
-  gp_Pnt2d aPnt2d;
-  gp_Pnt aPnt;
-  for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); ++theIndex)
+  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())
   {
-    aPnt = mypolyg.Pnt(theIndex);
-    if (hasloc)
-    {
-      aProj->Project(aPnt.Transformed(Location().Transformation()), aPnt2d);
-    }
-    else
+    gp_XYZ aCenter (0.0, 0.0, 0.0);
+    for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
     {
-      aProj->Project(aPnt, aPnt2d);
+      aCenter += myPolyg.Pnt (aIdx);
     }
-    mybox2d.Update(aPnt2d);
-    mypolyg.SetPnt2d(theIndex, aPnt2d);
+    myCOG = aCenter / myPolyg.Size();
   }
+
+  return theMgr.DistToGeometryCenter (myCOG);
 }
 
 //==================================================
-// Function: Areas
-// Purpose :
+// Function: NbSubElements
+// Purpose : Returns the amount of segments in poly
 //==================================================
-void Select3D_SensitivePoly
-::Areas(SelectBasics_ListOfBox2d& aSeq)
+Standard_Integer Select3D_SensitivePoly::NbSubElements()
 {
-  aSeq.Append(mybox2d);
+  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 (file)
index 0000000..b92f984
--- /dev/null
@@ -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 <NCollection_Handle.hxx>
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <TColStd_HArray1OfInteger.hxx>
+#include <Handle_TColgp_HArray1OfPnt.hxx>
+#include <Handle_TColStd_HArray1OfInteger.hxx>
+
+#include <Select3D_PointData.hxx>
+#include <Select3D_Pnt.hxx>
+#include <Select3D_SensitiveSet.hxx>
+#include <Select3D_TypeOfSensitivity.hxx>
+
+#include <Handle_SelectBasics_EntityOwner.hxx>
+
+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 <Select3D_SensitivePoly.lxx>
+
+#endif // _Select3D_SensitivePoly_HeaderFile
index 4acf436..4cc2817 100644 (file)
 // commercial license or contractual agreement.
 
 #include<Select3D_Pnt.hxx>
-#include<Select3D_Pnt2d.hxx>
 #include<TColgp_HArray1OfPnt.hxx>
 #include<TColgp_Array1OfPnt2d.hxx>
 
-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 (file)
index 3f5c13d..0000000
+++ /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 <mymaxrect>
-       ---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;
-
-
-
-
-
-
-
-
index 5c6ea76..867985e 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveSegment.ixx>
-#include <SelectBasics_BasicTool.hxx>
+#include <Select3D_SensitiveSegment.hxx>
 #include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-#include <Bnd_Box2d.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Dir2d.hxx>
-#include <gp_Lin2d.hxx>
-#include <ElCLib.hxx>
-#include <Extrema_ExtElC.hxx>
-#include <Extrema_POnCurv.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
+#include <TopLoc_Location.hxx>
 #include <Precision.hxx>
-#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
 
-#include <CSLib_Class2d.hxx>
+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);
+    gp_Pnt aCenter = CenterOfGeometry();
+    aDistToCOG = theMgr.DistToGeometryCenter (aCenter);
   }
-  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;
-  }
-
-  theMatchDepth = ComputeDepth (thePickArgs.PickLine());
 
-  return !thePickArgs.IsClipped (theMatchDepth);
-}
-
-//=====================================================
-// Function : Matches
-// Purpose  :
-//=====================================================
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
 
-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;
+  return isMatched;
 }
 
 //=======================================================================
-//function : Matches
+//function : GetConnected
 //purpose  :
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveSegment::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
-         const Bnd_Box2d& aBox,
-         const Standard_Real aTol)
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::GetConnected()
 {
-  Standard_Real Umin,Vmin,Umax,Vmax;
-  aBox.Get(Umin,Vmin,Umax,Vmax);
-  CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
+  Handle(Select3D_SensitiveSegment) aNewEntity =
+    new Select3D_SensitiveSegment (myOwnerId, myStart, myEnd);
 
-  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;
+  return aNewEntity;
 }
 
-
 //=======================================================================
-//function : GetConnected
-//purpose  :
+// function : CenterOfGeometry
+// purpose  : Returns center of the segment. If location transformation
+//            is set, it will be applied
 //=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::
-GetConnected(const TopLoc_Location& aLoc)
+gp_Pnt Select3D_SensitiveSegment::CenterOfGeometry() const
 {
-  Handle(Select3D_SensitiveSegment) NiouEnt =
-    new Select3D_SensitiveSegment(myOwnerId,mystart,myend,mymaxrect);
-
-  if(HasLocation()) NiouEnt->SetLocation(Location());
-  NiouEnt->UpdateLocation(aLoc);
-  return NiouEnt;
+  return (myStart.XYZ() + myEnd.XYZ()) * 0.5;
 }
 
 //=======================================================================
-//function : Dump
-//purpose  :
+// function : BoundingBox
+// purpose  : Returns bounding box of the segment. If location
+//            transformation is set, it will be applied
 //=======================================================================
-
-void Select3D_SensitiveSegment::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const
+Select3D_BndBox3d Select3D_SensitiveSegment::BoundingBox()
 {
-  S<<"\tSensitivePoint 3D :"<<endl;
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-  S<<"\t\t P1 [ "<<mystart.x<<" , "<<mystart.y <<" , "<<mystart.z <<" ]"<<endl;
-  S<<"\t\t P2 [ "<<myend.x<<" , "<<myend.y <<" , "<<myend.z <<" ]"<<endl;
-  S<<"\t\t maxrect ="<<mymaxrect<<endl;
-
+  const SelectMgr_Vec3 aMinPnt (Min (myStart.X(), myEnd.X()),
+                                Min (myStart.Y(), myEnd.Y()),
+                                Min (myStart.Z(), myEnd.Z()));
+  const SelectMgr_Vec3 aMaxPnt (Max (myStart.X(), myEnd.X()),
+                                Max (myStart.Y(), myEnd.Y()),
+                                Max (myStart.Z(), myEnd.Z()));
+  return Select3D_BndBox3d (aMinPnt, aMaxPnt);
 }
+
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
+// function : NbSubElements
+// purpose  : Returns the amount of points
 //=======================================================================
-
-Standard_Real Select3D_SensitiveSegment::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Integer Select3D_SensitiveSegment::NbSubElements()
 {
-  gp_Pnt aP0 = mystart;
-  gp_Pnt aP1 = myend;
-
-  // if segment is degenerated (zero length), just use depth of the end
-  gp_XYZ aV = aP1.XYZ() - aP0.XYZ();
-  Standard_Real aNorm = aV.Modulus();
-  if ( aNorm <= gp::Resolution() )
-    return ElCLib::Parameter (EyeLine, aP0);
-
-  // else compute point on segment closest to the line
-  gp_Lin aLine (aP0, aV);
-  Extrema_ExtElC aTool (aLine, EyeLine, Precision::Angular());
-  if ( aTool.IsDone() && ! aTool.IsParallel() )
-  {
-    for (Standard_Integer i=1; i <= aTool.NbExt(); i++)
-    {
-      Extrema_POnCurv POL1, POL2;
-      aTool.Points (i, POL1, POL2);
-      // use point found by extrema only if it is inside segment
-      if ( POL1.Parameter() > 0. && POL1.Parameter() < aNorm )
-        return ElCLib::Parameter (EyeLine, POL1.Value());
-    }
-  }
-
-  // if extrema failed or lines are parallel, return closest of the segment ends
-  return Min (ElCLib::Parameter (EyeLine, aP0),
-              ElCLib::Parameter (EyeLine, aP1));
+  return 2;
 }
diff --git a/src/Select3D/Select3D_SensitiveSegment.hxx b/src/Select3D/Select3D_SensitiveSegment.hxx
new file mode 100644 (file)
index 0000000..48cca6a
--- /dev/null
@@ -0,0 +1,91 @@
+// Created on: 1995-01-25
+// 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 _Select3D_SensitiveSegment_HeaderFile
+#define _Select3D_SensitiveSegment_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Standard_Integer.hxx>
+#include <Select3D_Pnt.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <gp_Pnt.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_OStream.hxx>
+
+class SelectBasics_EntityOwner;
+class gp_Pnt;
+class TopLoc_Location;
+class TColgp_Array1OfPnt2d;
+
+
+//! A framework to define sensitive zones along a segment
+//!          One gives the 3D start and end point
+class Select3D_SensitiveSegment : public Select3D_SensitiveEntity
+{
+public:
+
+  //! Constructs the sensitive segment object defined by
+  //! the owner theOwnerId, the points theFirstPnt, theLastPnt
+  Standard_EXPORT Select3D_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                             const gp_Pnt& theFirstPnt,
+                                             const gp_Pnt& theLastPnt);
+
+  //! changes the start Point of the Segment;
+  void StartPoint (const gp_Pnt& thePnt);
+
+  //! changes the end point of the segment
+  void EndPoint (const gp_Pnt& thePnt);
+
+  //! gives the 3D start Point of the Segment
+  gp_Pnt StartPoint() const;
+
+  //! gives the 3D End Point of the Segment
+  gp_Pnt EndPoint() const;
+
+  //! Returns the amount of points
+  Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
+
+  //! Checks whether the segment overlaps current selecting volume
+  Standard_EXPORT   virtual  Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                       SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
+
+  //! Returns center of the segment. If location transformation
+  //! is set, it will be applied
+  Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
+
+  //! Returns bounding box of the segment. If location
+  //! transformation is set, it will be applied
+  Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI(Select3D_SensitiveSegment)
+
+private:
+
+  gp_Pnt myStart;      //!< Start point
+  gp_Pnt myEnd;        //!< End point
+};
+
+DEFINE_STANDARD_HANDLE(Select3D_SensitiveSegment, Select3D_SensitiveEntity)
+
+#include <Select3D_SensitiveSegment.lxx>
+
+#endif // _Select3D_SensitiveSegment_HeaderFile
index 5a23672..c5fd4fe 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-inline void Select3D_SensitiveSegment::Set(const Standard_Integer MaxRect)
-{mymaxrect = MaxRect;}
-
-inline void Select3D_SensitiveSegment::StartPoint (const gp_Pnt& start)
+//=======================================================================
+//function : StartPoint
+//purpose  :
+//=======================================================================
+inline void Select3D_SensitiveSegment::StartPoint (const gp_Pnt& thePnt)
 {
-  mystart = start;
+  myStart = thePnt;
 }
 
-inline void Select3D_SensitiveSegment::EndPoint (const gp_Pnt& end)
+//=======================================================================
+//function : EndPoint
+//purpose  :
+//=======================================================================
+inline void Select3D_SensitiveSegment::EndPoint (const gp_Pnt& thePnt)
 {
-  myend = end;
+  myEnd = thePnt;
 }
 
-inline gp_Pnt Select3D_SensitiveSegment::StartPoint () const
-{return mystart;}
-
-inline gp_Pnt Select3D_SensitiveSegment::EndPoint () const
-{return myend;}
-
-inline gp_Pnt2d Select3D_SensitiveSegment::StartPoint2d () const
-{return myprojstart;}
-
-inline gp_Pnt2d Select3D_SensitiveSegment::EndPoint2d () const
-{return myprojend;}
+//=======================================================================
+//function : StartPoint
+//purpose  :
+//=======================================================================
+inline gp_Pnt Select3D_SensitiveSegment::StartPoint() const
+{
+  return myStart;
+}
 
-inline Standard_Integer Select3D_SensitiveSegment::MaxBoxes()
-const {return mymaxrect;}
+//=======================================================================
+//function : EndPoint
+//purpose  :
+//=======================================================================
+inline gp_Pnt Select3D_SensitiveSegment::EndPoint() const
+{
+  return myEnd;
+}
diff --git a/src/Select3D/Select3D_SensitiveSet.cxx b/src/Select3D/Select3D_SensitiveSet.cxx
new file mode 100644 (file)
index 0000000..ed9b8b3
--- /dev/null
@@ -0,0 +1,178 @@
+// Created on: 2014-05-29
+// 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 <Select3D_SensitiveSet.hxx>
+#include <Select3D_BVHPrimitiveContent.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveSet, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSet, Select3D_SensitiveEntity)
+
+//=======================================================================
+// function : Select3D_SensitiveSet
+// purpose  : Creates new empty sensitive set and its content
+//=======================================================================
+Select3D_SensitiveSet::Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId)
+: Select3D_SensitiveEntity (theOwnerId)
+{
+  myDetectedIdx = -1;
+  myIsLeftChildQueuedFirst = Standard_False;
+  myContent = new Select3D_BVHPrimitiveContent (this);
+}
+
+//=======================================================================
+// function : BVH
+// purpose  : Builds BVH tree for sensitive set
+//=======================================================================
+void Select3D_SensitiveSet::BVH()
+{
+  myContent->GetBVH();
+}
+
+//=======================================================================
+// function : Matches
+// purpose  : Checks whether one or more entities of the set overlap
+//            current selecting volume. Implements the traverse of BVH
+//            tree built for the set
+//=======================================================================
+Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                 SelectBasics_PickResult& thePickResult)
+{
+  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = myContent->GetBVH();
+
+  Standard_Integer aNode = 0; // a root node
+  if (!theMgr.Overlaps (aBVHTree->MinPoint (0),
+                        aBVHTree->MaxPoint (0)))
+  {
+    return Standard_False;
+  }
+
+  Standard_Integer aStack[32];
+  Standard_Integer aHead = -1;
+  Standard_Real aDepth      = RealLast();
+  Standard_Real aDistToCOG  = RealLast();
+  SelectMgr_Vec3 aClosestPnt (RealLast());
+  Standard_Integer aMatchesNb = -1;
+  for (;;)
+  {
+    if (!aBVHTree->IsOuter (aNode))
+    {
+      const Standard_Integer aLeftChildIdx  = aBVHTree->LeftChild  (aNode);
+      const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
+      const Standard_Boolean isLeftChildIn  = theMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
+                                                               aBVHTree->MaxPoint (aLeftChildIdx));
+      const Standard_Boolean isRightChildIn = theMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
+                                                               aBVHTree->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 = aBVHTree->BegPrimitive (aNode);
+      Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
+      Standard_Boolean isMatched = Standard_False;
+      for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
+      {
+        Standard_Real anElementDepth = 0.0;
+        isMatched = overlapsElement (theMgr, anIdx, anElementDepth);
+        if (isMatched)
+        {
+          if (aDepth > anElementDepth)
+          {
+            aDepth = anElementDepth;
+            myDetectedIdx = anIdx;
+          }
+          aMatchesNb++;
+        }
+      }
+      if (aHead < 0)
+      {
+        break;
+      }
+
+      aNode = aStack[aHead];
+      --aHead;
+    }
+  }
+
+  if (aMatchesNb != -1)
+  {
+    aDistToCOG = distanceToCOG (theMgr);
+    thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
+    return Standard_True;
+  }
+
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
+  return Standard_False;
+}
+
+//=======================================================================
+// function : BoundingBox
+// purpose  : This method should be redefined in Select3D_SensitiveSet
+//            descendants
+//=======================================================================
+Select3D_BndBox3d Select3D_SensitiveSet::BoundingBox()
+{
+  return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()),
+                            SelectMgr_Vec3 (RealFirst()));
+}
+
+//=======================================================================
+// function : CenterOfGeometry
+// purpose  : This method should be redefined in Select3D_SensitiveSet
+//            descendants
+//=======================================================================
+gp_Pnt Select3D_SensitiveSet::CenterOfGeometry() const
+{
+  return gp_Pnt (RealLast(), RealLast(), RealLast());
+}
+
+//=======================================================================
+// function : MarkDirty
+// purpose  : Marks BVH tree of the set as outdated. It will be rebuild
+//            at the next call of BVH()
+//=======================================================================
+void Select3D_SensitiveSet::MarkDirty()
+{
+  myContent->MarkDirty();
+}
+
+//=======================================================================
+// function : Clear
+// purpose  : Destroys cross-reference to avoid memory leak
+//=======================================================================
+void Select3D_SensitiveSet::Clear()
+{
+  myContent.Nullify();
+}
diff --git a/src/Select3D/Select3D_SensitiveSet.hxx b/src/Select3D/Select3D_SensitiveSet.hxx
new file mode 100644 (file)
index 0000000..9c9d5f1
--- /dev/null
@@ -0,0 +1,114 @@
+// Created on: 2014-05-29
+// 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_SensitiveSet_Header
+#define _Select3D_SensitiveSet_Header
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <NCollection_Handle.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+
+class Select3D_BVHPrimitiveContent;
+
+//! This class is base class for handling overlap detection of complex sensitive
+//! entities. It provides an interface for building BVH tree for some set of entities.
+//! Thereby, each iteration of overlap detection is a traverse of BVH tree in fact.
+//! To use speed-up heirarchical structure in a custom complex sensitive entity, it is
+//! necessary to make that custom entity a descendant of this class and organize sub-entities
+//! in some container which allows referencing to elements by index. Note that methods taking
+//! index as a parameter are used for BVH build and the range of given index is [0; Size() - 1].
+//! For example of usage see Select3D_SensitiveTriangulation.
+class Select3D_SensitiveSet : public Select3D_SensitiveEntity
+{
+public:
+
+  //! Creates new empty sensitive set and its content
+  Standard_EXPORT Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId);
+
+  Standard_EXPORT ~Select3D_SensitiveSet() {};
+
+public:
+
+  //! Returns the amount of sub-entities of the complex entity
+  virtual Standard_Integer Size() const = 0;
+
+  //! Returns bounding box of sub-entity with index theIdx in sub-entity list
+  virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const = 0;
+
+  //! Returns geometry center of sensitive entity index theIdx along the given axis theAxis
+  virtual Standard_Real Center (const Standard_Integer theIdx,
+                                const Standard_Integer theAxis) const = 0;
+
+  //! Swaps items with indexes theIdx1 and theIdx2
+  virtual void Swap (const Standard_Integer theIdx1,
+                     const Standard_Integer theIdx2) = 0;
+
+  //! Checks whether one or more entities of the set overlap current selecting volume.
+  //! Implements the traverse of BVH tree built for the set
+  Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                    SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
+
+  //! Builds BVH tree for sensitive set.
+  //! Must be called manually to build BVH tree for any sensitive set
+  //! in case if its content was initialized not in a constructor,
+  //! but element by element
+  Standard_EXPORT void BVH();
+
+  //! Marks BVH tree of the set as outdated. It will be rebuild
+  //! at the next call of BVH()
+  Standard_EXPORT void MarkDirty();
+
+  //! Returns bounding box of the whole set.
+  //! This method should be redefined in Select3D_SensitiveSet descendants
+  Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
+
+  //! Returns center of the whole set.
+  //! This method should be redefined in Select3D_SensitiveSet descendants
+  Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
+
+  //! Destroys cross-reference to avoid memory leak
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
+public:
+  DEFINE_STANDARD_RTTI(Select3D_SensitiveSet)
+
+protected:
+
+  //! 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) = 0;
+
+  //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
+  virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) = 0;
+
+protected:
+  Standard_Integer myDetectedIdx;     //!< Index of detected primitive in BVH sorted primitive array, for debug purposes
+
+private:
+
+  Standard_Boolean                                 myIsLeftChildQueuedFirst;     //!< Flag for slight randomization of BVH traverse
+  NCollection_Handle<Select3D_BVHPrimitiveContent> myContent;                    //!< A link between sensitive entity and BVH_PrimitiveSet
+};
+
+DEFINE_STANDARD_HANDLE(Select3D_SensitiveSet, Select3D_SensitiveEntity)
+
+#endif // _Select3D_SensitiveSet_Header
diff --git a/src/Select3D/Select3D_SensitiveTriangle.cdl b/src/Select3D/Select3D_SensitiveTriangle.cdl
deleted file mode 100644 (file)
index 1332967..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
--- 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.
-
-class SensitiveTriangle from Select3D  
-inherits SensitivePoly from Select3D
-
-    ---Purpose: 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.
-
-uses
-    EntityOwner      from SelectBasics,
-    Projector        from Select3D,
-    Lin              from gp,
-    ListOfBox2d      from SelectBasics,
-    PickArgs         from SelectBasics,
-    Array1OfPnt2d    from TColgp,
-    Box2d            from Bnd,
-    XY               from gp,
-    Pnt              from gp,
-    TypeOfSensitivity from Select3D,
-    Location          from TopLoc, 
-    SensitiveEntity   from Select3D
-
-raises
-    ConstructionError from Standard,
-    OutOfRange from Standard
-
-is
-    Create (OwnerId      : EntityOwner from SelectBasics;
-            P1,P2,P3     : Pnt from gp;
-            Sensitivity  : TypeOfSensitivity = Select3D_TOS_INTERIOR)
-     returns SensitiveTriangle;
-    ---Level: Public 
-        ---Purpose: Constructs a sensitive triangle object defined by the
-        -- owner OwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity. 
-
-    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 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;EyeLine: Lin from gp) 
-    returns Real from Standard;
-
-
-    Points3D(me; P1,P2,P3 : out Pnt from gp) ;
-        ---Purpose: Returns the 3D points P1, P2, P3 used at the time of construction.
-    Center3D (me) returns Pnt from gp;
-        ---Purpose: Returns the center point of the sensitive triangle created at construction time.
-    Center2D (me) returns XY from gp;
-        ---Purpose: WARNING : the returned Values are the original values
-        --          without the stored  location (if there's one).
-        --          To get the genuine value, One must apply this location
-        --          (Method Location() )
-    
-    
-    
-    
-    Status(me; 
-             X,Y  : Real from Standard;
-             aTol : Real from Standard ;
-             Dmin : out Real from Standard)
-    returns Integer from Standard;
-    
-    Status (myclass;
-             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 return 
-
-    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 from Select3D;
-end SensitiveTriangle;
index fa712d4..0436ad4 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveTriangle.ixx>
+#include <Select3D_SensitiveTriangle.hxx>
 
-
-#include <SelectBasics_BasicTool.hxx>
-#include <gp_Pnt2d.hxx>
 #include <gp_Pnt.hxx>
-#include <gp_Dir2d.hxx>
 #include <Precision.hxx>
 #include <Bnd_Box.hxx>
-#include <ElCLib.hxx>
 #include <TopLoc_Location.hxx>
 
-#include <CSLib_Class2d.hxx>
-
-static Standard_Boolean S3D_Str_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP,
-                                             const Standard_Real aTol, Standard_Real& aDMin)
-{
-  gp_XY V01(p1);
-  V01 -= p0;
-
-  gp_XY Vec(TheP);
-  Vec -= p0;
-
-  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;
-}
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveTriangle, Select3D_SensitiveEntity)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveTriangle, Select3D_SensitiveEntity)
 
 //==================================================
 // Function: Creation
 // Purpose :
 //==================================================
-
-Select3D_SensitiveTriangle::
-Select3D_SensitiveTriangle(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                           const gp_Pnt& P0,
-                           const gp_Pnt& P1,
-                           const gp_Pnt& P2,
-                           const Select3D_TypeOfSensitivity aType):
-Select3D_SensitivePoly(OwnerId,3),
-mytype (aType)
-{
-  mypolyg.SetPnt(0, P0);
-  mypolyg.SetPnt(1, P1);
-  mypolyg.SetPnt(2, P2);
-}
-
-//==================================================
-// Function: Matches
-// Purpose :
-//==================================================
-
-Standard_Boolean Select3D_SensitiveTriangle::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                      Standard_Real& theMatchDMin,
-                                                      Standard_Real& theMatchDepth)
+Select3D_SensitiveTriangle::Select3D_SensitiveTriangle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+                                                        const gp_Pnt& thePnt0,
+                                                        const gp_Pnt& thePnt1,
+                                                        const gp_Pnt& thePnt2,
+                                                        const Select3D_TypeOfSensitivity theType)
+: Select3D_SensitivePoly (theOwnerId, Standard_False, 3),
+  mySensType (theType)
 {
-  Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
-  if (thePickArgs.IsClipped (aDepth))
-  {
-    return Standard_False;
-  }
-
-  theMatchDepth = aDepth;
-
-  if (Bnd_Box2d (mybox2d).IsOut (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())))
-  {
-    return Standard_False;
-  }
-
-  Standard_Integer Res;
-  switch (mytype)
-  {
-  case Select3D_TOS_BOUNDARY:
-    Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
-    return Res== 1;
-    break;
-  case Select3D_TOS_INTERIOR:
-    Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
-    return (Res==0 || Res == 1);
-  default:
-    break;
-  }
-
-  return Standard_True;
+  myPolyg.SetPnt (0, thePnt0);
+  myPolyg.SetPnt (1, thePnt1);
+  myPolyg.SetPnt (2, thePnt2);
+  myCentroid = (gp_XYZ (myPolyg.Pnt (0)) + gp_XYZ (myPolyg.Pnt (1)) + gp_XYZ (myPolyg.Pnt (2)))
+                * (0.3);
 }
 
 //==================================================
 // Function: Matches
-// Purpose :
+// Purpose : Checks whether the triangle overlaps
+//           current selecting volume
 //==================================================
-
-Standard_Boolean Select3D_SensitiveTriangle::
-Matches (const Standard_Real XMin,
-         const Standard_Real YMin,
-         const Standard_Real XMax,
-         const Standard_Real YMax,
-         const Standard_Real aTol)
+Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                      SelectBasics_PickResult& thePickResult)
 {
-  Bnd_Box2d B;
-  B.Update(Min(XMin,XMax)-aTol,
-           Min(YMin,YMax)-aTol,
-           Max(XMin,XMax)+aTol,
-           Max(YMin,YMax)+aTol);
-  for(Standard_Integer anIndex=0;anIndex<=2;++anIndex)
+  Standard_Real aDepth     = RealLast();
+  Standard_Real aDistToCOG = RealLast();
+  gp_Pnt aPnt1 = myPolyg.Pnt3d (0);
+  gp_Pnt aPnt2 = myPolyg.Pnt3d (1);
+  gp_Pnt aPnt3 = myPolyg.Pnt3d (2);
+  Standard_Boolean isMatched = theMgr.Overlaps (aPnt1, aPnt2, aPnt3, mySensType, aDepth);
+  if (isMatched)
   {
-    if(B.IsOut(mypolyg.Pnt2d(anIndex)))
-      return Standard_False;
+    aDistToCOG = theMgr.DistToGeometryCenter (myCentroid);
   }
-  return Standard_True;
-}
 
-//=======================================================================
-//function : Matches
-//purpose  :
-//=======================================================================
+  thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
 
-Standard_Boolean Select3D_SensitiveTriangle::
-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 anIndex=0;anIndex<=2;++anIndex)
-  {
-    Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
-    if(RES!=1)
-      return Standard_False;
-  }
-  return Standard_True;
+  return isMatched;
 }
 
 //==================================================
 // Function: Points3D
 // Purpose :
 //==================================================
-
-void Select3D_SensitiveTriangle::Points3D(gp_Pnt& P0,gp_Pnt& P1,gp_Pnt& P2) const
+void Select3D_SensitiveTriangle::Points3D (gp_Pnt& thePnt0, gp_Pnt& thePnt1, gp_Pnt& thePnt2) const
 {
-  P0 = mypolyg.Pnt(0);
-  P1 = mypolyg.Pnt(1);
-  P2 = mypolyg.Pnt(2);
+  thePnt0 = myPolyg.Pnt (0);
+  thePnt1 = myPolyg.Pnt (1);
+  thePnt2 = myPolyg.Pnt (2);
 }
 
 //==================================================
 // Function: Center3D
 // Purpose :
 //==================================================
-
 gp_Pnt Select3D_SensitiveTriangle::Center3D() const
 {
   gp_XYZ aPnt1, aPnt2, aPnt3;
-  aPnt1 = mypolyg.Pnt(0);
-  aPnt2 = mypolyg.Pnt(1);
-  aPnt3 = mypolyg.Pnt(2);
-  return gp_Pnt((aPnt1+aPnt2+aPnt3)/3.);
+  aPnt1 = myPolyg.Pnt (0);
+  aPnt2 = myPolyg.Pnt (1);
+  aPnt3 = myPolyg.Pnt (2);
+  return gp_Pnt ((aPnt1 + aPnt2 + aPnt3) / 3.0);
 }
 
 //==================================================
-// Function: Center2D
+// Function: GetConnected
 // Purpose :
 //==================================================
-
-gp_XY Select3D_SensitiveTriangle::Center2D() const
-{
-  gp_XY aPnt1, aPnt2, aPnt3;
-  aPnt1 = mypolyg.Pnt2d(0);
-  aPnt2 = mypolyg.Pnt2d(1);
-  aPnt3 = mypolyg.Pnt2d(2);
-  return (aPnt1+aPnt2+aPnt3)/3.;
-}
-
-//=======================================================================
-//function : Status
-//purpose  : 0 = inside /1 = Boundary/ 2 = outside
-//=======================================================================
-
-Standard_Integer  Select3D_SensitiveTriangle::Status(const Standard_Real X,
-                                                     const Standard_Real Y,
-                                                     const Standard_Real aTol,
-                                                     Standard_Real& DMin) const
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle::GetConnected()
 {
-  return Status(mypolyg.Pnt2d(0), mypolyg.Pnt2d(1), mypolyg.Pnt2d(2),
-                gp_XY(X,Y), aTol, DMin);
-}
-
-//=======================================================================
-//function : Status
-//purpose  :
-//=======================================================================
-
-Standard_Integer  Select3D_SensitiveTriangle::Status(const gp_XY& p0,
-                                                     const gp_XY& p1,
-                                                     const gp_XY& p2,
-                                                     const gp_XY& TheP,
-                                                     const Standard_Real aTol,
-                                                     Standard_Real& DMin)
-{
-  Bnd_Box2d B;
-  B.Update(p0.X(),p0.Y());B.Update(p1.X(),p1.Y());B.Update(p2.X(),p2.Y());
-  B.Enlarge(aTol);
-  if(B.IsOut(TheP)) return 2;
-
-  // the point is classified corresponding to demi-spaces limited
-  // by each side of the triangle (with tolerance)
-  gp_XY V01(p1);V01-=p0;
-  gp_XY V02(p2);V02-=p0;
-  gp_XY V12(p2);V12-=p1;
-
-  // check these particular cases...
-  // if one of vectors is almost null (2 points are mixed),
-  // leave at once (it is already in the bounding box, which is good...)
-
-  DMin = aTol;
-
-  if ( V01.SquareModulus() <= gp::Resolution() )
-  {
-    Standard_Real LV = V02.SquareModulus();
-    if ( LV <= gp::Resolution())
-      return 0; // 3 points are mixed, and TheP is in the bounding box B...
-
-    if ( S3D_Str_NearSegment (p0, p2, TheP, aTol, DMin) )
-      return 0;
-    return 2;
-  }
-  if ( V02.SquareModulus() <= gp::Resolution() )
-  {
-    if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
-      return 0;
-    return 2;
-  }
-  if ( V12.SquareModulus() <= gp::Resolution() )
-  {
-    if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
-      return 0;
-    return 2;
-  }
-  if ( V01.CrossMagnitude(V02) <= gp::Resolution() )
-  {
-    if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
-      return 0;
-    return 2;
-  }
-
-  // oriented normal to p0p1...
-  gp_Dir2d N (-V01.Y(), V01.X());
-  Standard_Boolean Neg = (N * V02 < 0.);
-  if ( Neg )
-    N.Reverse();
-
-  gp_XY Vec(TheP);
-  Vec -= p0;
-
-  Standard_Real aD1 = Vec * N.XY();
-  if ( aD1 < -aTol )
-    return 2;
-
-  // oriented normal to p1p2...
-  if(Neg)
-    N.SetCoord(p2.Y()-p1.Y(),p1.X()-p2.X());
-  else
-    N.SetCoord(p1.Y()-p2.Y(),p2.X()-p1.X());
-
-  Vec.SetCoord(TheP.X()-p1.X(),TheP.Y()-p1.Y());
-  Standard_Real aD2 = Vec * N.XY();
-  if ( aD2 < -aTol )
-    return 2;   // outside
-
-  // oriented normal to p2p0...
-  // attention v20 (x0-x2)    =>   N y2-y0   => -N  y0-y2
-  //               (y0-y2)           x0-x2          x2-x0
-  if(Neg)
-    N.SetCoord(p0.Y()-p2.Y(),p2.X()-p0.X());
-  else
-    N.SetCoord(p2.Y()-p0.Y(),p0.X()-p2.X());
-
-  Vec.SetCoord(TheP.X()-p2.X(),TheP.Y()-p2.Y());
-  Standard_Real aD3 = Vec * N.XY();
-  if ( aD3 < -aTol )
-    return 2;  // outside
-
-  // compute 2d distance to triangle
-  Standard_Real aD = Min (aD1, Min (aD2, aD3));
-  DMin = ( aD < 0 ? -aD : 0. );
-  return 0;
-}
-
-//=======================================================================
-//function : Dump
-//purpose  :
-//=======================================================================
-
-void Select3D_SensitiveTriangle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
-{
-  // general information....
-
-  S<<"\tSensitiveTriangle 3D :\n";
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-
-  gp_Pnt aPnt1, aPnt2, aPnt3;
-  aPnt1 = mypolyg.Pnt(0);
-  aPnt2 = mypolyg.Pnt(1);
-  aPnt3 = mypolyg.Pnt(2);
-  S<<"\t\t P0 [ "<<aPnt1.X()<<" , "<<aPnt1.Y()<<" , "<<aPnt1.Z()<<" ]"<<endl;
-  S<<"\t\t P1 [ "<<aPnt2.X()<<" , "<<aPnt2.Y()<<" , "<<aPnt2.Z()<<" ]"<<endl;
-  S<<"\t\t P2 [ "<<aPnt3.X()<<" , "<<aPnt3.Y()<<" , "<<aPnt3.Z()<<" ]"<<endl;
-
-  if(FullDump)
-  {
-    S<<"\t\tProjected Points"<<endl;
+  // Create a copy of this
+  Handle(Select3D_SensitiveEntity) aNewEntity =
+    new Select3D_SensitiveTriangle (myOwnerId, myPolyg.Pnt(0), myPolyg.Pnt(1), myPolyg.Pnt(2), mySensType);
 
-    gp_Pnt2d aPnt1, aPnt2, aPnt3;
-    aPnt1 = mypolyg.Pnt2d(0);
-    aPnt2 = mypolyg.Pnt2d(1);
-    aPnt3 = mypolyg.Pnt2d(2);
-    S<<"\t\t  0.[ "<<aPnt1.X()<<" , "<<aPnt1.Y()<<" ]"<<endl;
-    S<<"\t\t  1.[ "<<aPnt2.X()<<" , "<<aPnt2.Y()<<" ]"<<endl;
-    S<<"\t\t  2.[ "<<aPnt3.X()<<" , "<<aPnt3.Y()<<" ]"<<endl;
-    Select3D_SensitiveEntity::DumpBox(S,mybox2d);
-  }
+  return aNewEntity;
 }
 
-//=======================================================================
-//function : ComputeDepth
-//purpose  :
-//=======================================================================
-
-Standard_Real Select3D_SensitiveTriangle::ComputeDepth(const gp_Lin& EyeLine) const
+//==================================================
+// Function: BoundingBox
+// Purpose : Returns bounding box of the triangle.
+//           If location transformation is set, it
+//           will be applied
+//==================================================
+Select3D_BndBox3d Select3D_SensitiveTriangle::BoundingBox()
 {
-  Standard_Real prof(Precision::Infinite());
-
-  gp_Pnt P1, P2, P3;
-  P1 = mypolyg.Pnt(0);
-  P2 = mypolyg.Pnt(1);
-  P3 = mypolyg.Pnt(2);
-
-  gp_Trsf TheTrsf ;
-  if(HasLocation())
-    TheTrsf = Location().Transformation();
-
-  if(TheTrsf.Form()!=gp_Identity)
-  {
-    P1.Transform(TheTrsf);
-    P2.Transform(TheTrsf);
-    P3.Transform(TheTrsf);
-  }
-
-  // formula calculation of the point parameters on intersection
-  // t = (P1P2 ^P1P3)* OP1  / ((P1P2^P1P3)*Dir)
-
-  gp_Pnt Oye  = EyeLine.Location(); // origin of the target line eye/point...
-  gp_Dir Dir  = EyeLine.Direction();
-
-  gp_Vec P1P2 (P1,P2), P1P3(P1,P3);
-  P1P2.Normalize();
-  P1P3.Normalize();
-
-  gp_Vec oP1(Oye,P1);
-  Standard_Real val1 = oP1.DotCross(P1P2,P1P3);
-  Standard_Real val2 = Dir.DotCross(P1P2,P1P3);
-
-  if(Abs(val2)>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;
+  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: GetConnected
-// Purpose :
+// Function: NbSubElements
+// Purpose : Returns the amount of points
 //==================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle::
-GetConnected(const TopLoc_Location &theLocation)
+Standard_Integer Select3D_SensitiveTriangle::NbSubElements()
 {
-  // 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);
-
-  return aNewEntity;
+  return 3;
 }
diff --git a/src/Select3D/Select3D_SensitiveTriangle.hxx b/src/Select3D/Select3D_SensitiveTriangle.hxx
new file mode 100644 (file)
index 0000000..1f17b09
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_TypeOfSensitivity.hxx>
+#include <Select3D_Pnt.hxx>
+#include <Select3D_SensitivePoly.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_OStream.hxx>
+
+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 (file)
index b6ae045..0000000
+++ /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 <boxes> 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;
index 694fc71..b552d92 100644 (file)
 // 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 <algorithm>
 
-#include <Select3D_SensitiveTriangulation.ixx>
-#include <gp_Pnt2d.hxx>
 #include <Poly.hxx>
 #include <Poly_Connect.hxx>
-#include <CSLib_Class2d.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <Select3D_SensitiveTriangle.hxx>
 #include <Precision.hxx>
-#include <ElCLib.hxx>
-#include <CSLib_Class2d.hxx>
+#include <Select3D_TypeOfSensitivity.hxx>
 
+#include <Select3D_SensitiveTriangulation.hxx>
 
-static Standard_Integer S3D_NumberOfFreeEdges(const Handle(Poly_Triangulation)& Trg)
-{
-  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++;
-  }
-  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;
-}
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
 
-// 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)
+static Standard_Integer NbOfFreeEdges (const Handle(Poly_Triangulation)& theTriangulation)
 {
-  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;
+  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 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...
-
-  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];
-
-  // to find connections in case when the border is not concerned...
-  if(!myIntFlag)
+  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);
+
+  myPrimitivesNb = theIsInterior ? aNbTriangles : NbOfFreeEdges (theTrg);
+  myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
+  TColStd_Array1OfInteger& aBVHPrimIdxs = myBVHPrimIndexes->ChangeArray1();
+
+  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++)
+  else
+  {
+    Standard_Integer aTrNodeIdx[3];
+    for (Standard_Integer aTrIdx = 1; aTrIdx <= aNbTriangles; aTrIdx++)
     {
-      triangles(i).Get(n[0],n[1],n[2]);
-      cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
+      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 (aNbTriangles != 0)
+    aCenter /= aNbTriangles;
+  myCDG3D = gp_Pnt (aCenter);
 
-  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);
+  myBndBox.Clear();
+  for (Standard_Integer aNodeIdx = 1; aNodeIdx <= myTriangul->NbNodes(); ++aNodeIdx)
+  {
+    myBndBox.Add (SelectMgr_Vec3 (aNodes (aNodeIdx).X(),
+                                  aNodes (aNodeIdx).Y(),
+                                  aNodes (aNodeIdx).Z()));
   }
 
-  aPrj->Project(myCDG3D,myCDG2D);
+  if (theIsInterior)
+  {
+    for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; ++aTriangleIdx)
+    {
+      aBVHPrimIdxs (aTriangleIdx - 1) = aTriangleIdx - 1;
+    }
+  }
+  else
+  {
+    Standard_Integer aStartIdx = myFreeEdges->Lower();
+    Standard_Integer anEndIdx = myFreeEdges->Upper();
+    for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
+    {
+      aBVHPrimIdxs ((aFreeEdgesIdx - aStartIdx) / 2) = (aFreeEdgesIdx - aStartIdx) / 2;
+    }
+  }
 }
 
-//=======================================================================
-//function : Areas
-//purpose  :
-//=======================================================================
-
-void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
-{
-  boxes.Append(mybox2d);
-}
 
 //=======================================================================
-//function : Matches
+//function : Select3D_SensitiveTriangulation
 //purpose  :
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                           Standard_Real& theMatchDMin,
-                                                           Standard_Real& theMatchDepth)
+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)
 {
-  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)
+  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)
   {
-    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++)
+    for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= myPrimitivesNb; ++aTriangleIdx)
     {
-      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);
-      }
+      myBVHPrimIndexes->SetValue (aTriangleIdx - 1, aTriangleIdx - 1);
     }
   }
-
-  //    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 aStartIdx = myFreeEdges->Lower();
+    Standard_Integer anEndIdx = myFreeEdges->Upper();
+    for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
     {
-      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
-          }
-        }
-      }
+      myBVHPrimIndexes->SetValue ((aFreeEdgesIdx - aStartIdx) / 2, (aFreeEdgesIdx - aStartIdx) / 2);
     }
   }
-  if ( myDetectedTr <= 0 )
-    return Standard_False;
-
-  // 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  :
+// function : Size
+// purpose  : Returns the length of array of triangles or edges
 //=======================================================================
-
-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)
+Standard_Integer Select3D_SensitiveTriangulation::Size() const
 {
-  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++)
-  {
-    if(B.IsOut(myNodes2d(i)))
-      return Standard_False;
-  }
-  return Standard_True;
+  return myPrimitivesNb;
 }
 
 //=======================================================================
-//function : Matches
-//purpose  :
+// function : Box
+// purpose  : Returns bounding box of triangle/edge with index theIdx
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveTriangulation::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
-         const Bnd_Box2d& aBox,
-         const Standard_Real aTol)
+Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer theIdx) const
 {
-  Standard_Real Umin,Vmin,Umax,Vmax;
-  aBox.Get(Umin,Vmin,Umax,Vmax);
-  CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
+  Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx);
+  SelectMgr_Vec3 aMinPnt (RealLast());
+  SelectMgr_Vec3 aMaxPnt (RealFirst());
+  Standard_Boolean hasInitLoc = HasInitLocation();
 
-  for(Standard_Integer j=1;j<=myNodes2d.Length();j++)
+  if (mySensType == Select3D_TOS_INTERIOR)
   {
-    Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j));
-    if(RES!=1) return Standard_False;
+    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 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);
+  return Select3D_BndBox3d (aMinPnt, aMaxPnt);
 }
 
 //=======================================================================
-//function : IsFree
-//purpose  :
+// function : Center
+// purpose  : Returns geometry center of triangle/edge with index theIdx
+//            in array along the given axis theAxis
 //=======================================================================
-
-Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle,
-                                                         Standard_Integer& FoundIndex) const
+Standard_Real Select3D_SensitiveTriangulation::Center (const Standard_Integer theIdx,
+                                                       const Standard_Integer theAxis) 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)
-  {
-    if(FreeE(I) == n[0])
-    {
-      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;
-    }
-  }
-
-  return FoundIndex!=-1;
+  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 : GetConnected
-//purpose  :
+// function : Swap
+// purpose  : Swaps items with indexes theIdx1 and theIdx2 in array
 //=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::
-GetConnected(const TopLoc_Location& aLoc)
+void Select3D_SensitiveTriangulation::Swap (const Standard_Integer theIdx1,
+                                            const Standard_Integer theIdx2)
 {
-  Handle(Select3D_SensitiveTriangulation) NiouEnt =
-    new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag);
-
-  if(HasLocation())
-    NiouEnt->SetLocation(Location());
-//  TopLoc_Location TheLocToApply = HasLocation() ?  Location()*aLoc : aLoc;
-//  if(!TheLocToApply.IsIdentity())
-  NiouEnt->UpdateLocation(aLoc);
+  Standard_Integer anElemIdx1 = myBVHPrimIndexes->Value (theIdx1);
+  Standard_Integer anElemIdx2 = myBVHPrimIndexes->Value (theIdx2);
 
-  return NiouEnt;
+  myBVHPrimIndexes->ChangeValue (theIdx1) = anElemIdx2;
+  myBVHPrimIndexes->ChangeValue (theIdx2) = anElemIdx1;
 }
 
 //=======================================================================
-//function : ResetLocation
-//purpose  :
+// function : overlapsElement
+// purpose  : Checks whether the element with index theIdx overlaps the
+//            current selecting volume
 //=======================================================================
-
-void Select3D_SensitiveTriangulation::ResetLocation()
+Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
+                                                                   Standard_Integer theElemIdx,
+                                                                   Standard_Real& theMatchDepth)
 {
-  Select3D_SensitiveEntity::ResetLocation();
-  ComputeTotalTrsf();
+  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 : SetLocation
-//purpose  :
+// function : distanceToCOG
+// purpose  : Calculates distance from the 3d projection of used-picked
+//            screen point to center of the geometry
 //=======================================================================
-
-void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc)
+Standard_Real Select3D_SensitiveTriangulation::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
 {
-  Select3D_SensitiveEntity::SetLocation(aLoc);
-  ComputeTotalTrsf();
+  return theMgr.DistToGeometryCenter (myCDG3D);
 }
 
-
 //=======================================================================
-//function : Dump
+//function : GetConnected
 //purpose  :
 //=======================================================================
-void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::GetConnected()
 {
-  S<<"\tSensitiveTriangulation 3D :"<<endl;
-  if(myiniloc.IsIdentity())
-    S<<"\t\tNo Initial Location"<<endl;
-  else
-    S<<"\t\tExisting Initial Location"<<endl;
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-
-  S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl;
-  S<<"\t\tNb Nodes     : "<<myTriangul->NbNodes()<<endl;
-  S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl;
+  Standard_Boolean isInterior = mySensType == Select3D_TOS_INTERIOR;
+  Handle(Select3D_SensitiveTriangulation) aNewEntity =
+    new Select3D_SensitiveTriangulation (myOwnerId, myTriangul, myInitLocation, myFreeEdges, myCDG3D, isInterior);
 
-  if(FullDump)
-  {
-//    S<<"\t\t\tOwner:"<<myOwnerId<<endl;
-    Select3D_SensitiveEntity::DumpBox(S,mybox2d);
-  }
+  return aNewEntity;
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
+// function : applyTransformation
+// purpose  : Inner function for transformation application to bounding
+//            box of the triangulation
 //=======================================================================
-
-Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
-                                                            const Standard_Integer theTriangle) const
+Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation()
 {
-  if (theTriangle == -1)
-  {
-    return Precision::Infinite(); // currently not implemented...
-  }
-
-  const Poly_Array1OfTriangle& triangles = myTriangul->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++)
-    {
-      P[i].Transform (myTrsf);
-    }
-  }
-
-  // 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;
-  }
+  if (!HasInitLocation())
+    return myBndBox;
 
-  // 3 pts mixed...
-  if (SingularCase ==2)
+  Select3D_BndBox3d aBndBox;
+  for (Standard_Integer aX = 0; aX <=1; ++aX)
   {
-    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())
+    for (Standard_Integer aY = 0; aY <=1; ++aY)
     {
-      prof = val1 / val2;
+      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()));
+      }
     }
   }
 
-  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);
-
-  P1 = Nodes(n1);
-  P2 = Nodes(n2);
-  P3 = Nodes(n3);
-  if(myTrsf.Form()!=gp_Identity)
+  if (myBndBox.IsValid())
+    return applyTransformation();
+
+  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;
 
-//=============================================================================
-// Function : DetectedTriangle2d
-// Purpose  :
-//=============================================================================
+  return applyTransformation();
+}
 
-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 (file)
index 0000000..ae90d64
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Handle_Poly_Triangulation.hxx>
+#include <TopLoc_Location.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Pnt.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <Handle_TColStd_HArray1OfInteger.hxx>
+#include <Standard_Boolean.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <Standard_OStream.hxx>
+#include <Select3D_SensitiveSet.hxx>
+#include <NCollection_Handle.hxx>
+
+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 <Select3D_SensitiveTriangulation.lxx>
+
+
+#endif // _Select3D_SensitiveTriangulation_Header
index f19ee25..4da2197 100644 (file)
 // 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
+//=======================================================================
+//function : HasInitLocation
+//purpose  :
+//=======================================================================
+inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
 {
-  return myCDG2D;
+  return !myInitLocation.IsIdentity();
 }
 
-inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
-{return !myiniloc.IsIdentity();}
+//=======================================================================
+//function : GetInitLocation
+//purpose  :
+//=======================================================================
 inline const TopLoc_Location& Select3D_SensitiveTriangulation::GetInitLocation() const
-{return myiniloc;}
-
-inline Standard_Integer Select3D_SensitiveTriangulation::DetectedTriangle() const
 {
-  return myDetectedTr;
+  return myInitLocation;
 }
diff --git a/src/Select3D/Select3D_SensitiveWire.cdl b/src/Select3D/Select3D_SensitiveWire.cdl
deleted file mode 100644 (file)
index 7e33fe6..0000000
+++ /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 <mymaxrect>
-           
-    
-    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 <mymaxrect>
-
-fields
-    mysensitive     : SensitiveEntitySequence from Select3D;
-    myDetectedIndex : Integer from Standard;
-end SensitiveWire;
-
-
-
-
-
-
-
-
index e95478f..e7280b7 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Select3D_SensitiveWire.ixx>
-#include <SelectBasics_BasicTool.hxx>
+#include <Select3D_SensitiveWire.hxx>
 #include <Select3D_SensitiveEntity.hxx>
-#include <Select3D_SensitiveEntitySequence.hxx>
-#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <Precision.hxx>
+#include <TopLoc_Location.hxx>
 
-#include <Bnd_Box2d.hxx>
-#include <ElCLib.hxx>
+#include <Select3D_SensitiveSegment.hxx>
 
-//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++)
-  {
-    mysensitive (aSensIt)->Project (aProj);
-  }
+  const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
+  return myEntities.Value (aSensitiveIdx)->BoundingBox();
 }
 
-//=====================================================
-// Function : Areas
-// Purpose  :
-//=====================================================
-
-void Select3D_SensitiveWire
-::Areas(SelectBasics_ListOfBox2d& theareas)
+//=======================================================================
+// 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
 {
-  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());
+  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());
 
-  theareas.Append(BB);
+  return aCenterCoord;
 }
 
-//=====================================================
-// Function : Matches
-// Purpose  :
-//=====================================================
-
-Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs,
-                                                  Standard_Real& theMatchDMin,
-                                                  Standard_Real& theMatchDepth)
+//=======================================================================
+// 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)
 {
-  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;
-  }
-
-  return isMatched;
+  const Standard_Integer aSensitiveIdx1 = myEntityIndexes.Value (theIdx1);
+  const Standard_Integer aSensitiveIdx2 = myEntityIndexes.Value (theIdx2);
+  myEntityIndexes.ChangeValue (theIdx1) = aSensitiveIdx2;
+  myEntityIndexes.ChangeValue (theIdx2) = aSensitiveIdx1;
 }
 
-//=====================================================
-// 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 : 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)
 {
-  Standard_Integer i;
-  for (i=1; i<=mysensitive.Length(); i++) 
+  const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
+  const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
+  SelectBasics_PickResult aMatchResult;
+  if (aSeg->Matches (theMgr, aMatchResult))
   {
-    if (!(mysensitive.Value(i)->Matches(XMin,YMin,XMax,YMax,aTol)))
-      return Standard_False;
+    theMatchDepth = aMatchResult.Depth();
+    return Standard_True;
   }
-  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;
+  return Standard_False;
 }
 
-
-//=====================================================
-// Function : MaxBoxes
-// Purpose  :
-//=====================================================
-
-Standard_Integer Select3D_SensitiveWire::
-MaxBoxes () const
+// =======================================================================
+// 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)
 {
-  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 :"<<endl;;
-  if(HasLocation())
-    S<<"\t\tExisting Location"<<endl;
-  S<<"\t\tComposed Of "<<mysensitive.Length()<<" Sensitive Entities"<<endl;
-
-  for(Standard_Integer i=1;i<= mysensitive.Length();i++){
-    S<<"Sensitive #"<<i<<" : "<<endl;
-    mysensitive(i)->Dump(S,FullDump);}
-
-  S<<"\tEnd Of Sensitive Wire"<<endl;
+  Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
+  for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
+    aNewEntity->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<Handle(Select3D_SensitiveEntity)>& 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 (file)
index 0000000..7513759
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Type.hxx>
+
+#include <Select3D_SensitiveSet.hxx>
+#include <Handle_SelectBasics_EntityOwner.hxx>
+#include <Standard_OStream.hxx>
+#include <NCollection_Sequence.hxx>
+
+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<Handle(Select3D_SensitiveEntity)>& 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<Handle(Select3D_SensitiveEntity)> myEntities;          //!< Vector of sub-entities
+  NCollection_Vector<Standard_Integer>                 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 (file)
index 0000000..25e476b
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _Select3D_TypeOfSensitivity_HeaderFile
+#define _Select3D_TypeOfSensitivity_HeaderFile
+
+#include <Standard_PrimitiveTypes.hxx>
+
+//! 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
index 3649dd9..d105e63 100644 (file)
@@ -1 +1,2 @@
-SelectBasics_PickArgs.hxx
\ No newline at end of file
+SelectBasics_PickResult.hxx
+SelectBasics_SelectingVolumeManager.hxx
index 2845c06..afef21f 100644 (file)
 
 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 (file)
index e67525e..0000000
+++ /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 (file)
index d2a8789..0000000
+++ /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 <SelectBasics_BasicTool.ixx>
-#include <Precision.hxx>
-#include <gp_Vec2d.hxx>
-
-
-//==================================================
-// 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())<Min(C.X(),D.X())) return Standard_False;
-  if(Min(A.X(),B.X())>Max(C.X(),D.X())) return Standard_False;
-  if(Max(A.Y(),B.Y())<Min(C.Y(),D.Y())) return Standard_False;
-  if(Min(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/det<Precision::Confusion()) return Standard_False;
-  if(deta/det>1+Precision::Confusion()) return Standard_False;
-  if(detb/det<Precision::Confusion()) return Standard_False;
-  if(detb/det>1+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)<SqTol) ||
-     (apoint.SquareDistance(pEnd)<SqTol)){
-    DMin = 0.; 
-    return Standard_True;
-  }
-
-  //2. Checking if the mouse point projection onto the segment`s line
-  //   falls inside the segment.
-  if(AB.Dot(AC)>=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<aTol){
-         return Standard_True;
-       }
-    }
-  }
-    
-  return Standard_False;
-} 
-
-
-
-//==================================================
-// Function: 
-// Purpose :
-//==================================================
-
-Standard_Boolean SelectBasics_BasicTool:: 
-AutoInter (const TColgp_Array1OfPnt2d& points)
-{
-  for (Standard_Integer i=3;i<=points.Length()-1;i++)
-    {     
-      for (Standard_Integer j=1;j<=i-2;j++)
-       {
-         if (MatchSegments (points(i),
-                            points(i+1),
-                            points(j),
-                            points(j+1))) return Standard_True;
-       }
-    }
-  return Standard_False;
-}
-
-
-//==================================================
-// Function: 
-// Purpose :
-//==================================================
-
-Standard_Boolean SelectBasics_BasicTool::
-MatchPolyg2d (const TColgp_Array1OfPnt2d& tabpoint,
-             const Standard_Real X,
-             const Standard_Real Y,
-             const Standard_Real aTol,
-             Standard_Real& DMin,
-             Standard_Integer& Rank)
-{
-       Rank =0;
-       Standard_Boolean Found= Standard_False;
-
-       //In the cycle towarded enumeration of possibilities segment, which is selected from wire
-       for(Standard_Integer i=tabpoint.Lower();i<=tabpoint.Upper()-1&& !Found;i++)
-       {       
-               if(MatchSegment(tabpoint.Value(i),tabpoint.Value(i+1),X,Y,aTol,DMin))
-               {
-                       Rank=i;
-                       return Standard_True;
-               }       
-       }
-       return Standard_False;
-}
index cda2f58..17b3e28 100644 (file)
@@ -25,8 +25,3 @@ SelectBasics_EntityOwner
 ::SelectBasics_EntityOwner (const Standard_Integer aPriority):
 mypriority(aPriority)
 {}
-
-
-
-
-
diff --git a/src/SelectBasics/SelectBasics_PickArgs.hxx b/src/SelectBasics/SelectBasics_PickArgs.hxx
deleted file mode 100755 (executable)
index cceb3b3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// Created on: 2013-09-04
-// Created by: Anton POLETAEV
-// Copyright (c) 2013-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_PickArgs_HeaderFile
-#define _SelectBasics_PickArgs_HeaderFile
-
-#include <Standard_TypeDef.hxx>
-#include <gp_Lin.hxx>
-
-//! 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 (file)
index 0000000..9088525
--- /dev/null
@@ -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 <Standard.hxx>
+#include <NCollection_Vec4.hxx>
+
+//! 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 (file)
index 0000000..0596813
--- /dev/null
@@ -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 <BVH_Box.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <NCollection_Vec3.hxx>
+
+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<Standard_Real, 3>& 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<Standard_Real>& theMinPt,
+                                           const NCollection_Vec3<Standard_Real>& 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<Standard_Real> DetectedPoint (const Standard_Real theDepth) const = 0;
+
+protected:
+  SelectionType myActiveSelectionType;      //!< Active selection type: point, box or polyline
+};
+
+#endif // _SelectBasics_SelectingVolumeManager_HeaderFile
index 7be63b1..02d7d0f 100644 (file)
 
 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;
-    ---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 .
-    --          
-
-    Matches (me : mutable;
-             thePickArgs : PickArgs from SelectBasics;
-             theMatchDMin : out Real from Standard;
-             theMatchDepth : out Real from Standard) returns Boolean is deferred;
+    Set (me : mutable;
+         theOwnerId : EntityOwner)
+      is virtual;
     ---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.
-
-    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.
+    ---Purpose: Sets owner of the entity
 
 
-    Matches (me  :mutable; 
-             Polyline:Array1OfPnt2d from TColgp;
-            aBox:Box2d from Bnd;
-             aTol: Real from Standard)
-    returns Boolean
-    is deferred;    
+    OwnerId (me)
+      returns any EntityOwner
+      is static;
     ---Level: Public 
-    ---Purpose: returns True if the polyline xi,yi
-    --          contains the SensitiveEntity. 
-    --          Necessary for selection using polyline selection
+    ---C++: return const&
+    ---Purpose: Returns pointer to owner of the entity
 
-    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
 
+    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 is overlapped by
+    --          current selecting volume
 
-    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
 
-fields
-    
-    myOwnerId       : EntityOwner from SelectBasics is protected;
-    mySFactor       : ShortReal from Standard;
-end SensitiveEntity;
-
+    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       : Real from Standard;
+end SensitiveEntity;
index e047985..d69189c 100644 (file)
 // commercial license or contractual agreement.
 
 #include <SelectBasics_SensitiveEntity.ixx>
+#include <TColStd_HArray1OfBoolean.hxx>
 
+//=======================================================================
+// 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;
+}
index 23a6a9b..54df66f 100644 (file)
 // 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 (file)
index a21c176..0000000
+++ /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 (file)
index a6883bf..0000000
+++ /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 <SelectBasics_SortAlgo.ixx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <gp_Pnt2d.hxx>
-
-//=======================================================================
-//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();
-}
-
index 076e4ef..9bf32ba 100755 (executable)
@@ -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
index 805bc79..954487e 100644 (file)
@@ -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 (file)
index 0000000..cf64c83
--- /dev/null
@@ -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 <SelectMgr_BaseFrustum.hxx>
+
+//=======================================================================
+// 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<SelectMgr_FrustumBuilder>& 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<Standard_Real, 3>& /*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 (file)
index 0000000..32fb41a
--- /dev/null
@@ -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 <Bnd_Box.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Pln.hxx>
+
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_ClipPlane.hxx>
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
+
+#include <NCollection_Handle.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+#include <SelectMgr_FrustumBuilder.hxx>
+#include <Select3D_TypeOfSensitivity.hxx>
+#include <SelectMgr_VectorTypes.hxx>
+
+//! 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<SelectMgr_FrustumBuilder>& 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<SelectMgr_BaseFrustum> 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<Standard_Real, 3>& 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<SelectMgr_FrustumBuilder> myBuilder;      //!< A tool implementing methods for volume build
+};
+
+#endif // _SelectMgr_BaseFrustum_HeaderFile
index de07861..8a0b522 100644 (file)
@@ -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 (file)
index 0000000..84f4290
--- /dev/null
@@ -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 <BVH_Box.hxx>
+#include <gp_Pnt.hxx>
+#include <SelectMgr_BaseFrustum.hxx>
+#include <SelectMgr_FrustumBuilder.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+
+//! 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 <int N>
+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 <SelectMgr_Frustum.lxx>
+
+#endif // _SelectMgr_Frustum_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_Frustum.lxx b/src/SelectMgr/SelectMgr_Frustum.lxx
new file mode 100644 (file)
index 0000000..5480089
--- /dev/null
@@ -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 <NCollection_Vector.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+
+#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 <int N>
+Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+const Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+const Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+const Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+const Standard_Boolean SelectMgr_Frustum<N>::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 <int N>
+const Standard_Boolean SelectMgr_Frustum<N>::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 (file)
index 0000000..f57fc47
--- /dev/null
@@ -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 <SelectMgr_FrustumBuilder.hxx>
+
+#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<Standard_Real> (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<Standard_Real> 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<Standard_Real> 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<Standard_Real> 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<Standard_Real> 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 (file)
index 0000000..419b355
--- /dev/null
@@ -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 <Graphic3d_Camera.hxx>
+#include <NCollection_Handle.hxx>
+#include <Precision.hxx>
+#include <SelectMgr_VectorTypes.hxx>
+
+//! 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<Standard_Real>   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 (file)
index 0000000..a59892e
--- /dev/null
@@ -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 <NCollection_Vector.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+
+#include <SelectMgr_RectangularFrustum.hxx>
+
+#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_BaseFrustum> 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<SelectMgr_BaseFrustum> (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<Standard_Real, 3>& 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 (file)
index 0000000..4ec8fc9
--- /dev/null
@@ -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 <SelectMgr_Frustum.hxx>
+
+//! 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<SelectMgr_BaseFrustum> 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<Standard_Real, 3>& 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
index 1c889c0..6231ea3 100644 (file)
@@ -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 <amode>th selection mode.   
+    RecomputePrimitives (me      : mutable;
+                         theMode : Integer from Standard)
+      is static;
+    ---Purpose: Re-computes the sensitive primitives which correspond to the <theMode>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;
index 4a0d3a7..3985350 100644 (file)
@@ -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 (file)
index 0000000..9148657
--- /dev/null
@@ -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 <Bnd_Box.hxx>
+#include <BVH_BinnedBuilder.hxx>
+
+#include <SelectMgr_SelectableObjectSet.hxx>
+
+//=======================================================================
+// 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<Standard_Real, 3, 32> (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 (file)
index 0000000..59ac5a4
--- /dev/null
@@ -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 <BVH_PrimitiveSet.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+#include <Handle_SelectMgr_SelectionManager.hxx>
+#include <SelectMgr_SelectableObject.hxx>
+#include <SelectMgr_VectorTypes.hxx>
+
+//! 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<Standard_Real, 3>
+{
+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<Handle(SelectMgr_SelectableObject)> myObjects;
+  NCollection_Sequence<Standard_Integer>                   myObjectIdxs;
+};
+
+#endif // _SelectMgr_SelectableObjectSet_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
new file mode 100644 (file)
index 0000000..6e5b483
--- /dev/null
@@ -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 <SelectMgr_SelectingVolumeManager.hxx>
+
+//=======================================================================
+// 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<Standard_Real, 3>& 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<Standard_Real> SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
+{
+  if (myActiveSelectionType != Point)
+    return NCollection_Vec3<Standard_Real> (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 (file)
index 0000000..2d0eb27
--- /dev/null
@@ -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 <NCollection_Handle.hxx>
+
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
+
+#include <SelectMgr_BaseFrustum.hxx>
+#include <SelectMgr_RectangularFrustum.hxx>
+#include <SelectMgr_TriangularFrustumSet.hxx>
+#include <SelectBasics_SelectingVolumeManager.hxx>
+
+//! 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<Standard_Real, 3>& 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<Standard_Real> 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<SelectMgr_BaseFrustum> 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 (file)
index 59b9c1a..0000000
+++ /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;
-
-
index 187c387..2ca5502 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <SelectMgr_Selection.ixx>
+#include <Standard_NullObject.hxx>
 
+#include <SelectMgr_Selection.hxx>
+
+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 (file)
index 0000000..cf0b79c
--- /dev/null
@@ -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 <NCollection_Handle.hxx>
+#include <NCollection_Vector.hxx>
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <SelectMgr_TypeOfUpdate.hxx>
+#include <MMgt_TShared.hxx>
+#include <Handle_SelectBasics_SensitiveEntity.hxx>
+#include <SelectMgr_SensitiveEntity.hxx>
+#include <SelectMgr_StateOfSelection.hxx>
+#include <SelectMgr_TypeOfBVHUpdate.hxx>
+
+class Standard_NullObject;
+class SelectBasics_SensitiveEntity;
+
+typedef NCollection_Handle<SelectMgr_SensitiveEntity> 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<SelectMgr_HSensitiveEntity>           myEntities;
+  NCollection_Vector<SelectMgr_HSensitiveEntity>::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 <SelectMgr_Selection.lxx>
+
+#endif
index 112f295..60ed4db 100644 (file)
 // 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;
+}
index 4e6f322..157d671 100644 (file)
 
 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.
-    
+    Contains (me;
+              theObject : SelectableObject from SelectMgr)
+      returns Boolean
+      is static;
+    ---Purpose: Returns true if the manager contains the selectable object theObject.
 
-       ---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  <aMode> notequal -1 ;
-       --         if  <anObject> 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
-       --        <aSelector> Only.  the sensitive entities for  selection
-       --        of mode <aMode> are computed if <aMode> not equal -1.
-       --        if <aMode> =-1 oc compute is done
 
 
-    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.
 
-    
-       
-    ---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, ....
-    
+    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.
 
-    
-    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 <anObject>
-    
-    
-    Deactivate (me       : mutable ;
-               anObject : SelectableObject from SelectMgr;
-               aMode    : Integer) is static; 
-       ---Level: Public 
-       ---Purpose: Deactivates the Mode <aMode> in every Selector where
-       --          it was activated
 
+    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.
 
-    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.
 
+    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.
 
-    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.
 
 
-    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.
+    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.
 
-    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;
-                      anIObj      : SelectableObject from SelectMgr;
-                      ForceUpdate : Boolean from Standard  = Standard_False;
-                      aMode       : Integer from Standard = -1);
-       ---Purpose: computes Selections in <anIObj> if they are
-       --          activated in at least one Selector.
-       --          puts a recompute flag in each selection which is not active.
-       --          if <aMode>=-1 all the selection modes will have to be
-       --          recomputed.
-       --          if <ForceUpdate>  = True, all selections are recomputed,
-       --          even if they are not active.
-
-
-    Update(me             : mutable;
-          anObject       : SelectableObject from SelectMgr;
-          ForceUpdate    : Boolean from Standard = Standard_True) is static;
-       ---Level: Public 
-       ---Purpose: updates the selectionModes of <anObject>
-       --          According to 
-       --          . the stored type of update in each selection
-       --          mode,
-       --          . the activation status of each selection mode
-       --          if <ForceUpdate> == 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; 
+    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.
+
+
+
+
+
+    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.
+
+
+
+
+
+    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.
+
+
+    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.
+
+
+
+
+
+    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;
index 73506ee..5e8513b 100644 (file)
 #include <SelectMgr_DataMapIteratorOfDataMapOfObjectSelectors.hxx>
 #include <OSD_Environment.hxx>
 
-
-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;
 
-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;
+  for (Standard_Integer anIdx = 1; anIdx <= theSelectorsSeq.Length() && aFoundIdx==0; anIdx++)
+  {
+    if (theSelector == theSelectorsSeq.Value (anIdx))
+      aFoundIdx = anIdx;
+  }
 
-} 
+  return aFoundIdx;
+}
 
 //==================================================
 // 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;
 
-//==================================================
-// Function: Load
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Load (const Handle(SelectMgr_SelectableObject)& anObject,
-      const Standard_Integer amode)
-{
-  if(!myglobal.Contains(anObject))
-    myglobal.Add(anObject);
-  if(amode!=-1) 
-    LoadMode (anObject,amode);
+  return Standard_False;
 }
 
-
 //==================================================
 // Function: Load
 // Purpose :
 //==================================================
-void SelectMgr_SelectionManager::
-Load (const Handle(SelectMgr_SelectableObject)& anObject,
-      const Handle(SelectMgr_ViewerSelector)& aview,      
-      const Standard_Integer amode)
+void SelectMgr_SelectionManager::Load (const Handle(SelectMgr_SelectableObject)& theObject,
+                                       const Standard_Integer theMode)
 {
-  if(!myselectors.Contains(aview)) myselectors.Add(aview);
-  if(amode!=-1)
-    LoadMode (anObject,amode);
-
+  if (myGlobal.Contains(theObject))
+    return;
 
-  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;
+
+  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())
+    {
+      aSelector->AddSelectableObject (theObject);
     }
   }
+  if (theMode != -1)
+    loadMode (theObject, theMode);
 }
 
 
 //==================================================
-// Function: Remove
+// Function: Load
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Remove(const Handle(SelectMgr_SelectableObject)& anObject)
+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);
+  }
 
-  if(myglobal.Contains(anObject)) {
-    TColStd_MapIteratorOfMapOfTransient It(myselectors);
-    for(;It.More();It.Next())
-    {
-      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());
-        }
+  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);
     }
-    myglobal.Remove(anObject);
   }
-
-  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())
+  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)& anObject,
-       const Handle(SelectMgr_ViewerSelector)& aVS)
+void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
 {
-  if(aVS->Contains(anObject)) {
-    for(anObject->Init();anObject->More();anObject->Next()){
-      aVS->Remove(anObject->CurrentSelection());
-    }
+  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;
 
-    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;
-        }
+      for (theObject->Init(); theObject->More(); theObject->Next())
+      {
+        aCurSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection());
+        theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove);
       }
-      if(seq.IsEmpty())
-        mylocal.UnBind(anObject);
+      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: Activate
+// Function: Remove
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Activate(const Handle(SelectMgr_SelectableObject)& anObject,
-         const Standard_Integer aMode,
-         const Standard_Boolean AutomaticProj)
+void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject,
+                                         const Handle(SelectMgr_ViewerSelector)& theSelector)
 {
-  if(aMode==-1) return;
-  //  Standard_Boolean global = Standard_False;
-  if(!anObject->HasSelection(aMode)) LoadMode(anObject,aMode);
+  if (!theSelector->Contains (theObject))
+    return;
 
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    Remove (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theSelector);
+  }
 
-  if(myglobal.Contains(anObject)) {
-    TColStd_MapIteratorOfMapOfTransient It(myselectors);
+  if (!theObject->HasOwnPresentations())
+    return;
 
-    for(;It.More();It.Next()){
-      Handle(SelectMgr_ViewerSelector) curview = 
-        Handle(SelectMgr_ViewerSelector)::DownCast(It.Key());
-      Activate(anObject,aMode,curview,AutomaticProj);
-    }
+  for (theObject->Init(); theObject->More(); theObject->Next())
+  {
+    theSelector->RemoveSelectionOfObject (theObject, theObject->CurrentSelection());
+    theObject->CurrentSelection()->UpdateBVHStatus (SelectMgr_TBU_Remove);
   }
 
-  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);
+  theSelector->RemoveSelectableObject (theObject);
 
-      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:
+  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);
+  if (!theObject->HasOwnPresentations())
+  {
+    for (PrsMgr_ListOfPresentableObjectsIter anChildIter (theObject->Children()); anChildIter.More(); anChildIter.Next())
+    {
+      Activate (Handle(SelectMgr_SelectableObject)::DownCast (anChildIter.Value()), theMode, theSelector);
+    }
 
-  const Handle(SelectMgr_Selection)& Sel = anObject->Selection(aMode);
+    return;
+  }
 
-  switch(Sel->UpdateStatus()){
-  case SelectMgr_TOU_Full:
-    anObject->UpdateSelection(aMode); 
-  case SelectMgr_TOU_Partial:
+  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))
     {
-      if(anObject->HasTransformation())
-        anObject->UpdateTransformations(Sel);
-      break;
+      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));
+  switch (aSelection->BVHUpdateStatus())
+  {
+  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);
 
-  else {
-    if (mylocal.IsBound(anObject)) {
-      if (SMSearch(mylocal.Find(anObject),aViewSel)==0)
-        (mylocal.ChangeFind (anObject)).Append(aViewSel);
-      aViewSel->Activate (anObject->Selection(aMode),AutomaticProj);
+  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));
     }
   }
 }
@@ -327,317 +396,323 @@ Activate(const Handle(SelectMgr_SelectableObject)& anObject,
 // Function: Deactivate
 // Purpose :
 //==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject)
+void SelectMgr_SelectionManager::Deactivate (const Handle(SelectMgr_SelectableObject)& theObject,
+                                             const Standard_Integer theMode,
+                                             const Handle(SelectMgr_ViewerSelector)& theSelector)
 {
-  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());}  
 
+  if (!theObject->HasOwnPresentations())
+  {
+    for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+    {
+      Deactivate (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode, theSelector);
     }
 
+    return;
   }
-}
-
-//==================================================
-// 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));
+  Standard_Boolean isInGlobal = myGlobal.Contains (theObject);
+  Standard_Boolean hasSelection = theMode == -1 ? Standard_True : theObject->HasSelection (theMode);
 
+  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));
+        }
+      }
     }
   }
-}
-
-//==================================================
-// 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))
+  else
   {
-    if(myglobal.Contains(anObject)|| mylocal.IsBound(anObject)) 
-      if(anObject->HasSelection(aMode))
-        aViewSel->Deactivate (anObject->Selection(aMode));
-  }  
-
+    if (theMode == -1)
+    {
+      for (theObject->Init(); theObject->More(); theObject->Next())
+      {
+        theSelector->Deactivate (theObject->CurrentSelection());
+      }
+    }
+    else
+      if (hasSelection)
+        theSelector->Deactivate (theObject->Selection (theMode));
+  }
 }
-//==================================================
-// Function: Deactivate
-// Purpose :
-//==================================================
-
-void SelectMgr_SelectionManager::
-Deactivate(const Handle(SelectMgr_SelectableObject)& anObject,
-           const Handle(SelectMgr_ViewerSelector)& aViewSel)
 
+//=======================================================================
+//function : IsActivated
+//purpose  :
+//=======================================================================
+Standard_Boolean SelectMgr_SelectionManager::IsActivated (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                          const Standard_Integer theMode,
+                                                          const Handle(SelectMgr_ViewerSelector)& theSelector) const
 {
-  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())
+    {
+      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;
+    }
 
-//==================================================
-// Function: Sleep
-// Purpose :
-//==================================================
-void SelectMgr_SelectionManager::
-Sleep (const Handle(SelectMgr_ViewerSelector)& aViewSel)
-{
-  if (myselectors.Contains(aViewSel))
-    aViewSel->Sleep();
-}
+    return Standard_False;
+  }
 
-void SelectMgr_SelectionManager::
-Sleep (const Handle(SelectMgr_SelectableObject)& anObject)
-{
+  if (!theObject->HasSelection (theMode))
+    return Standard_False;
 
-  if(myglobal.Contains(anObject)){
-    for( TColStd_MapIteratorOfMapOfTransient It(myselectors);
-      It.More();It.Next())
-      Handle(SelectMgr_ViewerSelector)::DownCast(It.Key())->Sleep(anObject);
+  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 if(mylocal.IsBound(anObject)){
-    const SelectMgr_SequenceOfSelector & VSeq = mylocal(anObject);
-    for (Standard_Integer I=1;I<=VSeq.Length();I++)
-      VSeq(I)->Sleep(anObject);
+  else
+  {
+    return theSelector->Status (aSelection) == SelectMgr_SOS_Activated;
   }
 
-
+  return Standard_False;
 }
 
 //=======================================================================
-//function : Sleep
-//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
 //=======================================================================
-void SelectMgr_SelectionManager::
-Sleep(const Handle(SelectMgr_SelectableObject)& anObject,
-      const Handle(SelectMgr_ViewerSelector)& aViewSel)
+void SelectMgr_SelectionManager::ClearSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
+                                                           const Standard_Integer theMode,
+                                                           const Handle(SelectMgr_ViewerSelector)& theSelector)
 {
-  if(!myselectors.Contains(aViewSel)) return;
-
-  if(!myglobal.Contains(anObject)){
-    if(!mylocal.IsBound(anObject))
-      return;
-    if(SMSearch(mylocal(anObject),aViewSel)==0)
-      return;
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    ClearSelectionStructures (theObj, theMode, theSelector);
   }
-  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);
-}
+  if (!theObj->HasOwnPresentations())
+    return;
 
+  if (theSelector == NULL)
+  {
+    if (!(myGlobal.Contains (theObj) || myLocal.IsBound(theObj)))
+      return;
 
-//=======================================================================
-//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);
+    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(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 (!(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 : Awake
-//purpose  : 
+//function : RestoreSelectionStructuress
+//purpose  : Re-adds newely calculated sensitive  entities of recomputed selection
+//           defined by mode theMode to all viewer selectors contained that selection.
 //=======================================================================
-void SelectMgr_SelectionManager::Awake (const Handle(SelectMgr_SelectableObject)& anObject,
-                                        const Handle(SelectMgr_ViewerSelector)& aViewSel,
-                                        const Standard_Boolean AutomaticProj)
+void SelectMgr_SelectionManager::RestoreSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
+                                                             const Standard_Integer theMode,
+                                                             const Handle(SelectMgr_ViewerSelector)& theSelector)
 {
-  if(!myselectors.Contains(aViewSel)) return;
-
-  if(!myglobal.Contains(anObject)){
-    if(!mylocal.IsBound(anObject))
-      return;
-    if(SMSearch(mylocal(anObject),aViewSel)==0)
-      return;
+  for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    RestoreSelectionStructures (theObj, theMode, theSelector);
   }
-  aViewSel->Awake(anObject,AutomaticProj);
 
-}
+  if (!theObj->HasOwnPresentations())
+    return;
 
+  if (theSelector == NULL)
+  {
+    if (!(myGlobal.Contains (theObj) || myLocal.IsBound(theObj)))
+      return;
 
-//=======================================================================
-//function : IsActivated
-//purpose  : 
-//=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject) const
-{
-  for(anObject->Init();anObject->More();anObject->Next()){
-    if(IsActivated(anObject,anObject->CurrentSelection()->Mode()))
-      return Standard_True;
+    TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors);
+    Handle(SelectMgr_ViewerSelector) aSelector;
+    for( ; aSelectorsIter.More(); aSelectorsIter.Next())
+    {
+      aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key());
+      RestoreSelectionStructures (theObj, theMode, aSelector);
+    }
   }
-  return Standard_False;
-}
-//=======================================================================
-//function : IsActivated
-//purpose  : 
-//=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject,
-                                                         const Standard_Integer aMode) const
-{
-  if(!anObject->HasSelection(aMode)) return Standard_False;
-  if (!(myglobal.Contains(anObject) || mylocal.IsBound(anObject))) 
-    return Standard_False;
+  else
+  {
+    if (!(myGlobal.Contains (theObj) || myLocal.IsBound (theObj)))
+      return;
 
-  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;
+    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();
   }
-  return Standard_False;
-
 }
 
 //=======================================================================
-//function : IsActivated
-//purpose  : 
+//function : rebuildSelectionStructures
+//purpose  : Internal function that marks 1st level BVH of object theObj
+//           as outdated
 //=======================================================================
-Standard_Boolean SelectMgr_SelectionManager::IsActivated(const Handle(SelectMgr_SelectableObject)& anObject,
-                                                         const Handle(SelectMgr_ViewerSelector)& VS,
-                                                         const Standard_Integer aMode) const
+void SelectMgr_SelectionManager::rebuildSelectionStructures (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);
+  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"<<endl;
-
-  if(ForceUpdate){
-    if( SelectDebugModeOnSM() ) cout<<"\t Global Recalculation of selections"<<endl;
-    if(aMode==-1){
-      anObject->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"<<endl;
-    cout<<"\t eventual selections are flagged"<<endl;}
-    if( aMode == -1 ){
-      for(anObject->Init();anObject->More();anObject->Next()){
-        if( SelectDebugModeOnSM() ) cout<<"\t\t Mode "<<anObject->CurrentSelection()->Mode()<<"  ";
-        anObject->CurrentSelection()->UpdateStatus(SelectMgr_TOU_Full);
-      }
-      if( SelectDebugModeOnSM() )  
-        cout << endl;
-    }
-    else if (anObject->HasSelection(aMode))
-      anObject->Selection(aMode)->UpdateStatus(SelectMgr_TOU_Full);
-  }
-
-  // recalculate whatever is required
-  // and set flag on top...
-  else{
-    TColStd_MapIteratorOfMapOfTransient It;
-    Handle(Standard_Transient) Tr;
-    Standard_Boolean Found;
-    // object selections are parsed
-
-    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;
-
-      // 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 (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
+  {
+    RecomputeSelection (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theIsForce, theMode);
+  }
+
+  if (!theObject->HasOwnPresentations())
+    return;
+
+  if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject)))
+    return;
+
+  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)"<<endl;
-  if(!myselectors.Contains(aViewSel)) return;
-
-  Standard_Boolean okay = myglobal.Contains(anObject);
-  if(!okay)
-    okay = (mylocal.IsBound(anObject) && (SMSearch(mylocal.Find(anObject),aViewSel)!=0)) ;
-  if(!okay) return;
-
-
-  // 
-  Standard_Boolean wasrecomputed;
-  for(anObject->Init();anObject->More();anObject->Next()){
-    const Handle(SelectMgr_Selection)& Sel = anObject->CurrentSelection();
-    wasrecomputed = Standard_False;
-    if(ForceUpdate){
-      switch(Sel->UpdateStatus()){
+void SelectMgr_SelectionManager::Update (const Handle(SelectMgr_SelectableObject)& theObject,
+                                         const Handle(SelectMgr_ViewerSelector)& theSelector,
+                                         const Standard_Boolean theIsForce)
+{
+  if (!mySelectors.Contains (theSelector))
+    return;
+
+  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);
+  }
+
+  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:
-        anObject->UpdateSelection(Sel->Mode()); //  no break on purpose...
+        ClearSelectionStructures (theObject, aSelection->Mode());
+        theObject->RecomputePrimitives (aSelection->Mode());
+        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);
     }
 
-    if(aViewSel->Status(Sel) == SelectMgr_SOS_Activated){
-      switch(Sel->UpdateStatus()){
+    if (theSelector->Status (aSelection) == SelectMgr_SOS_Activated)
+    {
+      switch (aSelection->UpdateStatus())
+      {
       case SelectMgr_TOU_Full:
-        anObject->UpdateSelection(Sel->Mode());
+        ClearSelectionStructures (theObject, aSelection->Mode(), theSelector);
+        theObject->RecomputePrimitives (aSelection->Mode());
+        RestoreSelectionStructures (theObject, aSelection->Mode(), theSelector);
       case SelectMgr_TOU_Partial:
-        if(anObject->HasTransformation())
-          anObject->UpdateTransformations(Sel);
-        wasrecomputed = Standard_True;
+        if (theObject->HasTransformation())
+        {
+          theObject->UpdateTransformations (aSelection);
+          theSelector->RebuildObjectsTree();
+        }
         break;
       default:
         break;
       }
-      if(wasrecomputed)
-        aViewSel->Convert(Sel);
-      Sel->UpdateStatus(SelectMgr_TOU_None);
+
+      aSelection->UpdateStatus(SelectMgr_TOU_None);
+      aSelection->UpdateBVHStatus (SelectMgr_TBU_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 :
+// Function: loadMode
+// Purpose : Private Method
 //==================================================
-
-
-TCollection_AsciiString SelectMgr_SelectionManager::
-Status(const Handle(SelectMgr_SelectableObject)& anObject) const
+void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObject)& theObject,
+                                           const Standard_Integer theMode,
+                                           const Handle(SelectMgr_ViewerSelector)& theSelector)
 {
-  TCollection_AsciiString TheStatus("\t\tStatus of object:");
+  if (theMode == -1)
+    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";
+  if (!theObject->HasSelection (theMode))
+  {
+    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);
+    }
   }
-
-  return TheStatus;
-
-}
-
-//==================================================
-// Function: LoadMode
-// Purpose : Private Method
-//==================================================
-
-
-void SelectMgr_SelectionManager
-::LoadMode (const Handle(SelectMgr_SelectableObject)& anObject,
-            const Standard_Integer amode)
-{
-  if(amode==-1) return;
-  if(!anObject->HasSelection(amode))
+  else if (theObject->Selection (theMode)->IsEmpty())
   {
-    Handle(SelectMgr_Selection) NewSel = new SelectMgr_Selection(amode); 
-    anObject->AddSelection (NewSel,amode);
+    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 (file)
index 0000000..5d515ed
--- /dev/null
@@ -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 <SelectMgr_SensitiveEntity.hxx>
+
+//=======================================================================
+// 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 (file)
index 0000000..71787a0
--- /dev/null
@@ -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 <SelectBasics_SensitiveEntity.hxx>
+#include <Handle_SelectBasics_SensitiveEntity.hxx>
+
+//! 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 (file)
index 0000000..e2a591a
--- /dev/null
@@ -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 <SelectMgr_SensitiveEntitySet.hxx>
+
+#include <BVH_BinnedBuilder.hxx>
+
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectMgr_SensitiveEntity.hxx>
+
+//=======================================================================
+// function : SelectMgr_SensitiveEntitySet
+// purpose  :
+//=======================================================================
+SelectMgr_SensitiveEntitySet::SelectMgr_SensitiveEntitySet()
+{
+  myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 32> (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<Standard_Real, 3>::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 (file)
index 0000000..c143bb9
--- /dev/null
@@ -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 <BVH_PrimitiveSet.hxx>
+
+#include <NCollection_Sequence.hxx>
+#include <NCollection_Handle.hxx>
+
+#include <Select3D_BndBox3d.hxx>
+
+#include <SelectMgr_SensitiveEntity.hxx>
+#include <SelectMgr_Selection.hxx>
+
+//! 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<Standard_Real, 3>
+{
+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<SelectMgr_HSensitiveEntity> myEntities;       //!< A sequence of calculated sensitives of the object
+  NCollection_Sequence<Standard_Integer>           myEntityIdxs;     //!< Cached indexes for faster BVH build
+};
+
+#endif // _SelectMgr_SensitiveEntitySet_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_SequenceOfSelection.hxx b/src/SelectMgr/SelectMgr_SequenceOfSelection.hxx
new file mode 100644 (file)
index 0000000..a1c9781
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+//
+// 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_SequenceOfSelection_HeaderFile
+#define _SelectMgr_SequenceOfSelection_HeaderFile
+
+#include <NCollection_Sequence.hxx>
+#include <SelectMgr_Selection.hxx>
+
+typedef NCollection_Sequence<Handle(SelectMgr_Selection)> SelectMgr_SequenceOfSelection;
+
+#endif // _SelectMgr_SequenceOfSelection_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_TriangularFrustum.cxx b/src/SelectMgr/SelectMgr_TriangularFrustum.cxx
new file mode 100644 (file)
index 0000000..715d1a8
--- /dev/null
@@ -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 <SelectMgr_TriangularFrustum.hxx>
+
+#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_BaseFrustum> 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<SelectMgr_BaseFrustum> (aRes);
+}
+
+//=======================================================================
+// function : Overlaps
+// purpose  : SAT intersection test between defined volume and
+//            given axis-aligned box
+//=======================================================================
+const Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& 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 (file)
index 0000000..fc8e5cd
--- /dev/null
@@ -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 <SelectMgr_Frustum.hxx>
+
+//! 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<SelectMgr_BaseFrustum> 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<Standard_Real, 3>& 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 (file)
index 0000000..fd9c2f6
--- /dev/null
@@ -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 <BRepMesh_DataStructureOfDelaun.hxx>
+#include <BRepMesh_Delaun.hxx>
+#include <NCollection_IncAllocator.hxx>
+
+#include <SelectMgr_TriangularFrustumSet.hxx>
+
+#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_BaseFrustum> 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<SelectMgr_TriangularFrustum>::DownCast (anIter.Value()->Transform (theTrsf)));
+  }
+
+  return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
+}
+
+// =======================================================================
+// function : Overlaps
+// purpose  :
+// =======================================================================
+const Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const BVH_Box<Standard_Real, 3>& 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 (file)
index 0000000..2513314
--- /dev/null
@@ -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 <NCollection_Handle.hxx>
+#include <NCollection_List.hxx>
+
+#include <SelectMgr_BaseFrustum.hxx>
+#include <SelectMgr_TriangularFrustum.hxx>
+
+typedef NCollection_Handle<SelectMgr_TriangularFrustum> SelectMgr_HTriangularFrustum;
+typedef NCollection_List<SelectMgr_HTriangularFrustum> SelectMgr_TriangFrustums;
+typedef NCollection_List<SelectMgr_HTriangularFrustum>::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<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
+
+  virtual const Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& 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 (file)
index 0000000..c8b92b2
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _SelectMgr_VectorTypes_HeaderFile
+#define _SelectMgr_VectorTypes_HeaderFile
+
+#include <gp_Trsf.hxx>
+#include <NCollection_Array1.hxx>
+#include <NCollection_Mat4.hxx>
+#include <NCollection_Vec3.hxx>
+#include <NCollection_Vec4.hxx>
+
+typedef NCollection_Vec3<Standard_Real>    SelectMgr_Vec3;
+typedef NCollection_Vec4<Standard_Real>    SelectMgr_Vec4;
+typedef NCollection_Mat4<Standard_Real>    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 (file)
index 01143d4..0000000
+++ /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 <aRank> 
-       --          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;
-
-
-
-
-
-
-
-
-
-
-
-
index 31210be..9190f3b 100644 (file)
 //              ROB JAN/07/98 : Improve Storage of detected entities
 //              AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
 
-#include <SelectMgr_ViewerSelector.ixx>
-#include <SelectMgr_CompareResults.hxx>
-#include <gp_Pnt2d.hxx>
+#include <BVH_Tree.hxx>
 #include <gp_Pnt.hxx>
-#include <gp_Lin.hxx>
-#include <Bnd_HArray1OfBox2d.hxx>
-#include <Bnd_Array1OfBox2d.hxx>
+#include <OSD_Environment.hxx>
 #include <Precision.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <NCollection_DataMap.hxx>
+#include <SelectMgr_ViewerSelector.hxx>
+#include <SelectMgr_CompareResults.hxx>
 #include <SelectBasics_EntityOwner.hxx>
-#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
-#include <SelectBasics_PickArgs.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
+#include <SelectBasics_PickResult.hxx>
+#include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_SortCriterion.hxx>
+#include <SelectMgr_SensitiveEntitySet.hxx>
 #include <SortTools_QuickSortOfInteger.hxx>
-#include <OSD_Environment.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+
+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()
+{
+  myLargestKey = -1;
+}
+
+SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
 {
-  // container to store depth limits in collection map
-  struct SelectMgr_DepthRange
+  myTolerances.Clear();
+}
+
+void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
+{
+  if (myTolerances.IsBound (theTolerance))
+  {
+    Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
+    aFreq++;
+
+    if (theTolerance == myLargestKey)
+      return;
+
+    Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
+    if (aFreq >= aMaxFreq)
+    {
+      myLargestKey = aFreq == aMaxFreq ? Max (myLargestKey, theTolerance) : theTolerance;
+    }
+  }
+  else
   {
-    Standard_Real DepthMin;
-    Standard_Real DepthMax;
-    Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); }
+    if (myTolerances.IsEmpty())
+    {
+      myTolerances.Bind (theTolerance, 1);
+      myLargestKey = theTolerance;
+      return;
+    }
 
-    void Common (const SelectMgr_DepthRange& theOther)
+    myTolerances.Bind (theTolerance, 1);
+    Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
+    if (aMaxFreq <= 1)
     {
-      if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin)
+      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<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
       {
-        DepthMin = RealFirst();
-        DepthMax = RealLast();
-        return;
+        if (aMaxFreq <= anIter.Value() && myLargestKey != anIter.Key())
+        {
+          aMaxFreq = anIter.Value();
+          myLargestKey = anIter.Key();
+        }
       }
-
-      DepthMin = Max (DepthMin, theOther.DepthMin);
-      DepthMax = Min (DepthMax, theOther.DepthMax);
     }
-  };
-};
+  }
+}
+
+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,433 +142,262 @@ 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;
-
-  if (!myselections.IsBound(aSelection))
+  for (theSelection->Init(); theSelection->More(); theSelection->Next())
   {
-    myselections.Bind(aSelection,0);
+    theSelection->Sensitive()->SetActiveForSelection();
   }
-  else if (myselections(aSelection)!=0)
-  {
-    myselections(aSelection)= 0;
-  }
-  if(AutomaticProj)
-    Convert(aSelection);
-}
 
+  theSelection->SetSelectionState (SelectMgr_SOS_Activated);
 
-//==================================================
-// Function: Deactivate
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::
-Deactivate (const Handle(SelectMgr_Selection)& aSel)
-{
-  if(myselections.IsBound(aSel))
-  {myselections(aSel)=1;
-  tosort = Standard_True;}
+  myTolerances.Add (theSelection->Sensitivity());
+  mytolerance = myTolerances.Largest();
+  myToUpdateTolerance = Standard_True;
 }
 
 
-
-
-
 //==================================================
-// Function: Sleep
+// Function: Deactivate
 // 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)
+void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
 {
-
-  for(SO->Init();SO->More();SO->Next()){
-    if(myselections.IsBound(SO->CurrentSelection())){
-      myselections(SO->CurrentSelection()) = 2;
-    }
+  for (theSelection->Init(); theSelection->More(); theSelection->Next())
+  {
+    theSelection->Sensitive()->ResetSelectionActiveStatus();
   }
-  UpdateSort();
-}
 
+  theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
 
-//==================================================
-// 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();
-  }
+  myTolerances.Decrement (theSelection->Sensitivity());
+  mytolerance = myTolerances.Largest();
+  myToUpdateTolerance = Standard_True;
 }
 
-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());
-    }
-  }
-
-}
 //==================================================
 // 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"<<endl;
-
-  SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
-  for(;It.More();It.Next()){
-    //Convert only if active...
-    if(It.Value()==0)
-      Convert(It.Key());
-  }
-  toupdate = Standard_False;
-  tosort = Standard_True;
-}
-
-
-//==================================================
-// Function: Convert
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::
-Convert (const Handle(SelectMgr_Selection)& /*aSel*/) {tosort=Standard_True;}
+  const Handle(SelectMgr_EntityOwner)& anOwner =
+    Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId());
 
+  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;
+      }
 
-//==================================================
-// Function: UpdateSort
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::UpdateSort()
-{
-  if( !myUpdateSortPossible )
-    return;
+      Standard_Integer aPriority = anOwner->Priority();
 
-  if( SelectDebugModeOnVS() )
-    cout<<"\t\t\t\t\t SelectMgr_ViewerSelector::UpdateSort()"<<endl;
-  mystored.Clear();
-  myentities.Clear();
-  myactivenb = NbBoxes();
-
-  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_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())
+      SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
+      if (mystored.Contains (anOwner))
       {
-        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(curxmin<xmin) xmin=curxmin;
-              if(curxmax>xmax) xmax=curxmax;
-              if(curymin<ymin) ymin=curymin;
-              if(curymax>ymax) ymax=curymax;
-            }
+        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);
       }
     }
-
-
-    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)
+//=======================================================================
+// 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 (myselections.IsBound(aSel))
-  { myselections.UnBind(aSel);
-  tosort = Standard_True;
-  }
-}
+  NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
+    myMapOfObjectSensitives.ChangeFind (theObject);
 
-//==================================================
-// 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;
-}
+  if (anEntitySet->Size() == 0)
+    return;
 
+  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
 
-//==================================================
-// Function: SetClipping
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::SetClipping (const Bnd_Box2d& abox)
-{myclip = abox;
-tosort = Standard_True;
-}
+  SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
+    mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
 
-//==================================================
-// 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);
+  Standard_Integer aNode = 0; // a root node
+  if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
+                      aSensitivesTree->MaxPoint (0)))
+  {
+    return;
   }
-}
+  Standard_Integer aStack[32];
+  Standard_Integer aHead = -1;
+  for (;;)
+  {
+    if (!aSensitivesTree->IsOuter (aNode))
+    {
+      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)
+      {
+        aNode = aLeftChildIdx;
+        ++aHead;
+        aStack[aHead] = aRightChildIdx;
+      }
+      else if (isLeftChildIn
+        || isRightChildIn)
+      {
+        aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+      }
+      else
+      {
+        if (aHead < 0)
+        {
+          break;
+        }
 
-//==================================================
-// 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();
+        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;
+      }
 
-  if (toupdate) UpdateConversion();
-  if (tosort)   UpdateSort();
-  if (myactivenb!=0){
-    Bnd_Box2d aBox;
-    aBox.Update(Xmin,Ymin,Xmax,Ymax);
-    myselector.InitSelect(aBox);
-    LoadResult(aBox);
+      aNode = aStack[aHead];
+      --aHead;
+    }
   }
 }
 
-//==================================================
-// Function: InitSelect
-// Purpose : Polyline Selection
-//==================================================
-void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly)
+//=======================================================================
+// 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 (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);
-  }
-}
+  if (mySelectableObjects->Size() == 0)
+    return;
 
+  const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
 
-//==================================================
-// 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;
+  if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
+                                      anObjectsTree->MaxPoint (0)))
   {
-    NCollection_DataMap<Handle(SelectMgr_EntityOwner), SelectMgr_DepthRange> 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 (!anObjectsTree->IsOuter (aNode))
     {
-      for (; myselector.More(); myselector.Next())
+      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)
       {
-        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))
-        {
-          // 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);
-        }
-
-        if (anEntityDRange.IsEmpty())
+        aNode = aLeftChildIdx;
+        ++aHead;
+        aStack[aHead] = aRightChildIdx;
+      }
+      else if (isLeftChildIn
+        || isRightChildIn)
+      {
+        aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+      }
+      else
+      {
+        if (aHead < 0)
         {
-          continue;
+          break;
         }
 
-        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 = 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;
+      }
 
-    SortResult();
+      aNode = aStack[aHead];
+      --aHead;
+    }
   }
 
+  SortResult();
+
   if (SelectDebugModeOnVS())
   {
     cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
@@ -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,137 +478,95 @@ 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;
-}
-//=======================================================================
-//function : Primitive
-//purpose  :
-//=======================================================================
-Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive
-(const Standard_Integer /*Index*/) const
-{
-  return myentities(myprim(myCurRank));
+  const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
+  anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
+  return anOwner;
 }
 
-
-//==================================================
-// Function: LastPosition
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast,
-                                            Standard_Real& YLast) const
-{   Xlast = lastx;YLast = lasty;}
-
-
-
 //===================================================
 //
 //       INTERNAL METHODS ....
 //
 //==================================================
 
-
-
-
-//==================================================
-// 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<<"=========================="<<endl;
-  S<<" SelectMgr_ViewerSelector "<<endl;
-  S<<"=========================="<<endl;
-  S<<" "<<endl;
-}
-
-
-
 //==================================================
 // Function: Status
 // Purpose : gives Information about selectors
 //==================================================
 
-TCollection_AsciiString SelectMgr_ViewerSelector::
-Status(const Handle(SelectMgr_SelectableObject)& SO) const
+TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
 {
-  TCollection_AsciiString Status("Status Object :\n\t");
-  Standard_Boolean Found= Standard_False;
-  for(SO->Init();SO->More();SO->Next()){
-    if(myselections.IsBound(SO->CurrentSelection()))
+  TCollection_AsciiString aStatus ("Status Object :\n\t");
+
+  for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
+  {
+    if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
     {
-      Found = Standard_True;
-      Status = Status + "Mode " +
-        TCollection_AsciiString(SO->CurrentSelection()->Mode()) +
-        " present - " ;
-      if(myselections(SO->CurrentSelection()))
-        Status = Status + " Active \n\t";
+      aStatus = aStatus + "Mode " +
+        TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
+        " present - ";
+      if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
+      {
+        aStatus = aStatus + " Active \n\t";
+      }
       else
-        Status = Status + " Inactive \n\t";
+      {
+        aStatus = aStatus + " Inactive \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())
+  if (mySelectableObjects->Contains (theSelectableObject))
   {
-    if(It.Value()==0) {NbActive++;
-    for(It.Key()->Init();It.Key()->More();It.Key()->Next()){NbPrim++;}
-    }
+    aStatus = aStatus + "Not Present in the selector\n\n";
   }
-  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";
-  }
-  return Status;
+
+  return aStatus;
 }
 
 //=======================================================================
@@ -968,111 +642,171 @@ 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<thearr.Length();I++){
-  //      indx = thearr(I);
-  //      indx1 = thearr(I+1);
-  //      if(mystored(indx) < mystored(indx1)){
-  //      OKSort = Standard_False;
-  //
-  //      temp = thearr(I+1);
-  //      thearr(I+1) = thearr (I);
-  //      thearr(I) = temp;
-  //
-  //      tmprim = myprim(I+1);
-  //      myprim(I+1) = myprim(I);
-  //      myprim(I) = tmprim;
-  //
-  //      }
-  //    }
-  //  } while (OKSort==Standard_False);
-  //
-  // OCC4201 (AGV): debut
-
   SortTools_QuickSortOfInteger::Sort (thearr,
     SelectMgr_CompareResults(mystored));
-  TColStd_Array1OfInteger myPrimArr (1, myprim.Length());
-  for (I = 1; I <= myPrimArr.Length(); I++)
-    myPrimArr (I) = myprim (I);
-  for (I = 1; I <= thearr.Length(); I++) {
-    const Standard_Integer ind = thearr(I);
-    if (ind > 0 && ind <= myPrimArr.Upper())
-      myprim (I) = myPrimArr (ind);
+}
+
+//=======================================================================
+//function : HasDepthClipping
+//purpose  : Stub
+//=======================================================================
+Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
+{
+  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<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
+    myMapOfObjectSensitives.Bind (theObject, anEntitySet);
   }
-  // OCC4201 (AGV): fin
-  // it is enough to return owners corresponding to parced indices...
+}
 
+//=======================================================================
+// 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<SelectMgr_SensitiveEntitySet>& 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 :
-//purpose  :
+// function : RemoveSelectionOfObject
+// purpose  : Removes selection of the object and marks its BVH tree
+//            for rebuild
 //=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const
+void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                        const Handle(SelectMgr_Selection)& theSelection)
 {
-  return myUpdateSortPossible;
+  if (myMapOfObjectSensitives.IsBound (theObject))
+  {
+    NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
+      myMapOfObjectSensitives.ChangeFind (theObject);
+    anEntitySet->Remove (theSelection);
+  }
 }
 
 //=======================================================================
-//function :
-//purpose  :
+// function : RebuildObjectsTree
+// purpose  : Marks BVH of selectable objects for rebuild
 //=======================================================================
-void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible )
+void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
 {
-  myUpdateSortPossible = possible;
+  mySelectableObjects->MarkDirty();
+
+  if (theIsForce)
+  {
+    mySelectableObjects->BVH();
+  }
 }
 
 //=======================================================================
-//function : PickingLine
-//purpose  : Stub
+// function : RebuildSensitivesTree
+// purpose  : Marks BVH of sensitive entities of particular selectable
+//            object for rebuild
 //=======================================================================
-gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/,
-                                              const Standard_Real /*theY*/) const
+void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
+                                                      const Standard_Boolean theIsForce)
 {
-  return gp_Lin();
+  if (!mySelectableObjects->Contains (theObject))
+    return;
+
+  NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
+  anEntitySet->MarkDirty();
+
+  if (theIsForce)
+  {
+    anEntitySet->BVH();
+  }
 }
 
 //=======================================================================
-//function : DepthClipping
-//purpose  : Stub
+// function : resetSelectionActivationStatus
+// purpose  : Marks all added sensitive entities of all objects as
+//            non-selectable
 //=======================================================================
-void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
-                                              const Standard_Real /*theY*/,
-                                              Standard_Real& theMin,
-                                              Standard_Real& theMax) const
+void SelectMgr_ViewerSelector::resetSelectionActivationStatus()
 {
-  theMin = RealFirst();
-  theMax = RealLast();
+  SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
+  for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
+  {
+    NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
+      aSensitivesIter.ChangeValue();
+    Standard_Integer anEntitiesNb = anEntitySet->Size();
+    for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
+    {
+      anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
+    }
+  }
 }
 
 //=======================================================================
-//function : DepthClipping
-//purpose  : Stub
+// function : DetectedEntity
+// purpose  : Returns sensitive entity that was detected during the
+//            previous run of selection algorithm
 //=======================================================================
-void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
-                                              const Standard_Real /*theY*/,
-                                              const Handle(SelectMgr_EntityOwner)& /*theOwner*/,
-                                              Standard_Real& theMin,
-                                              Standard_Real& theMax) const
+const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
 {
-  theMin = RealFirst();
-  theMax = RealLast();
+  const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
+  const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
+  const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
+    myMapOfObjectSensitives.Find (anObject);
+
+  return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
 }
 
 //=======================================================================
-//function : HasDepthClipping
-//purpose  : Stub
+// function : ActiveOwners
+// purpose  : Returns the list of active entity owners
 //=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
+NCollection_List<Handle(SelectBasics_EntityOwner)> SelectMgr_ViewerSelector::ActiveOwners() const
 {
-  return Standard_False;
+  NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
+  for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
+  {
+    const NCollection_Handle<SelectMgr_SensitiveEntitySet>& 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 (file)
index 0000000..ed28c9f
--- /dev/null
@@ -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 <MMgt_TShared.hxx>
+#include <NCollection_Handle.hxx>
+#include <NCollection_DataMap.hxx>
+#include <OSD_Chronometer.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+#include <Handle_TColStd_HArray1OfInteger.hxx>
+
+#include <Standard.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <SelectMgr_IndexedDataMapOfOwnerCriterion.hxx>
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <SelectMgr_SelectableObject.hxx>
+#include <SelectMgr_SelectableObjectSet.hxx>
+#include <Handle_SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_StateOfSelection.hxx>
+#include <Standard_OStream.hxx>
+#include <Handle_SelectBasics_SensitiveEntity.hxx>
+
+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<Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SensitiveEntitySet> > SelectMgr_MapOfObjectSensitives;
+typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SensitiveEntitySet> >::Iterator SelectMgr_MapOfObjectSensitivesIterator;
+
+typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities;
+typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer>::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<Standard_Real, Standard_Integer> 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 <aRank>
+  //!          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<Handle(SelectBasics_EntityOwner)> 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<SelectMgr_SelectableObjectSet> 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 <SelectMgr_ViewerSelector.lxx>
+
+#endif
index 6263e24..3f9c991 100644 (file)
@@ -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 (file)
index 0000000..9db0ac3
--- /dev/null
@@ -0,0 +1,3 @@
+StdSelect_ViewerSelector3d.hxx
+StdSelect_ViewerSelector3d.cxx
+StdSelect_ViewerSelector3d.lxx
index f9b5313..c59dda2 100644 (file)
@@ -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;
index 3b3f6ae..3930c6c 100644 (file)
 #include <gp_Ax3.hxx>
 #include <StdSelect_BRepOwner.hxx>
 
-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);
 //   }
index 1b8094f..b4a381b 100644 (file)
@@ -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;
index 5126512..96e1d63 100644 (file)
@@ -31,6 +31,7 @@
 #include <Bnd_Box.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Circle.hxx>
+#include <Select3D_SensitiveEntity.hxx>
 #include <Select3D_SensitiveCircle.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveSegment.hxx>
@@ -40,9 +41,7 @@
 #include <Select3D_SensitiveTriangulation.hxx>
 #include <Select3D_SensitiveTriangle.hxx>
 #include <Select3D_SensitiveGroup.hxx>
-
-#include <Select3D_ListIteratorOfListOfSensitive.hxx>
-#include <Select3D_ListOfSensitiveTriangle.hxx>
+#include <SelectMgr_Selection.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TColgp_SequenceOfPnt.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <Standard_NullObject.hxx>
 #include <Standard_ErrorHandler.hxx>
 
+#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 (file)
index 7c45d5a..0000000
+++ /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 <theProj>.
-
-    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 <theProj> 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 <theTolerance>.
-
-    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 <theXPix> and <theYPix>. 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 <theXPMin>, <theYPMin>, <theXPMax>
-    -- and <theYPMax> 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 <theView>.
-
-    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 <theView>.
-
-    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;
index e7128bc..b90c897 100644 (file)
@@ -14,7 +14,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <StdSelect_ViewerSelector3d.ixx>
+#include <StdSelect_ViewerSelector3d.hxx>
 #include <StdSelect.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
 #include <gp_Pln.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_Group.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_Structure.hxx>
 #include <SelectMgr_SelectableObject.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
 #include <TColgp_HArray1OfPnt2d.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveTriangulation.hxx>
 #include <Select3D_SensitiveTriangle.hxx>
 #include <Select3D_SensitiveWire.hxx>
-#include <Select3D_SensitiveEntitySequence.hxx>
-#include <Select3D_ListOfSensitiveTriangle.hxx>
 #include <Select3D_SensitiveBox.hxx>
-#include <Select3D_ListIteratorOfListOfSensitiveTriangle.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <SelectMgr_EntityOwner.hxx>
 
-#include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
 #include <Aspect_Grid.hxx>
 #include <Aspect_TypeOfMarker.hxx>
+#include <Aspect_Window.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <Graphic3d_ArrayOfPoints.hxx>
-#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
 #include <Poly_Connect.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 
 #include <V3d_Viewer.hxx>
 #include <TColgp_SequenceOfPnt.hxx>
 
+#include <OSD_Timer.hxx>
+
+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;
+  }
+
+  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<Standard_Real> (theXPix),
+                      static_cast<Standard_Real> (theYPix));
+  mySelectingVolumeMgr.BuildSelectingVolume (aMousePos);
 
-  InitSelect (aPnt2d.X(), aPnt2d.Y());
+  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;
-  }
-
-  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()));
+  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<Standard_Real> (theXPMin),
+                         static_cast<Standard_Real> (theYPMin));
+  gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXPMax),
+                         static_cast<Standard_Real> (theYPMax));
+  mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
+                                             aMaxMousePos);
+
+  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;
-  }
-
-  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);
-}
-
-//=======================================================================
-// 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;
+  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);
+
+  TraverseSensitives();
 }
 
-
 //=======================================================================
 // 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<Handle(Select3D_SensitiveEntity)>& 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 (file)
index 0000000..8931f11
--- /dev/null
@@ -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 <Standard.hxx>
+#include <Standard_Type.hxx>
+#include <Standard_DefineHandle.hxx>
+
+#include <Handle_Graphic3d_Group.hxx>
+#include <Handle_Graphic3d_Structure.hxx>
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <SelectMgr_ViewerSelector.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Handle_V3d_View.hxx>
+#include <Handle_SelectMgr_EntityOwner.hxx>
+#include <NCollection_Handle.hxx>
+
+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 <theTolerance>.
+  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 <theXPix> and <theYPix>. 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 <theXPMin>, <theYPMin>, <theXPMax>
+  //! and <theYPMax> 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 <theView>.
+  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 <StdSelect_ViewerSelector3d.lxx>
+
+#endif
index 8c910c1..c29b733 100644 (file)
 // 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;
 }
index 410cc3c..87447f7 100644 (file)
@@ -65,7 +65,6 @@
 #include <SelectMgr_EntityOwner.hxx>
 #include <StdSelect_BRepOwner.hxx>
 #include <StdSelect_ViewerSelector3d.hxx>
-#include <Select3D_Projector.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <ViewerTest_AutoUpdater.hxx>
 
@@ -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<Standard_Real> 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);
+
 }
 
 //=====================================================================
index e422a01..dc57808 100644 (file)
@@ -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",
index 6f44d21..befd5d8 100644 (file)
@@ -52,7 +52,6 @@
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
 #include <Precision.hxx>
-#include <Select3D_Projector.hxx>
 #include <StdSelect.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
@@ -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);
index 3bdc3cd..af5eaea 100644 (file)
@@ -108,7 +108,7 @@ is
     protected;
 
     ComputeSelection(me : mutable;
-                    theSelection : Selection from SelectMgr;
+                     theSelection : Selection from SelectMgr;
                     theMode      : Integer from Standard)
     is private;
 
index 1d2703a..20d20f7 100755 (executable)
@@ -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
index 496fa05..ec128f5 100755 (executable)
@@ -15,7 +15,7 @@ vinit
 vdisplay result
 vfit
 vsetdispmode 1
-vselect 290 135
+vselect 289 135
 
 set length 5.82393
 set only_screen 0
index 84fbd11..143dc1a 100755 (executable)
@@ -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]
 
index a7c3ce6..bb10a4e 100644 (file)
@@ -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
index dced33d..0b7cbb4 100644 (file)
@@ -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}
index 9292942..845286f 100644 (file)
@@ -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}
index 1c6d69f..eaa670f 100644 (file)
@@ -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)"
index 7d7f315..85f09be 100644 (file)
@@ -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!"
 }
index 0c83162..e3f0818 100644 (file)
@@ -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 (file)
index 0000000..f83d251
--- /dev/null
@@ -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 (file)
index 0000000..784cb7f
--- /dev/null
@@ -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 (file)
index 0000000..451488e
--- /dev/null
@@ -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 (file)
index 0000000..2f1615d
--- /dev/null
@@ -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"
+}
index 60b5935..dec8510 100644 (file)
@@ -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"
 }
index fbcf94a..14d888e 100644 (file)
@@ -19,6 +19,7 @@ vaxo
 vcaps -vbo 0
 vsetdispmode 1
 vdefaults absDefl=1.0
+vautoactivatesel 0
 set aMemInit [meminfo h]
 
 set aNb 1000
index 1a518e5..673506a 100644 (file)
@@ -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" } {
index f725c5e..dd3e7f2 100644 (file)
@@ -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
index 8eeeb40..640146b 100644 (file)
@@ -1,6 +1,5 @@
 puts "============"
 puts "CR25935"
-puts "Visualization, TKV3d, Exception when displaying shell in the viewer"
 puts "============"
 puts ""
 
index 771fabf..5f32178 100644 (file)
@@ -42,5 +42,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index 4344ea8..0eea14f 100644 (file)
@@ -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
 
index fa7a656..2de1363 100644 (file)
@@ -43,5 +43,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index 7d81c1e..6f85b8c 100644 (file)
@@ -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
 
index cef19ce..2d063c7 100644 (file)
@@ -45,5 +45,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index b3fcd32..a97ca75 100644 (file)
@@ -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
 
index 53f8cd8..1c003ff 100644 (file)
@@ -42,5 +42,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index 1c9fc71..9396cf4 100644 (file)
@@ -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
 
index fa9eff5..7198c4f 100644 (file)
@@ -43,5 +43,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index 1c52ccc..47ff98d 100644 (file)
@@ -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
 
index 8042caa..a6143b5 100644 (file)
@@ -45,5 +45,5 @@ vmoveto 225 98
 vmoveto 0 0
 vmoveto 270 326
 vmoveto 0 0
-vmoveto 341 111
+vmoveto 342 111
 
index b4396bb..065f006 100644 (file)
@@ -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
 
index 75d8b4f..3cccf76 100644 (file)
@@ -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
 
index 0218a64..c3fca24 100644 (file)
@@ -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
 
index 0b3a9df..38d7f64 100644 (file)
@@ -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
 
index e793b7d..6446e2b 100644 (file)
@@ -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
 
index 91d4f80..54ce708 100644 (file)
@@ -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
 
index 6c8ff2f..c6cecdd 100644 (file)
@@ -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
 
index 7d68360..f1604cf 100644 (file)
@@ -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
 
index 686934e..6fdd582 100644 (file)
@@ -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
 
index 50d0087..e96419c 100644 (file)
@@ -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
 
index 8a7e0e1..576182c 100644 (file)
@@ -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
 
index a7c42f9..66a6229 100644 (file)
@@ -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
 
index a32a485..c4fb4a4 100644 (file)
@@ -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
 
index f9dbdf5..8cccc59 100644 (file)
@@ -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
 
index 6fe215e..83971d9 100644 (file)
@@ -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
 
index b11b981..9038808 100644 (file)
@@ -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
 
index 154f1d1..3eda4d2 100644 (file)
@@ -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
 
index be8a923..59353e0 100644 (file)
@@ -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
 
index be875aa..d26f372 100644 (file)
@@ -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
 
index e0ad8cc..8439205 100644 (file)
@@ -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
 
index 62c9f47..9f53647 100644 (file)
@@ -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
index 81b16c6..5253e7f 100644 (file)
@@ -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
index 9b88d6d..c93f4f8 100644 (file)
@@ -43,5 +43,5 @@ vmoveto 214 112
 vmoveto 0 0
 vmoveto 104 203
 vmoveto 0 0
-vmoveto 209 35
+vmoveto 209 34
 
index 43afe2e..8c74847 100644 (file)
@@ -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
 
index 4136dbe..c050bf9 100644 (file)
@@ -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
 
index daa03cd..0c24fe0 100644 (file)
@@ -45,5 +45,5 @@ vmoveto 214 112
 vmoveto 0 0
 vmoveto 104 203
 vmoveto 0 0
-vmoveto 209 35
+vmoveto 209 34
 
index 2458932..56c072d 100644 (file)
@@ -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
 
index d568745..54a045a 100644 (file)
@@ -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