0027180: Visualization - improve selection logic of MeshVS_Mesh
authorvpa <vpa@opencascade.com>
Wed, 2 Mar 2016 17:27:42 +0000 (20:27 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 3 Mar 2016 11:17:17 +0000 (14:17 +0300)
MeshVS_Mesh selection logic in MeshVS_SMF_Mesh mode (entire mesh) has been optimized.
MeshVS_Mesh::ComputeSelection() now creates single sensitive entity
MeshVS_CommonSensitiveEntity (new class) instead of small sensitive entity on each element.
MeshVS_SensitiveQuad (new class) and Select3D_SensitiveTriangle are used instead of Select3D_SensitiveFace for local selection to reduce memory consumption when possible.

23 files changed:
src/MeshVS/FILES
src/MeshVS/MeshVS_Buffer.hxx
src/MeshVS/MeshVS_CommonSensitiveEntity.cxx [new file with mode: 0644]
src/MeshVS/MeshVS_CommonSensitiveEntity.hxx [new file with mode: 0644]
src/MeshVS/MeshVS_Mesh.cxx
src/MeshVS/MeshVS_Mesh.hxx
src/MeshVS/MeshVS_SensitiveQuad.cxx [new file with mode: 0644]
src/MeshVS/MeshVS_SensitiveQuad.hxx [new file with mode: 0644]
src/SelectBasics/SelectBasics_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_BaseFrustum.cxx
src/SelectMgr/SelectMgr_BaseFrustum.hxx
src/SelectMgr/SelectMgr_Frustum.hxx
src/SelectMgr/SelectMgr_Frustum.lxx
src/SelectMgr/SelectMgr_RectangularFrustum.cxx
src/SelectMgr/SelectMgr_RectangularFrustum.hxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_TriangularFrustum.cxx
src/SelectMgr/SelectMgr_TriangularFrustum.hxx
src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx
src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx
src/StdSelect/StdSelect_BRepSelectionTool.cxx
src/StdSelect/StdSelect_BRepSelectionTool.hxx

index 03957f4..40672f9 100755 (executable)
@@ -3,6 +3,8 @@ MeshVS_Buffer.hxx
 MeshVS_BuilderPriority.hxx
 MeshVS_ColorHasher.cxx
 MeshVS_ColorHasher.hxx
+MeshVS_CommonSensitiveEntity.hxx
+MeshVS_CommonSensitiveEntity.cxx
 MeshVS_DataMapIteratorOfDataMapOfColorMapOfInteger.hxx
 MeshVS_DataMapIteratorOfDataMapOfHArray1OfSequenceOfInteger.hxx
 MeshVS_DataMapIteratorOfDataMapOfIntegerAsciiString.hxx
@@ -67,6 +69,8 @@ MeshVS_SensitivePolyhedron.cxx
 MeshVS_SensitivePolyhedron.hxx
 MeshVS_SensitiveSegment.cxx
 MeshVS_SensitiveSegment.hxx
+MeshVS_SensitiveQuad.hxx
+MeshVS_SensitiveQuad.cxx
 MeshVS_SequenceOfPrsBuilder.hxx
 MeshVS_SymmetricPairHasher.hxx
 MeshVS_TextPrsBuilder.cxx
index 51ab75d..47a8370 100644 (file)
@@ -17,6 +17,7 @@
 #define MeshVS_Buffer_HeaderFile
 
 #include <Standard.hxx>
+#include <gp_Pnt.hxx>
 
 /**
  * General purpose buffer that is allocated on the stack with a
@@ -68,6 +69,12 @@ public:
     return * (myDynData ? (Standard_Integer*) myDynData : (Standard_Integer*) myAutoData);
   }
 
+  //! Interpret the buffer as a reference to gp_Pnt
+  operator gp_Pnt& ()
+  {
+    return * (myDynData ? (gp_Pnt*) myDynData : (gp_Pnt*) myAutoData);
+  }
+
 private:
   //! Deprecate copy constructor
   MeshVS_Buffer(const MeshVS_Buffer&) {}
diff --git a/src/MeshVS/MeshVS_CommonSensitiveEntity.cxx b/src/MeshVS/MeshVS_CommonSensitiveEntity.cxx
new file mode 100644 (file)
index 0000000..9438498
--- /dev/null
@@ -0,0 +1,323 @@
+// Created on: 2016-02-18
+// Created by: Varvara POSKONINA
+// Copyright (c) 2016 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 <MeshVS_CommonSensitiveEntity.hxx>
+
+#include <MeshVS_Buffer.hxx>
+#include <MeshVS_Drawer.hxx>
+#include <MeshVS_DrawerAttribute.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwner,
+                                                            const Handle(MeshVS_Mesh)&              theParentMesh,
+                                                            const MeshVS_MeshSelectionMethod        theSelMethod)
+: Select3D_SensitiveSet (theOwner),
+  myDataSource (theParentMesh->GetDataSource()),
+  mySelMethod (theSelMethod)
+{
+  theParentMesh->GetDrawer()->GetInteger (MeshVS_DA_MaxFaceNodes, myMaxFaceNodes);
+  Standard_ASSERT_RAISE (myMaxFaceNodes > 0,
+    "The maximal amount of nodes in a face must be greater than zero to create sensitive entity");
+  gp_XYZ aCenter (0.0, 0.0, 0.0);
+
+  if (mySelMethod == MeshVS_MSM_NODES)
+  {
+    Standard_Integer aNbSelectableNodes = 0;
+    const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
+    for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
+    {
+      const Standard_Integer aNodeIdx = aNodesIter.Key();
+      if (theParentMesh->IsSelectableNode (aNodeIdx))
+      {
+        const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
+        aCenter += aVertex.XYZ();
+        myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
+        ++aNbSelectableNodes;
+        myItemIndexes.Append (aNodeIdx);
+      }
+    }
+
+    // increase sensitivity for vertices detection
+    SetSensitivityFactor (8);
+    myCOG = aCenter / aNbSelectableNodes;
+  }
+  else if (mySelMethod == MeshVS_MSM_PRECISE)
+  {
+    const TColStd_PackedMapOfInteger& anAllNodesMap = myDataSource->GetAllNodes();
+    for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
+    {
+      const Standard_Integer aNodeIdx = aNodesIter.Key();
+      const gp_Pnt aVertex = getVertexByIndex (aNodeIdx);
+      aCenter += aVertex.XYZ();
+      myBndBox.Add (SelectMgr_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
+    }
+    myCOG = aCenter / anAllNodesMap.Extent();
+
+    const TColStd_PackedMapOfInteger& anAllElementsMap = myDataSource->GetAllElements();
+    MeshVS_EntityType aType;
+    for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
+    {
+      const Standard_Integer anElemIdx = anElemIter.Key();
+      if (theParentMesh->IsSelectableElem (anElemIdx)
+       && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
+       && aType == MeshVS_ET_Face)
+      {
+        myItemIndexes.Append (anElemIdx);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : Destructor
+//purpose  :
+//=======================================================================
+MeshVS_CommonSensitiveEntity::~MeshVS_CommonSensitiveEntity()
+{
+  myDataSource.Nullify();
+  myItemIndexes.Clear();
+}
+
+//=======================================================================
+//function : NbSubElements
+//purpose  :
+//=======================================================================
+Standard_Integer MeshVS_CommonSensitiveEntity::NbSubElements()
+{
+  return myItemIndexes.Size();
+}
+
+//=======================================================================
+//function : Size
+//purpose  :
+//=======================================================================
+Standard_Integer MeshVS_CommonSensitiveEntity::Size() const
+{
+  return myItemIndexes.Size();
+}
+
+//=======================================================================
+//function : getVertexByIndex
+//purpose  :
+//=======================================================================
+gp_Pnt MeshVS_CommonSensitiveEntity::getVertexByIndex (const Standard_Integer theNodeIdx) const
+{
+  Standard_Real aCoordsBuf[3];
+  TColStd_Array1OfReal aCoords (aCoordsBuf[0], 1, 3);
+  Standard_Integer aNbNodes;
+  MeshVS_EntityType aType;
+  if (!myDataSource->GetGeom (theNodeIdx, Standard_False, aCoords, aNbNodes, aType))
+  {
+    return gp_Pnt();
+  }
+  return gp_Pnt (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
+}
+
+//=======================================================================
+//function : Box
+//purpose  :
+//=======================================================================
+Select3D_BndBox3d MeshVS_CommonSensitiveEntity::Box (const Standard_Integer theIdx) const
+{
+  const Standard_Integer anItemIdx = myItemIndexes.Value (theIdx);
+  Select3D_BndBox3d aBox;
+  if (mySelMethod == MeshVS_MSM_PRECISE)
+  {
+    MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
+    TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
+    Standard_Integer aNbNodes;
+    MeshVS_EntityType aType;
+    if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
+      || aNbNodes == 0)
+    {
+      return aBox;
+    }
+
+    MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
+    TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
+    if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
+    {
+      return aBox;
+    }
+
+    for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
+    {
+      const SelectMgr_Vec3 aPnt (aCoords (3 * aNodeIdx - 2),
+                                 aCoords (3 * aNodeIdx - 1),
+                                 aCoords (3 * aNodeIdx));
+      aBox.Add (aPnt);
+    }
+  }
+  else if (mySelMethod == MeshVS_MSM_NODES)
+  {
+    const gp_Pnt aVert = getVertexByIndex (anItemIdx);
+    aBox.Add (SelectMgr_Vec3 (aVert.X(), aVert.Y(), aVert.Z()));
+  }
+
+  return aBox;
+}
+
+//=======================================================================
+//function : Center
+//purpose  :
+//=======================================================================
+Standard_Real MeshVS_CommonSensitiveEntity::Center (const Standard_Integer theIdx,
+                                                    const Standard_Integer theAxis) const
+{
+  const Select3D_BndBox3d& aBox = Box (theIdx);
+  SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
+
+  return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
+}
+
+//=======================================================================
+//function : Swap
+//purpose  :
+//=======================================================================
+void MeshVS_CommonSensitiveEntity::Swap (const Standard_Integer theIdx1,
+                                         const Standard_Integer theIdx2)
+{
+  const Standard_Integer anItem1 = myItemIndexes.Value (theIdx1);
+  const Standard_Integer anItem2 = myItemIndexes.Value (theIdx2);
+  myItemIndexes.ChangeValue (theIdx1) = anItem2;
+  myItemIndexes.ChangeValue (theIdx2) = anItem1;
+}
+
+//=======================================================================
+//function : overlapsElement
+//purpose  :
+//=======================================================================
+Standard_Boolean MeshVS_CommonSensitiveEntity::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
+                                                                Standard_Integer theElemIdx,
+                                                                Standard_Real& theMatchDepth)
+{
+  const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
+  if (mySelMethod == MeshVS_MSM_PRECISE)
+  {
+    MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
+    TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
+    Standard_Integer aNbNodes;
+    MeshVS_EntityType aType;
+    if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
+      || aNbNodes == 0)
+    {
+      return Standard_False;
+    }
+
+    MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
+    TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
+    if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
+    {
+      return Standard_False;
+    }
+    if (aNbNodes == 3)
+    {
+      return theMgr.Overlaps (gp_Pnt (aCoords (1), aCoords (2), aCoords (3)),
+                              gp_Pnt (aCoords (4), aCoords (5), aCoords (6)),
+                              gp_Pnt (aCoords (7), aCoords (8), aCoords (9)),
+                              Select3D_TOS_INTERIOR, theMatchDepth);
+    }
+
+    MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
+    TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
+    for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; aNodeIdx++)
+    {
+      aFacePnts.SetValue (aNodeIdx, gp_Pnt (aCoords (3 * aNodeIdx - 2),
+                                            aCoords (3 * aNodeIdx - 1),
+                                            aCoords (3 * aNodeIdx)));
+    }
+    return theMgr.Overlaps (aFacePnts, Select3D_TOS_INTERIOR, theMatchDepth);
+  }
+  else if (mySelMethod == MeshVS_MSM_NODES)
+  {
+    const gp_Pnt aVert = getVertexByIndex (anItemIdx);
+    return theMgr.Overlaps (aVert, theMatchDepth);
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : elementIsInside
+//purpose  :
+//=======================================================================
+Standard_Boolean MeshVS_CommonSensitiveEntity::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
+                                                                const Standard_Integer theElemIdx)
+{
+  const Standard_Integer anItemIdx = myItemIndexes.Value (theElemIdx);
+  if (mySelMethod == MeshVS_MSM_PRECISE)
+  {
+    MeshVS_Buffer aCoordsBuf (3 * myMaxFaceNodes * sizeof (Standard_Real));
+    TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * myMaxFaceNodes);
+    Standard_Integer aNbNodes;
+    MeshVS_EntityType aType;
+    if (!myDataSource->GetGeom (anItemIdx, Standard_True, aCoords, aNbNodes, aType)
+      || aNbNodes == 0)
+    {
+      return Standard_False;
+    }
+
+    MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
+    TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
+    if (!myDataSource->GetNodesByElement (anItemIdx, aElemNodes, aNbNodes))
+    {
+      return Standard_False;
+    }
+
+    MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
+    TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
+    for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
+    {
+      const gp_Pnt aPnt (aCoords (3 * aNodeIdx - 2),
+                         aCoords (3 * aNodeIdx - 1),
+                         aCoords (3 * aNodeIdx));
+      if (!theMgr.Overlaps (aPnt))
+      {
+        return Standard_False;
+      }
+    }
+    return Standard_True;
+  }
+  else if (mySelMethod == MeshVS_MSM_NODES)
+  {
+    const gp_Pnt aVert = getVertexByIndex (anItemIdx);
+    return theMgr.Overlaps (aVert);
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : distanceToCOG
+//purpose  :
+//=======================================================================
+Standard_Real MeshVS_CommonSensitiveEntity::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
+{
+  return theMgr.DistToGeometryCenter (myCOG);
+}
+
+//=======================================================================
+//function : BoundingBox
+//purpose  :
+//=======================================================================
+Select3D_BndBox3d MeshVS_CommonSensitiveEntity::BoundingBox()
+{
+  return myBndBox;
+}
diff --git a/src/MeshVS/MeshVS_CommonSensitiveEntity.hxx b/src/MeshVS/MeshVS_CommonSensitiveEntity.hxx
new file mode 100644 (file)
index 0000000..90bf524
--- /dev/null
@@ -0,0 +1,94 @@
+// Created on: 2016-02-18
+// Created by: Varvara POSKONINA
+// Copyright (c) 2016 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_CommonSensitiveEntity_Header
+#define _MeshVS_CommonSensitiveEntity_Header
+
+#include <MeshVS_DataSource.hxx>
+#include <MeshVS_Mesh.hxx>
+#include <MeshVS_MeshSelectionMethod.hxx>
+#include <Select3D_SensitiveSet.hxx>
+
+//! Sensitive entity covering entire mesh for global selection.
+class MeshVS_CommonSensitiveEntity : public Select3D_SensitiveSet
+{
+public:
+
+  //! Default constructor.
+  Standard_EXPORT MeshVS_CommonSensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwner,
+                                                const Handle(MeshVS_Mesh)&              theParentMesh,
+                                                const MeshVS_MeshSelectionMethod        theSelMethod);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~MeshVS_CommonSensitiveEntity();
+
+  //! Number of elements.
+  Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
+
+  //! Returns the amount of sub-entities of the complex entity
+  Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
+
+  //! Returns bounding box of sub-entity with index theIdx in sub-entity list
+  Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
+
+  //! Returns geometry center of sensitive entity index theIdx 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
+  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;
+
+public:
+
+  DEFINE_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
+
+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;
+
+  //! Checks whether the entity with index theIdx is inside the current selecting volume
+  Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
+                                                            const Standard_Integer theElemIdx) 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:
+
+  //! Return point for specified index.
+  gp_Pnt getVertexByIndex (const Standard_Integer theNodeIdx) const;
+
+private:
+
+  Handle(MeshVS_DataSource)            myDataSource;   //!< mesh data source
+  NCollection_Vector<Standard_Integer> myItemIndexes;  //!< indices for BVH tree reordering
+  MeshVS_MeshSelectionMethod           mySelMethod;    //!< selection mode
+  Standard_Integer                     myMaxFaceNodes; //!< maximum nodes within the element in mesh
+  gp_Pnt                               myCOG;          //!< center of gravity
+  Select3D_BndBox3d                    myBndBox;       //!< bounding box
+
+};
+
+DEFINE_STANDARD_HANDLE (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
+
+#endif // _MeshVS_CommonSensitiveEntity_Header
index 1027721..e8fb5be 100644 (file)
@@ -22,6 +22,7 @@
 #include <Graphic3d_MaterialAspect.hxx>
 #include <Graphic3d_NameOfMaterial.hxx>
 #include <MeshVS_Buffer.hxx>
+#include <MeshVS_CommonSensitiveEntity.hxx>
 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerOwner.hxx>
 #include <MeshVS_DataSource.hxx>
 #include <MeshVS_Drawer.hxx>
@@ -36,6 +37,7 @@
 #include <MeshVS_SensitiveMesh.hxx>
 #include <MeshVS_SensitivePolyhedron.hxx>
 #include <MeshVS_SensitiveSegment.hxx>
+#include <MeshVS_SensitiveQuad.hxx>
 #include <OSD_Timer.hxx>
 #include <Prs3d_LineAspect.hxx>
 #include <Prs3d_PointAspect.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <Select3D_SensitiveGroup.hxx>
 #include <Select3D_SensitivePoint.hxx>
+#include <Select3D_SensitiveTriangle.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
 #include <SelectMgr_SequenceOfOwner.hxx>
 #include <Standard_Type.hxx>
+#include <StdSelect_BRepSelectionTool.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_Array1OfReal.hxx>
@@ -195,6 +199,46 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg
 }
 
 //================================================================
+// Function : scanFacesForSharedNodes
+// Purpose  :
+//================================================================
+void MeshVS_Mesh::scanFacesForSharedNodes (const TColStd_PackedMapOfInteger& theAllElements,
+                                           const Standard_Integer theNbMaxFaceNodes,
+                                           TColStd_PackedMapOfInteger& theSharedNodes) const
+{
+  theSharedNodes.Clear();
+  MeshVS_EntityType aType;
+  Standard_Integer aNbNodes;
+  MeshVS_Buffer aCoordsBuf (3 * theNbMaxFaceNodes * sizeof (Standard_Real));
+  TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * theNbMaxFaceNodes);
+  for (TColStd_MapIteratorOfPackedMapOfInteger aFaceIter (theAllElements); aFaceIter.More(); aFaceIter.Next())
+  {
+    const Standard_Integer aFaceIdx = aFaceIter.Key();
+
+    if (IsSelectableElem (aFaceIdx) &&
+      myDataSource->GetGeomType (aFaceIdx, Standard_True, aType) &&
+      aType == MeshVS_ET_Face)
+    {
+      myDataSource->GetGeom (aFaceIdx, Standard_True, aCoords, aNbNodes, aType );
+      if (aNbNodes == 0)
+        continue;
+
+      MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
+      TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
+      if (!myDataSource->GetNodesByElement (aFaceIdx, aElemNodes, aNbNodes))
+        continue;
+
+      MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
+      TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
+      for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
+      {
+        theSharedNodes.Add (aElemNodes (aNodeIdx));
+      }
+    }
+  }
+}
+
+//================================================================
 // Function : ComputeSelection
 // Purpose  :
 //================================================================
@@ -296,116 +340,86 @@ void MeshVS_Mesh::ComputeSelection ( const Handle(SelectMgr_Selection)& theSelec
 
       if( myWholeMeshOwner.IsNull() )
        myWholeMeshOwner = new SelectMgr_EntityOwner( this );
-      
-      switch( mySelectionMethod )
+
+      switch (mySelectionMethod)
       {
       case MeshVS_MSM_BOX:
-        {
-          Bnd_Box box;
-          TColStd_MapIteratorOfPackedMapOfInteger anIterN( anAllNodesMap );
-          for( ; anIterN.More(); anIterN.Next() )
-         {
-            if( myDataSource->GetGeom( anIterN.Key(), Standard_False, aCoords, NbNodes, aType ) ) {
-              box.Add (gp_Pnt (aCoords(1), aCoords(2), aCoords(3)));
-            }
-         }
-          if (!box.IsVoid())
-            theSelection->Add (new Select3D_SensitiveBox (myWholeMeshOwner, box));
-        }
-        break;
-
+      {
+        Bnd_Box aBndBox;
+        BoundingBox (aBndBox);
+        if (!aBndBox.IsVoid())
+          theSelection->Add (new Select3D_SensitiveBox (myWholeMeshOwner, aBndBox));
+      }
+      break;
       case MeshVS_MSM_NODES:
-        {
-          TColStd_MapIteratorOfPackedMapOfInteger anIterN( anAllNodesMap );
-          for( ; anIterN.More(); anIterN.Next() )
-            if( myDataSource->GetGeom( anIterN.Key(), Standard_False, aCoords, NbNodes, aType ) &&
-                IsSelectableNode( anIterN.Key() ) )
-              theSelection->Add( new Select3D_SensitivePoint( myWholeMeshOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3) ) ) );
-        }
-        break;
-
+      {
+        theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_NODES));
+      }
+      break;
       case MeshVS_MSM_PRECISE:
+      {
+        theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_PRECISE));
+
+        // since MeshVS_Mesh objects can contain free edges and vertices, it is necessary to create
+        // separate sensitive entity for each of them
+        TColStd_PackedMapOfInteger aSharedNodes;
+        scanFacesForSharedNodes (anAllElementsMap, aMaxFaceNodes, aSharedNodes);
+
+        // create sensitive entities for free edges, if there are any
+        for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
         {
-          Handle( Select3D_SensitiveEntity ) anEnt;
-          TColStd_MapIteratorOfPackedMapOfInteger anIterMV( anAllElementsMap );
+          const Standard_Integer anElemIdx = anElemIter.Key();
 
-          TColStd_PackedMapOfInteger aSharedNodes;
-          for( ; anIterMV.More(); anIterMV.Next() )
+          if (IsSelectableElem (anElemIdx) &&
+            myDataSource->GetGeomType (anElemIdx, Standard_True, aType) &&
+            aType == MeshVS_ET_Link)
           {
-            Standard_Integer aKey = anIterMV.Key();
-
-            if( IsSelectableElem( aKey ) && 
-                myDataSource->GetGeomType( aKey, Standard_True, aType ) && 
-                aType==MeshVS_ET_Face )
+            myDataSource->GetGeom (anElemIdx, Standard_True, aCoords, NbNodes, aType);
+            if (NbNodes == 0)
+              continue;
+            
+            MeshVS_Buffer aNodesBuf (NbNodes * sizeof (Standard_Integer));
+            TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, NbNodes);
+            if (!myDataSource->GetNodesByElement (anElemIdx, aElemNodes, NbNodes))
+              continue;
+
+            MeshVS_Buffer aPntsBuf (NbNodes * 3 * sizeof (Standard_Real));
+            TColgp_Array1OfPnt aLinkPnts (aPntsBuf, 1, NbNodes);
+            Standard_Boolean isVertsShared = Standard_True;
+            for (Standard_Integer aPntIdx = 1; aPntIdx <= NbNodes; ++aPntIdx)
             {
-              myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
-              if( NbNodes==0 )
-                continue;
-
-              MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
-              TColStd_Array1OfInteger aElemNodes(aNodesBuf, 1, NbNodes);
-              if ( !myDataSource->GetNodesByElement ( aKey, aElemNodes, NbNodes ) )
-                continue;
-
-              TColgp_Array1OfPnt Points( 1, NbNodes );
-              for ( Standard_Integer i=1; i<=NbNodes; i++ )
-              {
-                Points (i) = gp_Pnt ( aCoords (3*i-2), aCoords (3*i-1), aCoords (3*i) );
-                aSharedNodes.Add( aElemNodes( i ) );
-              }
-
-              anEnt = new Select3D_SensitiveFace( myWholeMeshOwner, Points, Select3D_TOS_INTERIOR);
-              theSelection->Add( anEnt );
+              aLinkPnts (aPntIdx) = gp_Pnt (aCoords (3 * aPntIdx - 2),
+                                            aCoords (3 * aPntIdx - 1),
+                                            aCoords (3 * aPntIdx));
+              isVertsShared = isVertsShared && aSharedNodes.Contains (aElemNodes (aPntIdx));
+              aSharedNodes.Add (aElemNodes (aPntIdx));
             }
-          }
-          for( anIterMV.Initialize( anAllElementsMap ); anIterMV.More(); anIterMV.Next() )
-          {
-            Standard_Integer aKey = anIterMV.Key();
-
-            if( IsSelectableElem( aKey ) && 
-                myDataSource->GetGeomType( aKey, Standard_True, aType ) && 
-                aType==MeshVS_ET_Link )
+            
+            if (!isVertsShared)
             {
-              myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
-              if( NbNodes==0 )
-                continue;
-
-              MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
-              TColStd_Array1OfInteger aElemNodes(aNodesBuf, 1, NbNodes);
-              if ( !myDataSource->GetNodesByElement ( aKey, aElemNodes, NbNodes ) )
-                continue;
-
-              TColgp_Array1OfPnt Points( 1, NbNodes );
-              Standard_Boolean all_shared = Standard_True;
-              for ( Standard_Integer i=1; i<=NbNodes; i++ )
-              {
-                Points (i) = gp_Pnt ( aCoords (3*i-2), aCoords (3*i-1), aCoords (3*i) );
-                all_shared = all_shared && aSharedNodes.Contains( aElemNodes( i ) );
-                aSharedNodes.Add( aElemNodes( i ) );
-              }
-
-              if( !all_shared )
-              {
-                anEnt = new Select3D_SensitiveSegment( myWholeMeshOwner, Points.Value( 1 ), Points.Value( 2 ) );
-                theSelection->Add( anEnt );
-              }
+              Handle(Select3D_SensitiveEntity) aLinkEnt
+                = new Select3D_SensitiveSegment (myWholeMeshOwner, aLinkPnts.Value (1), aLinkPnts.Value (2));
+              theSelection->Add (aLinkEnt);
             }
           }
-          for( anIterMV.Initialize( anAllNodesMap ); anIterMV.More(); anIterMV.Next() )
+        }
+
+        // create sensitive entities for free nodes, if there are any
+        for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
+        {
+          const Standard_Integer aNodeIdx = aNodesIter.Key();
+          if (IsSelectableNode (aNodeIdx) &&
+            myDataSource->GetGeom (aNodeIdx, Standard_False, aCoords, NbNodes, aType) &&
+            !aSharedNodes.Contains (aNodeIdx))
           {
-            Standard_Integer aKey = anIterMV.Key();
-            if( IsSelectableElem( aKey ) && 
-                myDataSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) && 
-                !aSharedNodes.Contains( aKey ) )
-            {
-              anEnt = new Select3D_SensitivePoint( myWholeMeshOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3) ) ) ;
-              theSelection->Add( anEnt );
-            }
+            Handle(Select3D_SensitiveEntity) aNodeEnt
+              = new Select3D_SensitivePoint (myWholeMeshOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3)));
+            theSelection->Add (aNodeEnt);
           }
         }
-        break;
       }
       break;
+      }
 
     case MeshVS_SMF_Group:
       {
@@ -471,9 +485,22 @@ void MeshVS_Mesh::ComputeSelection ( const Handle(SelectMgr_Selection)& theSelec
 
               if ( aType == MeshVS_ET_Face && NbNodes > 0 )      // Faces: 2D-elements
               {
-                Handle (MeshVS_SensitiveFace) aFace = 
-                  new MeshVS_SensitiveFace( anOwner, anArr );
-                theSelection->Add ( aFace );
+                Handle(Select3D_SensitiveEntity) aSensFace;
+                if (NbNodes == 3)
+                {
+                  aSensFace = new Select3D_SensitiveTriangle (anOwner,
+                                                              anArr.Value (1), anArr.Value (2), anArr.Value (3),
+                                                              Select3D_TOS_INTERIOR);
+                }
+                else if (NbNodes == 4)
+                {
+                  aSensFace = new MeshVS_SensitiveQuad (anOwner, anArr);
+                }
+                else
+                {
+                  aSensFace = new MeshVS_SensitiveFace (anOwner, anArr);
+                }
+                theSelection->Add (aSensFace);
                 added = Standard_True;
               }
               else if ( aType == MeshVS_ET_Link && NbNodes > 0 ) // Links: 1D-elements
@@ -562,9 +589,22 @@ void MeshVS_Mesh::ComputeSelection ( const Handle(SelectMgr_Selection)& theSelec
 
               if ( aType == MeshVS_ET_Face && NbNodes > 0 )      // Faces: 2D-elements
               {
-                Handle (MeshVS_SensitiveFace) aFace = 
-                  new MeshVS_SensitiveFace( anOwner, anArr );
-                theSelection->Add ( aFace );
+                Handle(Select3D_SensitiveEntity) aSensFace;
+                if (NbNodes == 3)
+                {
+                  aSensFace = new Select3D_SensitiveTriangle (anOwner,
+                                                              anArr.Value (1), anArr.Value (2), anArr.Value (3),
+                                                              Select3D_TOS_INTERIOR);
+                }
+                else if (NbNodes == 4)
+                {
+                  aSensFace = new MeshVS_SensitiveQuad (anOwner, anArr);
+                }
+                else
+                {
+                  aSensFace = new MeshVS_SensitiveFace (anOwner, anArr);
+                }
+                theSelection->Add (aSensFace);
               }
               else if ( aType == MeshVS_ET_Link && NbNodes > 0 ) // Links: 1D-elements
               {
@@ -595,6 +635,8 @@ void MeshVS_Mesh::ComputeSelection ( const Handle(SelectMgr_Selection)& theSelec
     }
   }
 
+  StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
+
   if ( ShowComputeSelectionTime )
   {
     Standard_Real sec, cpu;
index 2561ccf..d15c562 100644 (file)
@@ -185,6 +185,16 @@ friend class MeshVS_PrsBuilder;
 
 protected:
 
+  //! Stores all vertices that belong to one of the faces to the given map
+  //! @param theAllElements [in] the map of all mesh elements
+  //! @param theNbMaxFaceNodes [in] the maximum amount of nodes per face, retrieved from drawer
+  //! @param theSharedNodes [out] the result map of all vertices that belong to one face at least
+  Standard_EXPORT void scanFacesForSharedNodes (const TColStd_PackedMapOfInteger& theAllElements,
+                                                const Standard_Integer theNbMaxFaceNodes,
+                                                TColStd_PackedMapOfInteger& theSharedNodes) const;
+
+protected:
+
 
   MeshVS_DataMapOfIntegerOwner myNodeOwners;
   MeshVS_DataMapOfIntegerOwner myElementOwners;
diff --git a/src/MeshVS/MeshVS_SensitiveQuad.cxx b/src/MeshVS/MeshVS_SensitiveQuad.cxx
new file mode 100644 (file)
index 0000000..5f0825d
--- /dev/null
@@ -0,0 +1,126 @@
+// Created on: 2016-03-02
+// Created by: Varvara POSKONINA
+// Copyright (c) 2016 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 <MeshVS_SensitiveQuad.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (MeshVS_SensitiveQuad, Select3D_SensitiveEntity)
+
+//=======================================================================
+// function : Constructor
+// purpose  :
+//=======================================================================
+MeshVS_SensitiveQuad::MeshVS_SensitiveQuad (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                            const TColgp_Array1OfPnt& theQuadVerts)
+: Select3D_SensitiveEntity (theOwner)
+{
+  const Standard_Integer aLowerIdx = theQuadVerts.Lower();
+  for (Standard_Integer aVertIdx = 0; aVertIdx < 4; ++aVertIdx)
+  {
+    myVertices[aVertIdx] = theQuadVerts.Value (aLowerIdx + aVertIdx);
+  }
+}
+
+//=======================================================================
+// function : Constructor
+// purpose  :
+//=======================================================================
+MeshVS_SensitiveQuad::MeshVS_SensitiveQuad (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                            const gp_Pnt& thePnt1,
+                                            const gp_Pnt& thePnt2,
+                                            const gp_Pnt& thePnt3,
+                                            const gp_Pnt& thePnt4)
+: Select3D_SensitiveEntity (theOwner)
+{
+  myVertices[0] = thePnt1;
+  myVertices[1] = thePnt2;
+  myVertices[2] = thePnt3;
+  myVertices[3] = thePnt4;
+}
+
+//=======================================================================
+// function : GetConnected
+// purpose  :
+//=======================================================================
+Handle(Select3D_SensitiveEntity) MeshVS_SensitiveQuad::GetConnected()
+{
+  return new MeshVS_SensitiveQuad (Handle(SelectMgr_EntityOwner)::DownCast (OwnerId()),
+    myVertices[0], myVertices[1], myVertices[2], myVertices[3]);
+}
+
+//=======================================================================
+// function : Matches
+// purpose  : Checks whether the box overlaps current selecting volume
+//=======================================================================
+Standard_Boolean MeshVS_SensitiveQuad::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+                                                SelectBasics_PickResult& thePickResult)
+{
+  thePickResult = SelectBasics_PickResult (RealLast(), RealLast());
+
+  if (!theMgr.IsOverlapAllowed()) // check for inclusion
+  {
+    for (Standard_Integer aPntIdx = 0; aPntIdx < 4; ++aPntIdx)
+    {
+      if (!theMgr.Overlaps (myVertices[aPntIdx]))
+        return Standard_False;
+    }
+
+    return Standard_True;
+  }
+
+  // check for overlap
+  Standard_Real aDepth1 = std::numeric_limits<Standard_Real>::max();
+  Standard_Real aDepth2 = std::numeric_limits<Standard_Real>::max();
+  if (!theMgr.Overlaps (myVertices[0], myVertices[1], myVertices[2], Select3D_TOS_INTERIOR, aDepth1)
+    && !theMgr.Overlaps (myVertices[0], myVertices[2], myVertices[3], Select3D_TOS_INTERIOR, aDepth2))
+  {
+    return Standard_False;
+  }
+
+  thePickResult = SelectBasics_PickResult (Min (aDepth1, aDepth2), theMgr.DistToGeometryCenter (CenterOfGeometry()));
+
+  return Standard_True;
+}
+
+//=======================================================================
+// function : CenterOfGeometry
+// purpose  :
+//=======================================================================
+gp_Pnt MeshVS_SensitiveQuad::CenterOfGeometry() const
+{
+  gp_XYZ aSum (0.0, 0.0, 0.0);
+  for (Standard_Integer aPntIdx = 0; aPntIdx < 4; ++aPntIdx)
+  {
+    aSum += myVertices[aPntIdx].XYZ();
+  }
+
+  return aSum / 4.0;
+}
+
+//=======================================================================
+// function : BoundingBox
+// purpose  :
+//=======================================================================
+Select3D_BndBox3d MeshVS_SensitiveQuad::BoundingBox()
+{
+  Select3D_BndBox3d aBox;
+  for (Standard_Integer aPntIdx = 0; aPntIdx < 4; ++aPntIdx)
+  {
+    aBox.Add (SelectMgr_Vec3 (myVertices[aPntIdx].X(),
+                              myVertices[aPntIdx].Y(),
+                              myVertices[aPntIdx].Z()));
+  }
+
+  return aBox;
+}
diff --git a/src/MeshVS/MeshVS_SensitiveQuad.hxx b/src/MeshVS/MeshVS_SensitiveQuad.hxx
new file mode 100644 (file)
index 0000000..416e29c
--- /dev/null
@@ -0,0 +1,68 @@
+// Created on: 2016-03-02
+// Created by: Varvara POSKONINA
+// Copyright (c) 2016 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_SensitiveQuad_HeaderFile
+#define _MeshVS_SensitiveQuad_HeaderFile
+
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+
+#include <TColgp_Array1OfPnt.hxx>
+
+//! This class contains description of planar quadrangle and defines methods
+//! for its detection by OCCT BVH selection mechanism
+class MeshVS_SensitiveQuad : public Select3D_SensitiveEntity
+{
+public:
+
+  //! Creates a new instance and initializes quadrangle vertices with the given points
+  Standard_EXPORT MeshVS_SensitiveQuad (const Handle(SelectMgr_EntityOwner)& theOwner, const TColgp_Array1OfPnt& theQuadVerts);
+
+  //! Creates a new instance and initializes quadrangle vertices with the given points
+  Standard_EXPORT MeshVS_SensitiveQuad (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                        const gp_Pnt& thePnt1,
+                                        const gp_Pnt& thePnt2,
+                                        const gp_Pnt& thePnt3,
+                                        const gp_Pnt& thePnt4);
+
+  //! Returns the amount of sub-entities in sensitive
+  Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE
+  {
+    return 1;
+  };
+
+  //! Returns a copy of this sensitive quadrangle
+  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;
+
+  //! Returns center of the box
+  Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
+
+  //! Returns coordinates of the box
+  Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT (MeshVS_SensitiveQuad, Select3D_SensitiveEntity)
+
+private:
+
+  gp_Pnt myVertices[4];     //!< 3d coordinates of quad's corners
+};
+
+DEFINE_STANDARD_HANDLE (MeshVS_SensitiveQuad, Select3D_SensitiveEntity)
+
+#endif // _MeshVS_SensitiveQuad_HeaderFile
index bb17a15..d4d40ea 100644 (file)
@@ -68,6 +68,12 @@ public:
                                      Standard_Integer theSensType,
                                      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 Standard_Boolean Overlaps (const TColgp_Array1OfPnt& 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 Standard_Boolean Overlaps (const gp_Pnt& thePt1,
index aecd3ad..3508da7 100644 (file)
@@ -176,7 +176,7 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt*/)
 //            may be considered of interior part or boundary line defined
 //            by segments depending on given sensitivity type
 //=======================================================================
-Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& /*theArrayOfPnts*/,
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const TColgp_Array1OfPnt& /*theArrayOfPnts*/,
                                                   Select3D_TypeOfSensitivity /*theSensType*/,
                                                   Standard_Real& /*theDepth*/)
 {
index c4adf95..225b835 100644 (file)
@@ -129,7 +129,7 @@ public:
   //! 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 Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+  Standard_EXPORT virtual Standard_Boolean Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                      Select3D_TypeOfSensitivity theSensType,
                                                      Standard_Real& theDepth);
 
index e73aef8..e03bed3 100644 (file)
@@ -76,7 +76,7 @@ protected:
                                                const gp_Pnt& thePnt2);
 
   //! SAT intersection test between frustum given and planar convex polygon represented as ordered point set
-  Standard_EXPORT Standard_Boolean hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+  Standard_EXPORT Standard_Boolean hasOverlap (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                gp_Vec& theNormal);
 
   //! SAT intersection test between defined volume and given triangle
index cc7e134..1562d3e 100644 (file)
@@ -308,15 +308,15 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
 //            polygon represented as ordered point set
 // =======================================================================
 template <int N>
-Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                    gp_Vec& theNormal)
 {
-  Standard_Integer aStartIdx = theArrayOfPnts->Lower();
-  Standard_Integer anEndIdx = theArrayOfPnts->Upper();
+  Standard_Integer aStartIdx = theArrayOfPnts.Lower();
+  Standard_Integer anEndIdx = theArrayOfPnts.Upper();
 
-  const gp_XYZ& aPnt1 = theArrayOfPnts->Value (aStartIdx).XYZ();
-  const gp_XYZ& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1).XYZ();
-  const gp_XYZ& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2).XYZ();
+  const gp_XYZ& aPnt1 = theArrayOfPnts.Value (aStartIdx).XYZ();
+  const gp_XYZ& aPnt2 = theArrayOfPnts.Value (aStartIdx + 1).XYZ();
+  const gp_XYZ& aPnt3 = theArrayOfPnts.Value (aStartIdx + 2).XYZ();
   const gp_XYZ aVec1 = aPnt1 - aPnt2;
   const gp_XYZ aVec2 = aPnt3 - aPnt2;
   theNormal = aVec2.Crossed (aVec1);
@@ -347,7 +347,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
     const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
     for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
     {
-      Standard_Real aProjection = aPlane.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
+      Standard_Real aProjection = aPlane.Dot (theArrayOfPnts.Value (aPntIter).XYZ());
       aMaxPolyg = Max (aMaxPolyg, aProjection);
       aMinPolyg = Min (aMinPolyg, aProjection);
     }
@@ -361,10 +361,10 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
   }
 
   Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6;
-  for (Standard_Integer aPntsIter = 0, aLastIdx = anEndIdx - aStartIdx, aLen = theArrayOfPnts->Length(); aPntsIter <= aLastIdx; ++aPntsIter)
+  for (Standard_Integer aPntsIter = 0, aLastIdx = anEndIdx - aStartIdx, aLen = theArrayOfPnts.Length(); aPntsIter <= aLastIdx; ++aPntsIter)
   {
-    const gp_XYZ aSegmDir = theArrayOfPnts->Value ((aPntsIter + 1) % aLen + aStartIdx).XYZ()
-      - theArrayOfPnts->Value (aPntsIter + aStartIdx).XYZ();
+    const gp_XYZ aSegmDir = theArrayOfPnts.Value ((aPntsIter + 1) % aLen + aStartIdx).XYZ()
+      - theArrayOfPnts.Value (aPntsIter + aStartIdx).XYZ();
     for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir)
     {
       Standard_Real aMaxPolyg = RealFirst();
@@ -375,7 +375,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
 
       for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
       {
-        Standard_Real aProjection = aTestDir.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
+        Standard_Real aProjection = aTestDir.Dot (theArrayOfPnts.Value (aPntIter).XYZ());
         aMaxPolyg = Max (aMaxPolyg, aProjection);
         aMinPolyg = Min (aMinPolyg, aProjection);
       }
index ff65aa7..664d3d4 100644 (file)
@@ -491,7 +491,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
 //            may be considered of interior part or boundary line defined
 //            by segments depending on given sensitivity type
 // =======================================================================
-Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                          Select3D_TypeOfSensitivity theSensType,
                                                          Standard_Real& theDepth)
 {
@@ -499,15 +499,12 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HAr
   {
     Standard_Integer aMatchingSegmentsNb = -1;
     theDepth = DBL_MAX;
-    Standard_Integer aLower = theArrayOfPnts->Lower();
-    Standard_Integer anUpper = theArrayOfPnts->Upper();
-
+    const Standard_Integer aLower  = theArrayOfPnts.Lower();
+    const 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);
-
+      const gp_Pnt& aStartPnt = theArrayOfPnts.Value (aPntIter);
+      const gp_Pnt& aEndPnt   = theArrayOfPnts.Value (aPntIter == anUpper ? aLower : (aPntIter + 1));
       if (hasOverlap (aStartPnt, aEndPnt))
       {
         aMatchingSegmentsNb++;
@@ -527,7 +524,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HAr
       return Standard_False;
 
     segmentPlaneIntersection (aPolyNorm,
-                              theArrayOfPnts->Value (theArrayOfPnts->Lower()),
+                              theArrayOfPnts.Value (theArrayOfPnts.Lower()),
                               theDepth);
   }
 
@@ -549,11 +546,8 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
 {
   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);
+    const gp_Pnt aPntsArrayBuf[4] = { thePnt1, thePnt2, thePnt3, thePnt1 };
+    const TColgp_Array1OfPnt aPntsArray (aPntsArrayBuf[0], 1, 4);
     return Overlaps (aPntsArray, Select3D_TOS_BOUNDARY, theDepth);
   }
   else if (theSensType == Select3D_TOS_INTERIOR)
index c1d4ca7..9cf9c12 100644 (file)
@@ -77,7 +77,7 @@ public:
   //! 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 Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+  Standard_EXPORT virtual Standard_Boolean Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                      Select3D_TypeOfSensitivity theSensType,
                                                      Standard_Real& theDepth) Standard_OVERRIDE;
 
index 69a7ca4..658900e 100644 (file)
@@ -284,6 +284,25 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp
   if (myActiveSelectionType == Unknown)
     return Standard_False;
 
+  return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts->Array1(),
+                                                                  (Select3D_TypeOfSensitivity)theSensType,
+                                                                  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
+//=======================================================================
+Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
+                                                             Standard_Integer theSensType,
+                                                             Standard_Real& theDepth)
+{
+  if (myActiveSelectionType == Unknown)
+    return Standard_False;
+
   return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
                                                                   (Select3D_TypeOfSensitivity)theSensType,
                                                                   theDepth);
index ec63b43..12f8901 100644 (file)
@@ -120,6 +120,13 @@ public:
                                                      Standard_Integer theSensType,
                                                      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 Standard_Boolean Overlaps (const TColgp_Array1OfPnt& theArrayOfPts,
+                                                     Standard_Integer theSensType,
+                                                     Standard_Real& theDepth) Standard_OVERRIDE;
+
   //! Checks if line segment overlaps selecting frustum
   Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
                                                      const gp_Pnt& thePnt2,
index ca0e675..79b02a1 100644 (file)
@@ -210,20 +210,18 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt,
 //            may be considered of interior part or boundary line defined
 //            by segments depending on given sensitivity type
 // =======================================================================
-Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                         Select3D_TypeOfSensitivity theSensType,
                                                         Standard_Real& /*theDepth*/)
 {
   if (theSensType == Select3D_TOS_BOUNDARY)
   {
-    Standard_Integer aLower = theArrayOfPnts->Lower();
-    Standard_Integer anUpper = theArrayOfPnts->Upper();
-
+    const Standard_Integer aLower  = theArrayOfPnts.Lower();
+    const 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);
-
+      const gp_Pnt& aStartPt = theArrayOfPnts.Value (aPtIdx);
+      const gp_Pnt& aEndPt   = theArrayOfPnts.Value (aPtIdx == anUpper ? aLower : (aPtIdx + 1));
       if (!hasOverlap (aStartPt, aEndPt))
       {
         return Standard_False;
@@ -265,11 +263,9 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt1,
 {
   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);
+    const gp_Pnt aPntsArrayBuf[3] = { thePnt1, thePnt2, thePnt3 };
+    const TColgp_Array1OfPnt aPntsArray (aPntsArrayBuf[0], 1, 3);
+    return Overlaps (aPntsArray, Select3D_TOS_BOUNDARY, theDepth);
   }
   else if (theSensType == Select3D_TOS_INTERIOR)
   {
index b829de8..ceb104f 100644 (file)
@@ -63,7 +63,7 @@ public:
   //! 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 Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+  Standard_EXPORT virtual Standard_Boolean Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                      Select3D_TypeOfSensitivity theSensType,
                                                      Standard_Real& theDepth) Standard_OVERRIDE;
 
index b221524..c5d8c9f 100644 (file)
@@ -175,7 +175,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt,
 // function : Overlaps
 // purpose  :
 // =======================================================================
-Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
+Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const TColgp_Array1OfPnt& theArrayOfPts,
                                                            Select3D_TypeOfSensitivity theSensType,
                                                            Standard_Real& theDepth)
 {
index 71f0b36..baad601 100644 (file)
@@ -61,7 +61,7 @@ public:
   Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
                                                      Standard_Real& theDepth) Standard_OVERRIDE;
 
-  Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
+  Standard_EXPORT virtual Standard_Boolean Overlaps (const TColgp_Array1OfPnt& theArrayOfPnts,
                                                      Select3D_TypeOfSensitivity theSensType,
                                                      Standard_Real& theDepth) Standard_OVERRIDE;
 
index 3726615..9b83721 100644 (file)
 #define BVH_PRIMITIVE_LIMIT 800000
 
 //==================================================
-// function: preBuildBVH
+// 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)
+void StdSelect_BRepSelectionTool::PreBuildBVH (const Handle(SelectMgr_Selection)& theSelection)
 {
   for (theSelection->Init(); theSelection->More(); theSelection->Next())
   {
@@ -196,7 +196,7 @@ void StdSelect_BRepSelectionTool
     anOwner->Set (theSelectableObj);
   }
 
-  preBuildBVH (theSelection);
+  PreBuildBVH (theSelection);
 }
 
 //==================================================
index 4d5e997..289d4ed 100644 (file)
@@ -118,7 +118,10 @@ public:
   //! if<InteriorFlag> =  False  the face  will  be sensitive only on its boundary
   Standard_EXPORT static Standard_Boolean GetSensitiveForFace (const TopoDS_Face& aFace, const Handle(StdSelect_BRepOwner)& anOwner, Select3D_EntitySequence& OutList, const Standard_Boolean AutoTriangulation = Standard_True, const Standard_Integer NbPOnEdge = 9, const Standard_Real MaxiParam = 500, const Standard_Boolean InteriorFlag = Standard_True);
 
-
+  //! 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
+  Standard_EXPORT static void PreBuildBVH (const Handle(SelectMgr_Selection)& theSelection);
 
 
 protected:
@@ -129,12 +132,6 @@ protected:
 
 private:
 
-  
-  //! 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
-  Standard_EXPORT static void preBuildBVH (const Handle(SelectMgr_Selection)& theSelection);
-  
   Standard_EXPORT static void GetEdgeSensitive (const TopoDS_Shape& aShape, const Handle(StdSelect_BRepOwner)& anOwner, const Handle(SelectMgr_Selection)& aSelection, const Standard_Real theDeflection, const Standard_Real theDeflectionAngle, const Standard_Integer NbPOnEdge, const Standard_Real MaximalParameter, Handle(Select3D_SensitiveEntity)& aSensitive);