mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0026195: Visualization - optimize selection algorithms
- initial transformation of triangulation is now applied to selecting frustum; - switched from NCollection_Vec3 to gp collections to avoid conversions and usage of macros; - calculation of frustum was refactored to reduce its build time; - double pixel tolerances for selection were replaced by integer ones; - switched to splitting along the main axis only in SelectMgr BVH selection primitive sets.
This commit is contained in:
@@ -101,7 +101,7 @@ void SelectMgr_BaseFrustum::SetViewport (const Standard_Real theX,
|
||||
// function : SetPixelTolerance
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Real theTol)
|
||||
void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Integer theTol)
|
||||
{
|
||||
myPixelTolerance = theTol;
|
||||
}
|
||||
@@ -130,7 +130,8 @@ void SelectMgr_BaseFrustum::SetBuilder (const Handle(SelectMgr_FrustumBuilder)&
|
||||
// purpose : SAT intersection test between defined volume and
|
||||
// given axis-aligned box
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& /*theBndBox*/,
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const SelectMgr_Vec3& /*theBoxMin*/,
|
||||
const SelectMgr_Vec3& /*theBoxMax*/,
|
||||
Standard_Real& /*theDepth*/)
|
||||
{
|
||||
return Standard_False;
|
||||
@@ -151,12 +152,21 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const SelectMgr_Vec3& /*theBox
|
||||
// function : Overlaps
|
||||
// purpose : Intersection test between defined volume and given point
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt*/,
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt*/,
|
||||
Standard_Real& /*theDepth*/)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : Intersection test between defined volume and given point
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt*/)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : SAT intersection test between defined volume and given
|
||||
@@ -164,7 +174,7 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt*/,
|
||||
// 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)& /*theArrayOfPts*/,
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& /*theArrayOfPnts*/,
|
||||
Select3D_TypeOfSensitivity /*theSensType*/,
|
||||
Standard_Real& /*theDepth*/)
|
||||
{
|
||||
@@ -191,8 +201,8 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/,
|
||||
// function : Overlaps
|
||||
// purpose : Checks if line segment overlaps selecting volume
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/,
|
||||
const gp_Pnt& /*thePt2*/,
|
||||
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt1*/,
|
||||
const gp_Pnt& /*thePnt2*/,
|
||||
Standard_Real& /*theDepth*/)
|
||||
{
|
||||
return Standard_False;
|
||||
@@ -208,9 +218,9 @@ Standard_Real SelectMgr_BaseFrustum::DistToGeometryCenter (const gp_Pnt& /*theCO
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
SelectMgr_Vec3 SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const
|
||||
gp_Pnt SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const
|
||||
{
|
||||
return SelectMgr_Vec3 (RealLast());
|
||||
return gp_Pnt (RealLast(), RealLast(), RealLast());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -16,8 +16,6 @@
|
||||
#ifndef _SelectMgr_BaseFrustum_HeaderFile
|
||||
#define _SelectMgr_BaseFrustum_HeaderFile
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
|
||||
@@ -67,7 +65,7 @@ public:
|
||||
//! @return current camera world view projection transformation state
|
||||
Standard_EXPORT const Graphic3d_WorldViewProjState& WorldViewProjState() const;
|
||||
|
||||
Standard_EXPORT void SetPixelTolerance (const Standard_Real theTol);
|
||||
Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTol);
|
||||
|
||||
Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth,
|
||||
const Standard_Integer theHeight);
|
||||
@@ -97,14 +95,19 @@ public:
|
||||
//! 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; }
|
||||
|
||||
//! IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
//! IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
//! Note that this method does not perform any checks on type of the frustum.
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real /*theScaleFactor*/) { return NULL; }
|
||||
//! and transforms it using the matrix given.
|
||||
//! There are no default parameters, but in case if:
|
||||
//! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
|
||||
//! - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer /*theScaleFactor*/,
|
||||
const gp_Trsf& /*theTrsf*/) { return NULL; }
|
||||
|
||||
//! SAT intersection test between defined volume and given axis-aligned box
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
Standard_Real& theDepth);
|
||||
|
||||
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
|
||||
@@ -114,19 +117,25 @@ public:
|
||||
Standard_Boolean* theInside = NULL);
|
||||
|
||||
//! Intersection test between defined volume and given point
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
|
||||
Standard_Real& theDepth);
|
||||
|
||||
//! Intersection test between defined volume and given point
|
||||
//! Does not perform depth calculation, so this method is defined as
|
||||
//! helper function for inclusion test. Therefore, its implementation
|
||||
//! makes sense only for rectangular frustum with box selection mode activated.
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt);
|
||||
|
||||
//! 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)& theArrayOfPts,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
|
||||
Select3D_TypeOfSensitivity theSensType,
|
||||
Standard_Real& theDepth);
|
||||
|
||||
//! Checks if line segment overlaps selecting frustum
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
|
||||
const gp_Pnt& thePt2,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
Standard_Real& theDepth);
|
||||
|
||||
//! SAT intersection test between defined volume and given triangle. The test may
|
||||
@@ -142,7 +151,7 @@ public:
|
||||
//! screen point and given point theCOG
|
||||
Standard_EXPORT virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG);
|
||||
|
||||
Standard_EXPORT virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const;
|
||||
Standard_EXPORT virtual gp_Pnt 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
|
||||
@@ -152,8 +161,8 @@ public:
|
||||
DEFINE_STANDARD_RTTI(SelectMgr_BaseFrustum, Standard_Transient)
|
||||
|
||||
protected:
|
||||
Standard_Real myPixelTolerance; //!< Pixel tolerance
|
||||
Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic
|
||||
Standard_Integer myPixelTolerance; //!< Pixel tolerance
|
||||
Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic
|
||||
|
||||
Handle(SelectMgr_FrustumBuilder) myBuilder; //!< A tool implementing methods for volume build
|
||||
};
|
||||
|
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <BVH_Box.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <SelectMgr_BaseFrustum.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
@@ -75,39 +77,39 @@ protected:
|
||||
|
||||
//! 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,
|
||||
SelectMgr_Vec3& theNormal);
|
||||
gp_Vec& theNormal);
|
||||
|
||||
//! SAT intersection test between defined volume and given triangle
|
||||
Standard_EXPORT Standard_Boolean hasOverlap (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
const gp_Pnt& thePnt3,
|
||||
SelectMgr_Vec3& theNormal);
|
||||
gp_Vec& 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& theDirect,
|
||||
const gp_XYZ& theDirect,
|
||||
Standard_Boolean* theInside) 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;
|
||||
const gp_XYZ& theAxis) const;
|
||||
|
||||
protected:
|
||||
|
||||
SelectMgr_Vec3 myPlanes[N + 2]; //!< Plane equations
|
||||
SelectMgr_Vec3 myVertices[N * 2]; //!< Vertices coordinates
|
||||
gp_Vec myPlanes[N + 2]; //!< Plane equations
|
||||
gp_Pnt 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
|
||||
gp_Vec myEdgeDirs[6]; //!< Cached edge directions
|
||||
};
|
||||
|
||||
#include <SelectMgr_Frustum.lxx>
|
||||
|
@@ -17,9 +17,6 @@
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <Standard_Assert.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.
|
||||
@@ -27,18 +24,18 @@
|
||||
template <int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
const SelectMgr_Vec3& theDirect,
|
||||
const gp_XYZ& theDirect,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
const Standard_Real aMinB =
|
||||
theDirect.x() * (theDirect.x() < 0.0 ? theBoxMax.x() : theBoxMin.x()) +
|
||||
theDirect.y() * (theDirect.y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) +
|
||||
theDirect.z() * (theDirect.z() < 0.0 ? theBoxMax.z() : theBoxMin.z());
|
||||
theDirect.X() * (theDirect.X() < 0.0 ? theBoxMax.x() : theBoxMin.x()) +
|
||||
theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) +
|
||||
theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMax.z() : theBoxMin.z());
|
||||
|
||||
const Standard_Real aMaxB =
|
||||
theDirect.x() * (theDirect.x() < 0.0 ? theBoxMin.x() : theBoxMax.x()) +
|
||||
theDirect.y() * (theDirect.y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) +
|
||||
theDirect.z() * (theDirect.z() < 0.0 ? theBoxMin.z() : theBoxMax.z());
|
||||
theDirect.X() * (theDirect.X() < 0.0 ? theBoxMin.x() : theBoxMax.x()) +
|
||||
theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) +
|
||||
theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMin.z() : theBoxMax.z());
|
||||
|
||||
Standard_ASSERT_RAISE (aMaxB >= aMinB, "Error! Failed to project box");
|
||||
|
||||
@@ -48,7 +45,7 @@ Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBox
|
||||
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
|
||||
{
|
||||
const Standard_Real aProj = DOT (myVertices[aVertIdx], theDirect);
|
||||
const Standard_Real aProj = myVertices[aVertIdx].XYZ().Dot (theDirect);
|
||||
|
||||
aMinF = Min (aMinF, aProj);
|
||||
aMaxF = Max (aMaxF, aProj);
|
||||
@@ -83,7 +80,7 @@ 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
|
||||
const gp_XYZ& theAxis) const
|
||||
{
|
||||
// frustum projection
|
||||
Standard_Real aMinF = RealLast();
|
||||
@@ -95,21 +92,21 @@ Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const gp_Pnt& thePnt1,
|
||||
|
||||
Standard_Real aTriangleProj;
|
||||
|
||||
aTriangleProj = DOTp (theAxis, thePnt1);
|
||||
aTriangleProj = theAxis.Dot (thePnt1.XYZ());
|
||||
aMinTr = Min (aMinTr, aTriangleProj);
|
||||
aMaxTr = Max (aMaxTr, aTriangleProj);
|
||||
|
||||
aTriangleProj = DOTp (theAxis, thePnt2);
|
||||
aTriangleProj = theAxis.Dot (thePnt2.XYZ());
|
||||
aMinTr = Min (aMinTr, aTriangleProj);
|
||||
aMaxTr = Max (aMaxTr, aTriangleProj);
|
||||
|
||||
aTriangleProj = DOTp (theAxis, thePnt3);
|
||||
aTriangleProj = theAxis.Dot (thePnt3.XYZ());
|
||||
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);
|
||||
const Standard_Real aProj = myVertices[aVertIter].XYZ().Dot (theAxis);
|
||||
|
||||
aMinF = Min (aMinF, aProj);
|
||||
aMaxF = Max (aMaxF, aProj);
|
||||
@@ -152,17 +149,17 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const SelectMgr_Vec3& theMinP
|
||||
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
|
||||
{
|
||||
SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
|
||||
const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
|
||||
|
||||
const Standard_Real aBoxProjMin =
|
||||
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());
|
||||
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 aBoxProjMax =
|
||||
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());
|
||||
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());
|
||||
|
||||
Standard_ASSERT_RAISE (aBoxProjMax >= aBoxProjMin, "Error! Failed to project box");
|
||||
|
||||
@@ -180,13 +177,16 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const SelectMgr_Vec3& theMinP
|
||||
|
||||
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
|
||||
{
|
||||
SelectMgr_Vec3 anEdge1 (aDim == 0, aDim == 1, aDim == 2);
|
||||
|
||||
// the following code performs a speedup of cross-product
|
||||
// of vector with 1.0 at the position aDim and myEdgeDirs[aVolDir]
|
||||
const Standard_Integer aNext = (aDim + 1) % 3;
|
||||
const Standard_Integer aNextNext = (aDim + 2) % 3;
|
||||
for (Standard_Integer aVolDir = 0, aDirectionsNb = myIsOrthographic ? 4 : 6; aVolDir < aDirectionsNb; ++aVolDir)
|
||||
{
|
||||
SelectMgr_Vec3 aDirection (anEdge1.y() * myEdgeDirs[aVolDir].z() - anEdge1.z() * myEdgeDirs[aVolDir].y(),
|
||||
anEdge1.z() * myEdgeDirs[aVolDir].x() - anEdge1.x() * myEdgeDirs[aVolDir].z(),
|
||||
anEdge1.x() * myEdgeDirs[aVolDir].y() - anEdge1.y() * myEdgeDirs[aVolDir].x());
|
||||
gp_XYZ aDirection (DBL_MAX, DBL_MAX, DBL_MAX);
|
||||
aDirection.ChangeData()[aDim] = 0;
|
||||
aDirection.ChangeData()[aNext] = -myEdgeDirs[aVolDir].XYZ().GetData()[aNextNext];
|
||||
aDirection.ChangeData()[aNextNext] = myEdgeDirs[aVolDir].XYZ().GetData()[aNext];
|
||||
|
||||
if (isSeparated (theMinPnt, theMaxPnt, aDirection, theInside))
|
||||
{
|
||||
@@ -209,11 +209,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt)
|
||||
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
|
||||
{
|
||||
const Select3D_Vec3& aPlane = myPlanes[aPlaneIdx];
|
||||
|
||||
const Standard_Real aPointProj = aPlane.x() * thePnt.X() +
|
||||
aPlane.y() * thePnt.Y() +
|
||||
aPlane.z() * thePnt.Z();
|
||||
const Standard_Real aPointProj = myPlanes[aPlaneIdx].XYZ().Dot (thePnt.XYZ());
|
||||
|
||||
if (aPointProj > myMaxVertsProjections[aPlaneIdx]
|
||||
|| aPointProj < myMinVertsProjections[aPlaneIdx])
|
||||
@@ -233,10 +229,8 @@ template <int N>
|
||||
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())
|
||||
const gp_XYZ& aDir = theEndPnt.XYZ() - theStartPnt.XYZ();
|
||||
if (aDir.Modulus() < Precision::Confusion())
|
||||
return Standard_True;
|
||||
|
||||
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
|
||||
@@ -244,10 +238,9 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
|
||||
{
|
||||
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);
|
||||
Standard_Real aProj1 = myPlanes[aPlaneIdx].XYZ().Dot (theStartPnt.XYZ());
|
||||
Standard_Real aProj2 = myPlanes[aPlaneIdx].XYZ().Dot (theEndPnt.XYZ());
|
||||
aMinSegm = Min (aProj1, aProj2);
|
||||
aMaxSegm = Max (aProj1, aProj2);
|
||||
|
||||
@@ -265,12 +258,12 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
|
||||
Standard_Real aMin2 = DBL_MAX, aMax2 = -DBL_MAX;
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = DOT (aDir, myVertices[aVertIdx]);
|
||||
Standard_Real aProjection = aDir.Dot (myVertices[aVertIdx].XYZ());
|
||||
aMax2 = Max (aMax2, aProjection);
|
||||
aMin2 = Min (aMin2, aProjection);
|
||||
}
|
||||
Standard_Real aProj1 = DOTp (aDir, theStartPnt);
|
||||
Standard_Real aProj2 = DOTp (aDir, theEndPnt);
|
||||
Standard_Real aProj1 = aDir.Dot (theStartPnt.XYZ());
|
||||
Standard_Real aProj2 = aDir.Dot (theEndPnt.XYZ());
|
||||
aMin1 = Min (aProj1, aProj2);
|
||||
aMax1 = Max (aProj1, aProj2);
|
||||
if (aMin1 > aMax2
|
||||
@@ -285,18 +278,16 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
|
||||
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());
|
||||
const gp_XYZ aTestDir = aDir.Crossed (myEdgeDirs[aEdgeDirIdx].XYZ());
|
||||
|
||||
Standard_Real Proj1 = DOTp (aTestDir, theStartPnt);
|
||||
Standard_Real Proj2 = DOTp (aTestDir, theEndPnt);
|
||||
Standard_Real Proj1 = aTestDir.Dot (theStartPnt.XYZ());
|
||||
Standard_Real Proj2 = aTestDir.Dot (theEndPnt.XYZ());
|
||||
aMinSegm = Min (Proj1, Proj2);
|
||||
aMaxSegm = Max (Proj1, Proj2);
|
||||
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]);
|
||||
Standard_Real aProjection = aTestDir.Dot (myVertices[aVertIdx].XYZ());
|
||||
aMaxF = Max (aMaxF, aProjection);
|
||||
aMinF = Min (aMinF, aProjection);
|
||||
}
|
||||
@@ -318,26 +309,25 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
|
||||
// =======================================================================
|
||||
template <int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
|
||||
SelectMgr_Vec3& theNormal)
|
||||
gp_Vec& 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);
|
||||
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);
|
||||
const gp_XYZ& aNormal = theNormal.XYZ();
|
||||
Standard_Real aPolygProjection = aNormal.Dot (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]);
|
||||
Standard_Real aProjection = aNormal.Dot (myVertices[aVertIdx].XYZ());
|
||||
aMax = Max (aMax, aProjection);
|
||||
aMin = Min (aMin, aProjection);
|
||||
}
|
||||
@@ -347,17 +337,17 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Integer aPlanesNb = N == 4 ? N + 2 : N + 1;
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < aPlanesNb; ++aPlaneIdx)
|
||||
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
|
||||
{
|
||||
Standard_Real aMaxF = RealFirst();
|
||||
Standard_Real aMinF = RealLast();
|
||||
Standard_Real aMaxPolyg = RealFirst();
|
||||
Standard_Real aMinPolyg = RealLast();
|
||||
SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
|
||||
const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
|
||||
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
|
||||
{
|
||||
Standard_Real aProjection = DOTp (aPlane, theArrayOfPnts->Value (aPntIter));
|
||||
Standard_Real aProjection = aPlane.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
|
||||
aMaxPolyg = Max (aMaxPolyg, aProjection);
|
||||
aMinPolyg = Min (aMinPolyg, aProjection);
|
||||
}
|
||||
@@ -371,30 +361,28 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
|
||||
}
|
||||
|
||||
Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6;
|
||||
for (Standard_Integer aPntsIter = aStartIdx; aPntsIter <= anEndIdx; ++aPntsIter)
|
||||
for (Standard_Integer aPntsIter = 0, aLastIdx = anEndIdx - aStartIdx, aLen = theArrayOfPnts->Length(); aPntsIter <= aLastIdx; ++aPntsIter)
|
||||
{
|
||||
const gp_XYZ aSegmDir = aPntsIter == anEndIdx ? theArrayOfPnts->Value (aStartIdx).XYZ() - theArrayOfPnts->Value (anEndIdx).XYZ()
|
||||
: theArrayOfPnts->Value (aPntsIter + 1).XYZ() - theArrayOfPnts->Value (aPntsIter).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();
|
||||
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());
|
||||
const gp_XYZ aTestDir = aSegmDir.Crossed (myEdgeDirs[aVolDir].XYZ());
|
||||
|
||||
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
|
||||
{
|
||||
Standard_Real aProjection = DOTp (aTestDir, theArrayOfPnts->Value (aPntIter));
|
||||
Standard_Real aProjection = aTestDir.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
|
||||
aMaxPolyg = Max (aMaxPolyg, aProjection);
|
||||
aMinPolyg = Min (aMinPolyg, aProjection);
|
||||
}
|
||||
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]);
|
||||
Standard_Real aProjection = aTestDir.Dot (myVertices[aVertIdx].XYZ());
|
||||
aMaxF = Max (aMaxF, aProjection);
|
||||
aMinF = Min (aMinF, aProjection);
|
||||
}
|
||||
@@ -418,31 +406,27 @@ template <int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
const gp_Pnt& thePnt3,
|
||||
SelectMgr_Vec3& theNormal)
|
||||
gp_Vec& 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 gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
|
||||
thePnt3.XYZ() - thePnt2.XYZ(),
|
||||
thePnt1.XYZ() - thePnt3.XYZ() };
|
||||
|
||||
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
|
||||
{
|
||||
SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
|
||||
const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
|
||||
Standard_Real aTriangleProj;
|
||||
|
||||
aTriangleProj = DOT (aPlane, aPnt1);
|
||||
aTriangleProj = aPlane.Dot (thePnt1.XYZ());
|
||||
Standard_Real aTriangleProjMin = aTriangleProj;
|
||||
Standard_Real aTriangleProjMax = aTriangleProj;
|
||||
|
||||
aTriangleProj = DOT (aPlane, aPnt2);
|
||||
aTriangleProj = aPlane.Dot (thePnt2.XYZ());
|
||||
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
|
||||
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
|
||||
|
||||
aTriangleProj = DOT (aPlane, aPnt3);
|
||||
aTriangleProj = aPlane.Dot (thePnt3.XYZ());
|
||||
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
|
||||
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
|
||||
|
||||
@@ -455,10 +439,8 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
theNormal = aTrEdges[2].Crossed (aTrEdges[0]);
|
||||
if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal.XYZ()))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -468,12 +450,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
|
||||
{
|
||||
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());
|
||||
const gp_XYZ& aTestDirection = myEdgeDirs[aVolDir].XYZ().Crossed (aTrEdges[aTriangleEdgeIdx]);
|
||||
|
||||
if (isSeparated (thePnt1, thePnt2, thePnt3, aTestDirection))
|
||||
{
|
||||
@@ -484,6 +461,3 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
#undef DOT
|
||||
#undef DOTp
|
||||
|
@@ -165,7 +165,7 @@ static NCollection_Vec4<Standard_Real> safePointCast (const gp_Pnt& thePnt)
|
||||
// function : unProject
|
||||
// purpose : Unprojects point from NDC coords to 3d world space
|
||||
//=======================================================================
|
||||
SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
|
||||
gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
|
||||
{
|
||||
Graphic3d_Mat4d aInvView;
|
||||
Graphic3d_Mat4d aInvProj;
|
||||
@@ -173,7 +173,7 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
|
||||
// this case should never happen
|
||||
if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
|
||||
{
|
||||
return SelectMgr_Vec3 (0.0, 0.0, 0.0);
|
||||
return gp_Pnt (0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// use compatible type of point
|
||||
@@ -184,7 +184,7 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
|
||||
|
||||
const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
|
||||
|
||||
return SelectMgr_Vec3 (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
|
||||
return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -193,9 +193,9 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
|
||||
// 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
|
||||
gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX,
|
||||
const Standard_Real& theY,
|
||||
const Standard_Real& theZ) const
|
||||
{
|
||||
Standard_Real aX, anY, aZ;
|
||||
|
||||
|
@@ -70,16 +70,16 @@ public:
|
||||
//! Projects 2d screen point onto view frustum plane:
|
||||
//! theZ = 0 - near plane,
|
||||
//! theZ = 1 - far plane
|
||||
Standard_EXPORT SelectMgr_Vec3 ProjectPntOnViewPlane (const Standard_Real& theX,
|
||||
const Standard_Real& theY,
|
||||
const Standard_Real& theZ) const;
|
||||
Standard_EXPORT gp_Pnt ProjectPntOnViewPlane (const Standard_Real& theX,
|
||||
const Standard_Real& theY,
|
||||
const Standard_Real& theZ) const;
|
||||
|
||||
DEFINE_STANDARD_RTTI(SelectMgr_FrustumBuilder, Standard_Transient)
|
||||
|
||||
private:
|
||||
|
||||
//! Unprojects point from NDC coords to 3d world space
|
||||
SelectMgr_Vec3 unProject (const gp_Pnt& thePnt) const;
|
||||
gp_Pnt unProject (const gp_Pnt& thePnt) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -18,11 +18,6 @@
|
||||
|
||||
#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 :
|
||||
@@ -31,18 +26,15 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
|
||||
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);
|
||||
gp_XYZ anU = theSegPnt2.XYZ() - theSegPnt1.XYZ();
|
||||
gp_XYZ aV = myViewRayDir.XYZ();
|
||||
gp_XYZ aW = theSegPnt1.XYZ() - myNearPickedPnt.XYZ();
|
||||
|
||||
Standard_Real anA = anU.Dot (anU);
|
||||
Standard_Real aB = anU.Dot (aV);
|
||||
Standard_Real aC = aV.Dot (aV);
|
||||
Standard_Real aD = anU.Dot (aW);
|
||||
Standard_Real anE = aV.Dot (aW);
|
||||
Standard_Real aCoef = anA * aC - aB * aB;
|
||||
Standard_Real aSn = aCoef;
|
||||
Standard_Real aTc, aTn, aTd = aCoef;
|
||||
@@ -78,24 +70,22 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
|
||||
}
|
||||
aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
|
||||
|
||||
SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + myViewRayDir * aTc;
|
||||
theDepth = DISTANCE (myNearPickedPnt, aClosestPnt);
|
||||
gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTc;
|
||||
theDepth = myNearPickedPnt.Distance (aClosestPnt);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : segmentPlaneIntersection
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec3& thePlane,
|
||||
void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const gp_Vec& 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);
|
||||
gp_XYZ anU = myViewRayDir.XYZ();
|
||||
gp_XYZ aW = myNearPickedPnt.XYZ() - thePntOnPlane.XYZ();
|
||||
Standard_Real aD = thePlane.Dot (anU);
|
||||
Standard_Real aN = -thePlane.Dot (aW);
|
||||
|
||||
if (Abs (aD) < Precision::Confusion())
|
||||
{
|
||||
@@ -118,36 +108,144 @@ void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec
|
||||
return;
|
||||
}
|
||||
|
||||
SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + anU * aParam;
|
||||
theDepth = DISTANCE (myNearPickedPnt, aClosestPnt);
|
||||
gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + anU * aParam;
|
||||
theDepth = myNearPickedPnt.Distance (aClosestPnt);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// =======================================================================
|
||||
// function : computeFrustum
|
||||
// purpose : Computes base frustum data: its vertices and edge directions
|
||||
// =======================================================================
|
||||
void computeFrustum (const gp_Pnt2d theMinPnt, const gp_Pnt2d& theMaxPnt,
|
||||
const Handle(SelectMgr_FrustumBuilder)& theBuilder,
|
||||
gp_Pnt* theVertices, gp_Vec* theEdges)
|
||||
{
|
||||
// LeftTopNear
|
||||
theVertices[0] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
|
||||
theMaxPnt.Y(),
|
||||
0.0);
|
||||
// LeftTopFar
|
||||
theVertices[1] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
|
||||
theMaxPnt.Y(),
|
||||
1.0);
|
||||
// LeftBottomNear
|
||||
theVertices[2] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
|
||||
theMinPnt.Y(),
|
||||
0.0);
|
||||
// LeftBottomFar
|
||||
theVertices[3] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
|
||||
theMinPnt.Y(),
|
||||
1.0);
|
||||
// RightTopNear
|
||||
theVertices[4] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
|
||||
theMaxPnt.Y(),
|
||||
0.0);
|
||||
// RightTopFar
|
||||
theVertices[5] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
|
||||
theMaxPnt.Y(),
|
||||
1.0);
|
||||
// RightBottomNear
|
||||
theVertices[6] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
|
||||
theMinPnt.Y(),
|
||||
0.0);
|
||||
// RightBottomFar
|
||||
theVertices[7] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
|
||||
theMinPnt.Y(),
|
||||
1.0);
|
||||
|
||||
// Horizontal
|
||||
theEdges[0] = theVertices[4].XYZ() - theVertices[0].XYZ();
|
||||
// Vertical
|
||||
theEdges[1] = theVertices[2].XYZ() - theVertices[0].XYZ();
|
||||
// LeftLower
|
||||
theEdges[2] = theVertices[2].XYZ() - theVertices[3].XYZ();
|
||||
// RightLower
|
||||
theEdges[3] = theVertices[6].XYZ() - theVertices[7].XYZ();
|
||||
// LeftUpper
|
||||
theEdges[4] = theVertices[0].XYZ() - theVertices[1].XYZ();
|
||||
// RightUpper
|
||||
theEdges[5] = theVertices[4].XYZ() - theVertices[5].XYZ();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : computeNormals
|
||||
// purpose : Computes normals to frustum faces
|
||||
// =======================================================================
|
||||
void computeNormals (const SelectMgr_Vec3* theVertices, SelectMgr_Vec3* theNormals)
|
||||
void computeNormals (const gp_Vec* theEdges, gp_Vec* theNormals)
|
||||
{
|
||||
// Top
|
||||
theNormals[0] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
|
||||
theVertices[4] - theVertices[0]);
|
||||
theNormals[0] = theEdges[0].Crossed (theEdges[4]);
|
||||
// Bottom
|
||||
theNormals[1] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[2],
|
||||
theVertices[6] - theVertices[2]);
|
||||
theNormals[1] = theEdges[2].Crossed (theEdges[3]);
|
||||
// Left
|
||||
theNormals[2] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
|
||||
theVertices[2] - theVertices[0]);
|
||||
theNormals[2] = theEdges[4].Crossed (theEdges[1]);
|
||||
// Right
|
||||
theNormals[3] = SelectMgr_Vec3::Cross (theVertices[5] - theVertices[4],
|
||||
theVertices[6] - theVertices[4]);
|
||||
theNormals[3] = theEdges[5].Crossed (theEdges[3]);
|
||||
// Near
|
||||
theNormals[4] = SelectMgr_Vec3::Cross (theVertices[6] - theVertices[4],
|
||||
theVertices[0] - theVertices[4]);
|
||||
theNormals[4] = theEdges[0].Crossed (theEdges[1]);
|
||||
// Far
|
||||
theNormals[5] = SelectMgr_Vec3::Cross (theVertices[7] - theVertices[5],
|
||||
theVertices[1] - theVertices[5]);
|
||||
theNormals[5] = -theNormals[4];
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : cacheVertexProjections
|
||||
// purpose : Caches projection of frustum's vertices onto its plane directions
|
||||
// and {i, j, k}
|
||||
// =======================================================================
|
||||
void SelectMgr_RectangularFrustum::cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum)
|
||||
{
|
||||
if (theFrustum->myIsOrthographic)
|
||||
{
|
||||
// project vertices onto frustum normals
|
||||
// Since orthographic view volume's faces are always a pairwise translation of
|
||||
// one another, only 2 vertices that belong to opposite faces can be projected
|
||||
// to simplify calculations.
|
||||
Standard_Integer aVertIdxs[6] = { LeftTopNear, LeftBottomNear, // opposite planes in height direction
|
||||
LeftBottomNear, RightBottomNear, // opposite planes in width direcion
|
||||
LeftBottomFar, RightBottomNear }; // opposite planes in depth direction
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; aPlaneIdx += 2)
|
||||
{
|
||||
Standard_Real aProj1 = theFrustum->myPlanes[aPlaneIdx].XYZ().Dot (theFrustum->myVertices[aVertIdxs[aPlaneIdx]].XYZ());
|
||||
Standard_Real aProj2 = theFrustum->myPlanes[aPlaneIdx].XYZ().Dot (theFrustum->myVertices[aVertIdxs[aPlaneIdx + 1]].XYZ());
|
||||
theFrustum->myMinVertsProjections[aPlaneIdx] = Min (aProj1, aProj2);
|
||||
theFrustum->myMaxVertsProjections[aPlaneIdx] = Max (aProj1, aProj2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// project all vertices onto frustum normals
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
|
||||
{
|
||||
Standard_Real aMax = -DBL_MAX;
|
||||
Standard_Real aMin = DBL_MAX;
|
||||
const gp_XYZ& aPlane = theFrustum->myPlanes[aPlaneIdx].XYZ();
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = aPlane.Dot (theFrustum->myVertices[aVertIdx].XYZ());
|
||||
aMin = Min (aMin, aProjection);
|
||||
aMax = Max (aMax, aProjection);
|
||||
}
|
||||
theFrustum->myMinVertsProjections[aPlaneIdx] = aMin;
|
||||
theFrustum->myMaxVertsProjections[aPlaneIdx] = aMax;
|
||||
}
|
||||
}
|
||||
|
||||
// project vertices onto {i, j, k}
|
||||
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)
|
||||
{
|
||||
const gp_XYZ& aVert = theFrustum->myVertices[aVertIdx].XYZ();
|
||||
aMax = Max (aVert.GetData()[aDim], aMax);
|
||||
aMin = Min (aVert.GetData()[aDim], aMin);
|
||||
}
|
||||
theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
|
||||
theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,94 +257,24 @@ namespace
|
||||
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;
|
||||
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0);
|
||||
myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
|
||||
myMousePos = thePoint;
|
||||
|
||||
// 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);
|
||||
gp_Pnt2d aMinPnt (thePoint.X() - myPixelTolerance * 0.5,
|
||||
thePoint.Y() - myPixelTolerance * 0.5);
|
||||
gp_Pnt2d aMaxPnt (thePoint.X() + myPixelTolerance * 0.5,
|
||||
thePoint.Y() + myPixelTolerance * 0.5);
|
||||
|
||||
// calculate base frustum characteristics: vertices and edge directions
|
||||
computeFrustum (aMinPnt, aMaxPnt, myBuilder, myVertices, myEdgeDirs);
|
||||
|
||||
// compute frustum normals
|
||||
computeNormals (myVertices, myPlanes);
|
||||
computeNormals (myEdgeDirs, myPlanes);
|
||||
|
||||
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];
|
||||
// compute vertices projections onto frustum normals and
|
||||
// {i, j, k} vectors and store them to corresponding class fields
|
||||
cacheVertexProjections (this);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -262,278 +290,104 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d& theMinPnt,
|
||||
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5,
|
||||
(theMinPnt.Y() + theMaxPnt.Y()) * 0.5,
|
||||
1.0);
|
||||
myViewRayDir = myFarPickedPnt - myNearPickedPnt;
|
||||
myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
|
||||
|
||||
// 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);
|
||||
// calculate base frustum characteristics: vertices and edge directions
|
||||
computeFrustum (theMinPnt, theMaxPnt, myBuilder, myVertices, myEdgeDirs);
|
||||
|
||||
// compute frustum normals
|
||||
computeNormals (myVertices, myPlanes);
|
||||
computeNormals (myEdgeDirs, myPlanes);
|
||||
|
||||
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];
|
||||
// compute vertices projections onto frustum normals and
|
||||
// {i, j, k} vectors and store them to corresponding class fields
|
||||
cacheVertexProjections (this);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// 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]);
|
||||
|
||||
// compute frustum normals
|
||||
computeNormals (aRes->myVertices, aRes->myPlanes);
|
||||
|
||||
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 : Scale
|
||||
// purpose : IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
// function : ScaleAndTransform
|
||||
// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
// Note that this method does not perform any checks on type of the frustum.
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
// and transforms it using the matrix given.
|
||||
// There are no default parameters, but in case if:
|
||||
// - transformation only is needed: @theScaleFactor must be initialized
|
||||
// as any negative value;
|
||||
// - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
// =======================================================================
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Scale (const Standard_Real theScaleFactor)
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::ScaleAndTransform (const Standard_Integer theScaleFactor,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
|
||||
Standard_ASSERT_RAISE (theScaleFactor > 0,
|
||||
"Error! Pixel tolerance for selection should be greater than zero");
|
||||
|
||||
aRes->myNearPickedPnt = myNearPickedPnt;
|
||||
aRes->myFarPickedPnt = myFarPickedPnt;
|
||||
aRes->myViewRayDir = myViewRayDir;
|
||||
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
|
||||
const Standard_Boolean isToScale = theScaleFactor != 1;
|
||||
const Standard_Boolean isToTrsf = theTrsf.Form() != gp_Identity;
|
||||
|
||||
if (!isToScale && !isToTrsf)
|
||||
return aRes;
|
||||
|
||||
aRes->myIsOrthographic = myIsOrthographic;
|
||||
SelectMgr_RectangularFrustum* aRef = this;
|
||||
|
||||
if (isToScale)
|
||||
{
|
||||
aRes->myNearPickedPnt = myNearPickedPnt;
|
||||
aRes->myFarPickedPnt = myFarPickedPnt;
|
||||
aRes->myViewRayDir = myViewRayDir;
|
||||
|
||||
const gp_Pnt2d aMinPnt (myMousePos.X() - theScaleFactor * 0.5,
|
||||
myMousePos.Y() - theScaleFactor * 0.5);
|
||||
const gp_Pnt2d aMaxPnt (myMousePos.X() + theScaleFactor * 0.5,
|
||||
myMousePos.Y() + theScaleFactor * 0.5);
|
||||
|
||||
// recompute base frustum characteristics from scratch
|
||||
computeFrustum (aMinPnt, aMaxPnt, myBuilder, aRes->myVertices, aRes->myEdgeDirs);
|
||||
|
||||
aRef = aRes;
|
||||
}
|
||||
|
||||
if (isToTrsf)
|
||||
{
|
||||
aRes->myNearPickedPnt = aRef->myNearPickedPnt.Transformed (theTrsf);
|
||||
aRes->myFarPickedPnt = aRef->myFarPickedPnt.Transformed (theTrsf);
|
||||
aRes->myViewRayDir = aRes->myFarPickedPnt.XYZ() - aRes->myNearPickedPnt.XYZ();
|
||||
|
||||
// LeftTopNear
|
||||
aRes->myVertices[0] = aRef->myVertices[0].Transformed (theTrsf);
|
||||
// LeftTopFar
|
||||
aRes->myVertices[1] = aRef->myVertices[1].Transformed (theTrsf);
|
||||
// LeftBottomNear
|
||||
aRes->myVertices[2] = aRef->myVertices[2].Transformed (theTrsf);
|
||||
// LeftBottomFar
|
||||
aRes->myVertices[3] = aRef->myVertices[3].Transformed (theTrsf);
|
||||
// RightTopNear
|
||||
aRes->myVertices[4] = aRef->myVertices[4].Transformed (theTrsf);
|
||||
// RightTopFar
|
||||
aRes->myVertices[5] = aRef->myVertices[5].Transformed (theTrsf);
|
||||
// RightBottomNear
|
||||
aRes->myVertices[6] = aRef->myVertices[6].Transformed (theTrsf);
|
||||
// RightBottomFar
|
||||
aRes->myVertices[7] = aRef->myVertices[7].Transformed (theTrsf);
|
||||
|
||||
// Horizontal
|
||||
aRes->myEdgeDirs[0] = aRes->myVertices[4].XYZ() - aRes->myVertices[0].XYZ();
|
||||
// Vertical
|
||||
aRes->myEdgeDirs[1] = aRes->myVertices[2].XYZ() - aRes->myVertices[0].XYZ();
|
||||
// LeftLower
|
||||
aRes->myEdgeDirs[2] = aRes->myVertices[2].XYZ() - aRes->myVertices[3].XYZ();
|
||||
// RightLower
|
||||
aRes->myEdgeDirs[3] = aRes->myVertices[6].XYZ() - aRes->myVertices[7].XYZ();
|
||||
// LeftUpper
|
||||
aRes->myEdgeDirs[4] = aRes->myVertices[0].XYZ() - aRes->myVertices[1].XYZ();
|
||||
// RightUpper
|
||||
aRes->myEdgeDirs[5] = aRes->myVertices[4].XYZ() - aRes->myVertices[5].XYZ();
|
||||
}
|
||||
|
||||
// LeftTopNear
|
||||
aRes->myVertices[0] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// LeftTopFar
|
||||
aRes->myVertices[1] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// LeftBottomNear
|
||||
aRes->myVertices[2] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// LeftBottomFar
|
||||
aRes->myVertices[3] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// RightTopNear
|
||||
aRes->myVertices[4] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// RightTopFar
|
||||
aRes->myVertices[5] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() + theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// RightBottomNear
|
||||
aRes->myVertices[6] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
0.0);
|
||||
// RightBottomFar
|
||||
aRes->myVertices[7] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
|
||||
myMousePos.Y() - theScaleFactor / 2.0,
|
||||
1.0);
|
||||
// compute frustum normals
|
||||
computeNormals (aRes->myVertices, aRes->myPlanes);
|
||||
computeNormals (aRes->myEdgeDirs, aRes->myPlanes);
|
||||
|
||||
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];
|
||||
cacheVertexProjections (aRes);
|
||||
|
||||
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
|
||||
}
|
||||
@@ -556,20 +410,19 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const SelectMgr_Vec3& t
|
||||
// purpose : SAT intersection test between defined volume and
|
||||
// given axis-aligned box
|
||||
// =======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
Standard_Real& theDepth)
|
||||
{
|
||||
const SelectMgr_Vec3& aMinPnt = theBox.CornerMin();
|
||||
const SelectMgr_Vec3& aMaxPnt = theBox.CornerMax();
|
||||
if (!hasOverlap (aMinPnt, aMaxPnt))
|
||||
if (!hasOverlap (theBoxMin, theBoxMax))
|
||||
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());
|
||||
gp_Pnt aNearestPnt (RealLast(), RealLast(), RealLast());
|
||||
aNearestPnt.SetX (Max (Min (myNearPickedPnt.X(), theBoxMax.x()), theBoxMin.x()));
|
||||
aNearestPnt.SetY (Max (Min (myNearPickedPnt.Y(), theBoxMax.y()), theBoxMin.y()));
|
||||
aNearestPnt.SetZ (Max (Min (myNearPickedPnt.Z(), theBoxMax.z()), theBoxMin.z()));
|
||||
|
||||
theDepth = DISTANCE (aNearestPnt, myNearPickedPnt);
|
||||
theDepth = aNearestPnt.Distance (myNearPickedPnt);
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -584,15 +437,24 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt,
|
||||
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));
|
||||
gp_XYZ aV = thePnt.XYZ() - myNearPickedPnt.XYZ();
|
||||
gp_Pnt aDetectedPnt =
|
||||
myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * (aV.Dot (myViewRayDir.XYZ()) / myViewRayDir.Dot (myViewRayDir));
|
||||
|
||||
theDepth = DISTANCE (aDetectedPnt, myNearPickedPnt);
|
||||
theDepth = aDetectedPnt.Distance (myNearPickedPnt);
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : Intersection test between defined volume and given point
|
||||
// =======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt)
|
||||
{
|
||||
return hasOverlap (thePnt);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : Checks if line segment overlaps selecting frustum
|
||||
@@ -647,7 +509,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HAr
|
||||
}
|
||||
else if (theSensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
SelectMgr_Vec3 aPolyNorm (RealLast());
|
||||
gp_Vec aPolyNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
|
||||
if (!hasOverlap (theArrayOfPnts, aPolyNorm))
|
||||
return Standard_False;
|
||||
|
||||
@@ -683,21 +545,20 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
|
||||
}
|
||||
else if (theSensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
SelectMgr_Vec3 aTriangleNormal (RealLast());
|
||||
gp_Vec aTriangleNormal (gp_XYZ (RealLast(), RealLast(), 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()) };
|
||||
gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
|
||||
thePnt3.XYZ() - thePnt2.XYZ(),
|
||||
thePnt1.XYZ() - thePnt3.XYZ() };
|
||||
|
||||
Standard_Real anAlpha = DOT (aTriangleNormal, myViewRayDir);
|
||||
Standard_Real anAlpha = aTriangleNormal.Dot (myViewRayDir);
|
||||
if (Abs (anAlpha) < gp::Resolution())
|
||||
{
|
||||
// handle degenerated triangles: in this case, there is no possible way to detect overlap correctly.
|
||||
if (aTriangleNormal.SquareModulus() < gp::Resolution())
|
||||
if (aTriangleNormal.SquareMagnitude() < gp::Resolution())
|
||||
{
|
||||
theDepth = std::numeric_limits<Standard_Real>::max();
|
||||
return Standard_False;
|
||||
@@ -705,44 +566,38 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
|
||||
|
||||
// handle the case when triangle normal and selecting frustum direction are orthogonal: for this case, overlap
|
||||
// is detected correctly, and distance to triangle's plane can be measured as distance to its arbitrary vertex.
|
||||
const SelectMgr_Vec3 aDiff = myNearPickedPnt - aPnt1;
|
||||
theDepth = DOT (aTriangleNormal, aDiff);
|
||||
const gp_XYZ aDiff = myNearPickedPnt.XYZ() - thePnt1.XYZ();
|
||||
theDepth = aTriangleNormal.Dot (aDiff);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / anAlpha);
|
||||
gp_XYZ anEdge = (thePnt1.XYZ() - myNearPickedPnt.XYZ()) * (1.0 / anAlpha);
|
||||
|
||||
Standard_Real aTime = DOT (aTriangleNormal, anEdge);
|
||||
Standard_Real aTime = aTriangleNormal.Dot (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());
|
||||
gp_XYZ aVec = myViewRayDir.XYZ().Crossed (anEdge);
|
||||
|
||||
Standard_Real anU = DOT (aVec, aTrEdges[2]);
|
||||
Standard_Real aV = DOT (aVec, aTrEdges[0]);
|
||||
Standard_Real anU = aVec.Dot (aTrEdges[2]);
|
||||
Standard_Real aV = aVec.Dot (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);
|
||||
gp_Pnt aDetectedPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
|
||||
theDepth = myNearPickedPnt.Distance (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;
|
||||
gp_Pnt aPtOnPlane = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * 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()));
|
||||
gp_XYZ aW = aPtOnPlane.XYZ() - aPnts[anEdgeIdx].XYZ();
|
||||
Standard_Real aCoef = aTrEdges[anEdgeIdx].Dot (aW) / aTrEdges[anEdgeIdx].Dot (aTrEdges[anEdgeIdx]);
|
||||
Standard_Real aDist = aPtOnPlane.Distance (aPnts[anEdgeIdx].XYZ() + aCoef * aTrEdges[anEdgeIdx]);
|
||||
if (aMinDist > aDist)
|
||||
{
|
||||
aMinDist = aDist;
|
||||
@@ -762,8 +617,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
|
||||
// =======================================================================
|
||||
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);
|
||||
return theCOG.Distance (myNearPickedPnt);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -771,9 +625,9 @@ Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt&
|
||||
// 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
|
||||
gp_Pnt SelectMgr_RectangularFrustum::DetectedPoint (const Standard_Real theDepth) const
|
||||
{
|
||||
return myNearPickedPnt + myViewRayDir.Normalized() * theDepth;
|
||||
return myNearPickedPnt.XYZ() + myViewRayDir.Normalized().XYZ() * theDepth;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -800,8 +654,9 @@ Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_Sequen
|
||||
|
||||
const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
|
||||
|
||||
Standard_Real aDotProduct = DOTp (myViewRayDir, aPlaneDirXYZ);
|
||||
Standard_Real aDistance = - (DOTp (myNearPickedPnt, aPlaneDirXYZ) + aPlaneD);
|
||||
Standard_Real aDotProduct = myViewRayDir.XYZ().Dot (aPlaneDirXYZ);
|
||||
Standard_Real aDistance = - myNearPickedPnt.XYZ().Dot (aPlaneDirXYZ) +
|
||||
aPlaneD;
|
||||
|
||||
// check whether the pick line is parallel to clip plane
|
||||
if (Abs (aDotProduct) < Precision::Angular())
|
||||
@@ -820,8 +675,8 @@ Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_Sequen
|
||||
continue;
|
||||
}
|
||||
|
||||
const SelectMgr_Vec3 anIntersectionPt = myNearPickedPnt + myViewRayDir * aParam;
|
||||
const Standard_Real aDistToPln = DISTANCE (anIntersectionPt, myNearPickedPnt);
|
||||
const gp_Pnt anIntersectionPt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aParam;
|
||||
const Standard_Real aDistToPln = anIntersectionPt.Distance (myNearPickedPnt);
|
||||
|
||||
// change depth limits for case of opposite and directed planes
|
||||
if (aDotProduct < 0.0)
|
||||
|
@@ -42,18 +42,22 @@ public:
|
||||
Standard_EXPORT 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
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
|
||||
//! IMPORTANT: Makes sense only for frustum built on a single point!
|
||||
//! IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
//! Note that this method does not perform any checks on type of the frustum.
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real theScaleFactor) Standard_OVERRIDE;
|
||||
//! and transforms it using the matrix given.
|
||||
//! There are no default parameters, but in case if:
|
||||
//! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
|
||||
//! - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScaleFactor,
|
||||
const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
|
||||
|
||||
// SAT Tests for different objects
|
||||
|
||||
//! SAT intersection test between defined volume and given axis-aligned box
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
|
||||
@@ -66,6 +70,9 @@ public:
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Intersection test between defined volume and given point
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt) 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
|
||||
@@ -92,29 +99,45 @@ public:
|
||||
Standard_EXPORT virtual 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
|
||||
Standard_EXPORT virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
|
||||
Standard_EXPORT virtual gp_Pnt 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 Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
|
||||
const Standard_Real theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! A set of helper functions that return rectangular selecting frustum data
|
||||
inline const gp_Pnt* GetVertices() const { return myVertices; }
|
||||
|
||||
inline gp_Pnt GetNearPnt() const { return myNearPickedPnt; }
|
||||
|
||||
inline gp_Pnt GetFarPnt() const { return myFarPickedPnt; }
|
||||
protected:
|
||||
|
||||
Standard_EXPORT void segmentSegmentDistance (const gp_Pnt& theSegPnt1,
|
||||
const gp_Pnt& theSegPnt2,
|
||||
Standard_Real& theDepth);
|
||||
|
||||
Standard_EXPORT void segmentPlaneIntersection (const SelectMgr_Vec3& thePlane,
|
||||
Standard_EXPORT void segmentPlaneIntersection (const gp_Vec& 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;
|
||||
gp_Pnt2d myMousePos; //!< Mouse coordinates
|
||||
void cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum);
|
||||
|
||||
private:
|
||||
enum { LeftTopNear, LeftTopFar,
|
||||
LeftBottomNear, LeftBottomFar,
|
||||
RightTopNear, RightTopFar,
|
||||
RightBottomNear, RightBottomFar };
|
||||
|
||||
private:
|
||||
|
||||
gp_Pnt myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
|
||||
gp_Pnt myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
|
||||
gp_Vec myViewRayDir;
|
||||
gp_Pnt2d myMousePos; //!< Mouse coordinates
|
||||
};
|
||||
|
||||
#endif // _SelectMgr_RectangularFrustum_HeaderFile
|
||||
|
@@ -25,7 +25,7 @@
|
||||
//=======================================================================
|
||||
SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet()
|
||||
{
|
||||
myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 32> (1, 32, Standard_False);
|
||||
myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (1, 32, Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -109,15 +109,7 @@ Standard_Real SelectMgr_SelectableObjectSet::Center (const Standard_Integer theI
|
||||
void SelectMgr_SelectableObjectSet::Swap (const Standard_Integer theIndex1,
|
||||
const Standard_Integer theIndex2)
|
||||
{
|
||||
const Standard_Integer aIndex1 = theIndex1 + 1;
|
||||
const Standard_Integer aIndex2 = theIndex2 + 1;
|
||||
|
||||
Handle(SelectMgr_SelectableObject) anObject1 = myObjects.FindKey (aIndex1);
|
||||
Handle(SelectMgr_SelectableObject) anObject2 = myObjects.FindKey (aIndex2);
|
||||
|
||||
myObjects.Substitute (aIndex1, EMPTY_OBJ);
|
||||
myObjects.Substitute (aIndex2, anObject1);
|
||||
myObjects.Substitute (aIndex1, anObject2);
|
||||
myObjects.Swap (theIndex1 + 1, theIndex2 + 1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -29,8 +29,6 @@
|
||||
//! binned BVH builder is used with 32 bins and 1 element per leaf.
|
||||
class SelectMgr_SelectableObjectSet : public BVH_PrimitiveSet<Standard_Real, 3>
|
||||
{
|
||||
Handle(SelectMgr_SelectableObject) EMPTY_OBJ;
|
||||
|
||||
public:
|
||||
|
||||
//! Creates new empty objects set and initializes BVH tree
|
||||
|
@@ -32,10 +32,19 @@ SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boo
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Transform
|
||||
// purpose : Returns a copy of active frustum transformed according to the matrix given
|
||||
// function : ScaleAndTransform
|
||||
// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
// Note that this method does not perform any checks on type of the frustum.
|
||||
//
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
// and transforms it using the matrix given.
|
||||
// There are no default parameters, but in case if:
|
||||
// - transformation only is needed: @theScaleFactor must be initialized
|
||||
// as any negative value;
|
||||
// - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
//=======================================================================
|
||||
SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (const gp_Trsf& theTrsf)
|
||||
SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
SelectMgr_SelectingVolumeManager aMgr (Standard_False);
|
||||
|
||||
@@ -44,31 +53,13 @@ SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (co
|
||||
|
||||
aMgr.myActiveSelectionType = myActiveSelectionType;
|
||||
|
||||
aMgr.mySelectingVolumes[myActiveSelectionType / 2] = mySelectingVolumes[myActiveSelectionType / 2]->Transform (theTrsf);
|
||||
aMgr.mySelectingVolumes[myActiveSelectionType / 2]
|
||||
= mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
|
||||
aMgr.myToAllowOverlap = myToAllowOverlap;
|
||||
|
||||
return aMgr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Scale
|
||||
// purpose : IMPORTANT: Makes sense only for point selection!
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
//=======================================================================
|
||||
SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Scale (const Standard_Real theScaleFactor)
|
||||
{
|
||||
if (myActiveSelectionType != Point)
|
||||
return SelectMgr_SelectingVolumeManager (Standard_False);
|
||||
|
||||
SelectMgr_SelectingVolumeManager aMgr (Standard_False);
|
||||
|
||||
aMgr.myActiveSelectionType = Point;
|
||||
|
||||
aMgr.mySelectingVolumes[Point] = mySelectingVolumes[Point]->Scale (theScaleFactor);
|
||||
|
||||
return aMgr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetActiveSelectionType
|
||||
// purpose :
|
||||
@@ -178,7 +169,7 @@ void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer the
|
||||
// function : SetPixelTolerance
|
||||
// purpose : Updates pixel tolerance in all selecting volumes
|
||||
//=======================================================================
|
||||
void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Real theTolerance)
|
||||
void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
|
||||
{
|
||||
for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
|
||||
{
|
||||
@@ -229,13 +220,14 @@ void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1
|
||||
// purpose : SAT intersection test between defined volume and
|
||||
// given axis-aligned box
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
Standard_Real& theDepth)
|
||||
{
|
||||
if (myActiveSelectionType == Unknown)
|
||||
return Standard_False;
|
||||
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBndBox, theDepth);
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -256,16 +248,28 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec
|
||||
// function : Overlaps
|
||||
// purpose : Intersection test between defined volume and given point
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt,
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
|
||||
Standard_Real& theDepth)
|
||||
{
|
||||
if (myActiveSelectionType == Unknown)
|
||||
return Standard_False;
|
||||
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt,
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
|
||||
theDepth);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : Intersection test between defined volume and given point
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt)
|
||||
{
|
||||
if (myActiveSelectionType == Unknown)
|
||||
return Standard_False;
|
||||
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Overlaps
|
||||
// purpose : SAT intersection test between defined volume and given
|
||||
@@ -273,14 +277,14 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt
|
||||
// may be considered of interior part or boundary line defined
|
||||
// by segments depending on given sensitivity type
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
|
||||
Standard_Integer theSensType,
|
||||
Standard_Real& theDepth)
|
||||
{
|
||||
if (myActiveSelectionType == Unknown)
|
||||
return Standard_False;
|
||||
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPts,
|
||||
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
|
||||
(Select3D_TypeOfSensitivity)theSensType,
|
||||
theDepth);
|
||||
}
|
||||
@@ -341,10 +345,10 @@ Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_P
|
||||
// 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
|
||||
gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
|
||||
{
|
||||
if (myActiveSelectionType != Point)
|
||||
return NCollection_Vec3<Standard_Real> (RealLast());
|
||||
return gp_Pnt (RealLast(), RealLast(), RealLast());
|
||||
|
||||
return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
|
||||
}
|
||||
@@ -382,3 +386,45 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
|
||||
{
|
||||
return myActiveSelectionType != Box || myToAllowOverlap;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetVertices
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
|
||||
{
|
||||
if (myActiveSelectionType == Polyline)
|
||||
return NULL;
|
||||
|
||||
const SelectMgr_RectangularFrustum* aFr =
|
||||
reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
|
||||
return aFr->GetVertices();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetNearPnt
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPnt() const
|
||||
{
|
||||
if (myActiveSelectionType == Polyline)
|
||||
return gp_Pnt();
|
||||
|
||||
const SelectMgr_RectangularFrustum* aFr =
|
||||
reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
|
||||
return aFr->GetNearPnt();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetFarPnt
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPnt() const
|
||||
{
|
||||
if (myActiveSelectionType == Polyline)
|
||||
return gp_Pnt();
|
||||
|
||||
const SelectMgr_RectangularFrustum* aFr =
|
||||
reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
|
||||
return aFr->GetFarPnt();
|
||||
}
|
||||
|
@@ -38,12 +38,16 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
//! IMPORTANT: Makes sense only for point selection!
|
||||
//! IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
//! Note that this method does not perform any checks on type of the frustum.
|
||||
//!
|
||||
//! Returns a copy of the frustum resized according to the scale factor given
|
||||
Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Scale (const Standard_Real theScaleFactor);
|
||||
//! and transforms it using the matrix given.
|
||||
//! There are no default parameters, but in case if:
|
||||
//! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
|
||||
//! - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
Standard_EXPORT virtual SelectMgr_SelectingVolumeManager ScaleAndTransform (const Standard_Integer theScaleFactor,
|
||||
const gp_Trsf& theTrsf);
|
||||
|
||||
Standard_EXPORT virtual Standard_Integer GetActiveSelectionType() const Standard_OVERRIDE;
|
||||
|
||||
@@ -74,7 +78,7 @@ public:
|
||||
const Standard_Real theHeight);
|
||||
|
||||
//! Updates pixel tolerance in all selecting volumes
|
||||
Standard_EXPORT void SetPixelTolerance (const Standard_Real theTolerance);
|
||||
Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
|
||||
|
||||
//! Updates window size in all selecting volumes
|
||||
Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight);
|
||||
@@ -92,7 +96,8 @@ public:
|
||||
|
||||
|
||||
//! SAT intersection test between defined volume and given axis-aligned box
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
|
||||
const SelectMgr_Vec3& theBoxMax,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
|
||||
@@ -102,9 +107,12 @@ public:
|
||||
Standard_Boolean* theInside = NULL) Standard_OVERRIDE;
|
||||
|
||||
//! Intersection test between defined volume and given point
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Intersection test between defined volume and given point
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt) 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
|
||||
@@ -113,16 +121,16 @@ public:
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Checks if line segment overlaps selecting frustum
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
|
||||
const gp_Pnt& thePt2,
|
||||
Standard_EXPORT virtual 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
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
|
||||
const gp_Pnt& thePt2,
|
||||
const gp_Pnt& thePt3,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
const gp_Pnt& thePnt3,
|
||||
Standard_Integer theSensType,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
@@ -133,7 +141,7 @@ public:
|
||||
|
||||
//! 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;
|
||||
Standard_EXPORT virtual gp_Pnt 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
|
||||
@@ -147,6 +155,13 @@ public:
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean IsOverlapAllowed() const Standard_OVERRIDE;
|
||||
|
||||
//! A set of helper functions that return rectangular selecting frustum data
|
||||
Standard_EXPORT const gp_Pnt* GetVertices() const;
|
||||
|
||||
Standard_EXPORT gp_Pnt GetNearPnt() const;
|
||||
|
||||
Standard_EXPORT gp_Pnt GetFarPnt() const;
|
||||
|
||||
private:
|
||||
enum { Frustum, FrustumSet, VolumeTypesNb }; //!< Defines the amount of available selecting volumes
|
||||
|
||||
|
@@ -27,7 +27,7 @@ SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx)
|
||||
: myMode (theModeIdx),
|
||||
mySelectionState (SelectMgr_SOS_Unknown),
|
||||
myBVHUpdateStatus (SelectMgr_TBU_None),
|
||||
mySensFactor (2.0)
|
||||
mySensFactor (2)
|
||||
{}
|
||||
|
||||
SelectMgr_Selection::~SelectMgr_Selection()
|
||||
@@ -46,7 +46,7 @@ void SelectMgr_Selection::Destroy()
|
||||
Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anEntityIdx);
|
||||
anEntity->BaseSensitive()->Set (NULL);
|
||||
}
|
||||
mySensFactor = 2.0;
|
||||
mySensFactor = 2;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
@@ -132,7 +132,7 @@ void SelectMgr_Selection::SetSelectionState (const SelectMgr_StateOfSelection th
|
||||
// function: Sensitivity
|
||||
// purpose : Returns sensitivity of the selection
|
||||
//==================================================
|
||||
Standard_Real SelectMgr_Selection::Sensitivity() const
|
||||
Standard_Integer SelectMgr_Selection::Sensitivity() const
|
||||
{
|
||||
return mySensFactor;
|
||||
}
|
||||
|
@@ -130,7 +130,7 @@ public:
|
||||
Standard_EXPORT void SetSelectionState (const SelectMgr_StateOfSelection theState) const;
|
||||
|
||||
//! Returns sensitivity of the selection
|
||||
Standard_EXPORT Standard_Real Sensitivity() const;
|
||||
Standard_EXPORT Standard_Integer Sensitivity() const;
|
||||
|
||||
DEFINE_STANDARD_RTTI (SelectMgr_Selection, MMgt_TShared)
|
||||
|
||||
@@ -147,7 +147,7 @@ private:
|
||||
SelectMgr_TypeOfUpdate myUpdateStatus;
|
||||
mutable SelectMgr_StateOfSelection mySelectionState;
|
||||
mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus;
|
||||
Standard_Real mySensFactor;
|
||||
Standard_Integer mySensFactor;
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared)
|
||||
|
@@ -122,12 +122,7 @@ Standard_Real SelectMgr_SensitiveEntitySet::Center (const Standard_Integer theIn
|
||||
void SelectMgr_SensitiveEntitySet::Swap (const Standard_Integer theIndex1,
|
||||
const Standard_Integer theIndex2)
|
||||
{
|
||||
const Handle(SelectMgr_SensitiveEntity) anEntity1 = GetSensitiveById (theIndex1);
|
||||
const Handle(SelectMgr_SensitiveEntity) anEntity2 = GetSensitiveById (theIndex2);
|
||||
|
||||
mySensitives.Substitute (theIndex1 + 1, EMPTY_ENT);
|
||||
mySensitives.Substitute (theIndex2 + 1, anEntity1);
|
||||
mySensitives.Substitute (theIndex1 + 1, anEntity2);
|
||||
mySensitives.Swap (theIndex1 + 1, theIndex2 + 1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -33,8 +33,6 @@ typedef NCollection_IndexedMap<Handle(SelectMgr_SensitiveEntity)> SelectMgr_Inde
|
||||
//! the performance of searching for overlap among sensitives of one selectable object
|
||||
class SelectMgr_SensitiveEntitySet : public BVH_PrimitiveSet<Standard_Real, 3>
|
||||
{
|
||||
Handle(SelectMgr_SensitiveEntity) EMPTY_ENT;
|
||||
|
||||
public:
|
||||
|
||||
Standard_EXPORT SelectMgr_SensitiveEntitySet();
|
||||
|
@@ -15,10 +15,6 @@
|
||||
|
||||
#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();
|
||||
@@ -26,23 +22,55 @@ SelectMgr_TriangularFrustum::~SelectMgr_TriangularFrustum()
|
||||
|
||||
namespace
|
||||
{
|
||||
void computeFrustumNormals (const SelectMgr_Vec3* theVertices, SelectMgr_Vec3* theNormals)
|
||||
void computeFrustumNormals (const gp_Vec* theEdges, gp_Vec* theNormals)
|
||||
{
|
||||
// V0V1
|
||||
theNormals[0] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0],
|
||||
theVertices[4] - theVertices[0]);
|
||||
theNormals[0] = theEdges[0].Crossed (theEdges[1]);
|
||||
// V1V2
|
||||
theNormals[1] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[1],
|
||||
theVertices[5] - theVertices[1]);
|
||||
theNormals[1] = theEdges[1].Crossed (theEdges[2]);
|
||||
// V0V2
|
||||
theNormals[2] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0],
|
||||
theVertices[5] - theVertices[0]);
|
||||
theNormals[2] = theEdges[0].Crossed (theEdges[2]);
|
||||
// Near
|
||||
theNormals[3] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
|
||||
theVertices[2] - theVertices[0]);
|
||||
theNormals[3] = theEdges[3].Crossed (theEdges[5]);
|
||||
// Far
|
||||
theNormals[4] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[3],
|
||||
theVertices[5] - theVertices[3]);
|
||||
theNormals[4] = -theNormals[3];
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : cacheVertexProjections
|
||||
// purpose : Caches projection of frustum's vertices onto its plane directions
|
||||
// and {i, j, k}
|
||||
// =======================================================================
|
||||
void SelectMgr_TriangularFrustum::cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum)
|
||||
{
|
||||
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++aPlaneIdx)
|
||||
{
|
||||
Standard_Real aMax = -DBL_MAX;
|
||||
Standard_Real aMin = DBL_MAX;
|
||||
const gp_XYZ& aPlane = theFrustum->myPlanes[aPlaneIdx].XYZ();
|
||||
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
|
||||
{
|
||||
Standard_Real aProjection = aPlane.Dot (theFrustum->myVertices[aVertIdx].XYZ());
|
||||
aMax = Max (aMax, aProjection);
|
||||
aMin = Min (aMin, aProjection);
|
||||
}
|
||||
theFrustum->myMaxVertsProjections[aPlaneIdx] = aMax;
|
||||
theFrustum->myMinVertsProjections[aPlaneIdx] = aMin;
|
||||
}
|
||||
|
||||
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 = theFrustum->myVertices[aVertIdx].XYZ().GetData()[aDim];
|
||||
aMax = Max (aMax, aProjection);
|
||||
aMin = Min (aMin, aProjection);
|
||||
}
|
||||
theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
|
||||
theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,131 +97,71 @@ void SelectMgr_TriangularFrustum::Build (const gp_Pnt2d& theP1,
|
||||
// V2_Far
|
||||
myVertices[5] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 1.0);
|
||||
|
||||
computeFrustumNormals (myVertices, myPlanes);
|
||||
|
||||
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];
|
||||
myEdgeDirs[0] = myVertices[0].XYZ() - myVertices[3].XYZ();
|
||||
// V1_Near - V1_Far
|
||||
myEdgeDirs[1] = myVertices[1] - myVertices[4];
|
||||
myEdgeDirs[1] = myVertices[1].XYZ() - myVertices[4].XYZ();
|
||||
// V2_Near - V1_Far
|
||||
myEdgeDirs[2] = myVertices[2] - myVertices[5];
|
||||
myEdgeDirs[2] = myVertices[2].XYZ() - myVertices[5].XYZ();
|
||||
// V1_Near - V0_Near
|
||||
myEdgeDirs[3] = myVertices[1] - myVertices[0];
|
||||
myEdgeDirs[3] = myVertices[1].XYZ() - myVertices[0].XYZ();
|
||||
// V2_Near - V1_Near
|
||||
myEdgeDirs[4] = myVertices[2] - myVertices[1];
|
||||
myEdgeDirs[4] = myVertices[2].XYZ() - myVertices[1].XYZ();
|
||||
// V1_Near - V0_Near
|
||||
myEdgeDirs[5] = myVertices[2] - myVertices[0];
|
||||
myEdgeDirs[5] = myVertices[2].XYZ() - myVertices[0].XYZ();
|
||||
|
||||
computeFrustumNormals (myEdgeDirs, myPlanes);
|
||||
|
||||
cacheVertexProjections (this);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Transform
|
||||
// purpose : Returns a copy of the frustum transformed according to the matrix given
|
||||
// function : ScaleAndTransform
|
||||
// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
// Note that this method does not perform any checks on type of the frustum.
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
// and transforms it using the matrix given.
|
||||
// There are no default parameters, but in case if:
|
||||
// - transformation only is needed: @theScaleFactor must be initialized
|
||||
// as any negative value;
|
||||
// - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
//=======================================================================
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::Transform (const gp_Trsf& theTrsf)
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::ScaleAndTransform (const Standard_Integer /*theScale*/,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
SelectMgr_TriangularFrustum* aRes = new SelectMgr_TriangularFrustum();
|
||||
|
||||
// V0_Near
|
||||
aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]);
|
||||
aRes->myVertices[0] = myVertices[0].Transformed (theTrsf);
|
||||
// V1_Near
|
||||
aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]);
|
||||
aRes->myVertices[1] = myVertices[1].Transformed (theTrsf);
|
||||
// V2_Near
|
||||
aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]);
|
||||
aRes->myVertices[2] = myVertices[2].Transformed (theTrsf);
|
||||
// V0_Far
|
||||
aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]);
|
||||
aRes->myVertices[3] = myVertices[3].Transformed (theTrsf);
|
||||
// V1_Far
|
||||
aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]);
|
||||
aRes->myVertices[4] = myVertices[4].Transformed (theTrsf);
|
||||
// V2_Far
|
||||
aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]);
|
||||
aRes->myVertices[5] = myVertices[5].Transformed (theTrsf);
|
||||
|
||||
aRes->myIsOrthographic = myIsOrthographic;
|
||||
|
||||
computeFrustumNormals (aRes->myVertices, aRes->myPlanes);
|
||||
|
||||
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];
|
||||
aRes->myEdgeDirs[0] = aRes->myVertices[0].XYZ() - aRes->myVertices[3].XYZ();
|
||||
// V1_Near - V1_Far
|
||||
aRes->myEdgeDirs[1] = aRes->myVertices[1] - aRes->myVertices[4];
|
||||
aRes->myEdgeDirs[1] = aRes->myVertices[1].XYZ() - aRes->myVertices[4].XYZ();
|
||||
// V2_Near - V1_Far
|
||||
aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[5];
|
||||
aRes->myEdgeDirs[2] = aRes->myVertices[2].XYZ() - aRes->myVertices[5].XYZ();
|
||||
// V1_Near - V0_Near
|
||||
aRes->myEdgeDirs[3] = aRes->myVertices[1] - aRes->myVertices[0];
|
||||
aRes->myEdgeDirs[3] = aRes->myVertices[1].XYZ() - aRes->myVertices[0].XYZ();
|
||||
// V2_Near - V1_Near
|
||||
aRes->myEdgeDirs[4] = aRes->myVertices[2] - aRes->myVertices[1];
|
||||
aRes->myEdgeDirs[4] = aRes->myVertices[2].XYZ() - aRes->myVertices[1].XYZ();
|
||||
// V1_Near - V0_Near
|
||||
aRes->myEdgeDirs[5] = aRes->myVertices[2] - aRes->myVertices[0];
|
||||
aRes->myEdgeDirs[5] = aRes->myVertices[2].XYZ() - aRes->myVertices[0].XYZ();
|
||||
|
||||
computeFrustumNormals (aRes->myEdgeDirs, aRes->myPlanes);
|
||||
|
||||
cacheVertexProjections (aRes);
|
||||
|
||||
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
|
||||
}
|
||||
@@ -203,10 +171,11 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::Transform
|
||||
// purpose : SAT intersection test between defined volume and
|
||||
// given axis-aligned box
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const SelectMgr_Vec3& theMinPt,
|
||||
const SelectMgr_Vec3& theMaxPt,
|
||||
Standard_Real& /*theDepth*/)
|
||||
{
|
||||
return hasOverlap (theBox.CornerMin(), theBox.CornerMax());
|
||||
return hasOverlap (theMinPt, theMaxPt);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -261,7 +230,7 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const Handle(TColgp_HArr
|
||||
}
|
||||
else if (theSensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
SelectMgr_Vec3 aNorm (RealLast());
|
||||
gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
|
||||
return hasOverlap (theArrayOfPnts, aNorm);
|
||||
}
|
||||
|
||||
@@ -302,7 +271,7 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt1,
|
||||
}
|
||||
else if (theSensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
SelectMgr_Vec3 aNorm (RealLast());
|
||||
gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
|
||||
return hasOverlap (thePnt1, thePnt2, thePnt3, aNorm);
|
||||
}
|
||||
|
||||
|
@@ -40,12 +40,14 @@ public:
|
||||
const gp_Pnt2d& theP3) Standard_OVERRIDE;
|
||||
|
||||
//! Returns a copy of the frustum transformed according to the matrix given
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
|
||||
const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
|
||||
// SAT Tests for different objects
|
||||
|
||||
//! SAT intersection test between defined volume and given axis-aligned box
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
|
||||
const SelectMgr_Vec3& theMaxPnt,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
|
||||
@@ -82,6 +84,10 @@ public:
|
||||
//! Nullifies the handle to corresponding builder instance to prevent memory leaks
|
||||
Standard_EXPORT void Clear();
|
||||
|
||||
private:
|
||||
|
||||
void cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum);
|
||||
|
||||
DEFINE_STANDARD_RTTI(SelectMgr_TriangularFrustum,Standard_Transient)
|
||||
};
|
||||
|
||||
|
@@ -97,17 +97,24 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Transform
|
||||
// purpose : Returns a copy of the frustum with all sub-volumes transformed
|
||||
// according to the matrix given
|
||||
// function : ScaleAndTransform
|
||||
// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
|
||||
// Note that this method does not perform any checks on type of the frustum.
|
||||
// Returns a copy of the frustum resized according to the scale factor given
|
||||
// and transforms it using the matrix given.
|
||||
// There are no default parameters, but in case if:
|
||||
// - transformation only is needed: @theScaleFactor must be initialized
|
||||
// as any negative value;
|
||||
// - scale only is needed: @theTrsf must be set to gp_Identity.
|
||||
// =======================================================================
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::Transform (const gp_Trsf& theTrsf)
|
||||
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::ScaleAndTransform (const Standard_Integer theScale,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet();
|
||||
|
||||
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->Transform (theTrsf)));
|
||||
aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->ScaleAndTransform (theScale, theTrsf)));
|
||||
}
|
||||
|
||||
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
|
||||
@@ -117,12 +124,13 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::Transf
|
||||
// function : Overlaps
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt,
|
||||
const SelectMgr_Vec3& theMaxPnt,
|
||||
Standard_Real& theDepth)
|
||||
{
|
||||
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.Value()->Overlaps (theBox, theDepth))
|
||||
if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt, theDepth))
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
@@ -47,29 +47,31 @@ public:
|
||||
Standard_EXPORT 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
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
|
||||
const gp_Trsf& theTrsf) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
|
||||
const SelectMgr_Vec3& theMaxPnt,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
|
||||
const SelectMgr_Vec3& theMaxPnt,
|
||||
Standard_Boolean* theInside) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
|
||||
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)& theArrayOfPts,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
|
||||
Select3D_TypeOfSensitivity theSensType,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
|
||||
const gp_Pnt& thePt2,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
|
||||
const gp_Pnt& thePt2,
|
||||
const gp_Pnt& thePt3,
|
||||
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
|
||||
const gp_Pnt& thePnt2,
|
||||
const gp_Pnt& thePnt3,
|
||||
Select3D_TypeOfSensitivity theSensType,
|
||||
Standard_Real& theDepth) Standard_OVERRIDE;
|
||||
|
||||
|
@@ -66,8 +66,8 @@ namespace {
|
||||
//=======================================================================
|
||||
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
|
||||
{
|
||||
myLargestKey = -1.0;
|
||||
myCustomTolerance = -1.0;
|
||||
myLargestKey = -1;
|
||||
myCustomTolerance = -1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -84,7 +84,7 @@ SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
|
||||
// purpose : Adds the value given to map, checks if the current tolerance value
|
||||
// should be replaced by theTolerance
|
||||
//=======================================================================
|
||||
void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
|
||||
void SelectMgr_ToleranceMap::Add (const Standard_Integer& theTolerance)
|
||||
{
|
||||
if (myTolerances.IsBound (theTolerance))
|
||||
{
|
||||
@@ -113,7 +113,7 @@ void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
|
||||
// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
|
||||
// should be recalculated
|
||||
//=======================================================================
|
||||
void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
|
||||
void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
|
||||
{
|
||||
if (myTolerances.IsBound (theTolerance))
|
||||
{
|
||||
@@ -122,8 +122,8 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
|
||||
|
||||
if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
|
||||
{
|
||||
myLargestKey = 0.0;
|
||||
for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
|
||||
myLargestKey = 0;
|
||||
for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.Value() != 0)
|
||||
myLargestKey = Max (myLargestKey, anIter.Key());
|
||||
@@ -199,35 +199,12 @@ Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select
|
||||
&& sensitivity (theEntity) < myTolerances.Tolerance();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: scaleAndTransform
|
||||
// purpose : Applies given scale and transformation matrices to the default selecting volume manager
|
||||
//=======================================================================
|
||||
SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
SelectMgr_SelectingVolumeManager aMgr;
|
||||
|
||||
if (theScale > Precision::Angular())
|
||||
{
|
||||
aMgr = mySelectingVolumeMgr.Scale (theScale);
|
||||
}
|
||||
|
||||
if (theTrsf.Form() != gp_Identity)
|
||||
{
|
||||
aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
|
||||
mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
|
||||
}
|
||||
|
||||
return aMgr;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: sensitivity
|
||||
// purpose : In case if custom tolerance is set, this method will return sum of entity
|
||||
// sensitivity and custom tolerance.
|
||||
//=======================================================================
|
||||
Standard_Real SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
|
||||
Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
|
||||
{
|
||||
return myTolerances.IsCustomTolSet() ?
|
||||
theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
|
||||
@@ -259,7 +236,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
|
||||
|
||||
Standard_Integer aPriority = anOwner->Priority();
|
||||
|
||||
SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
|
||||
SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
|
||||
if (mystored.Contains (anOwner))
|
||||
{
|
||||
if (theMgr.GetActiveSelectionType() != 1)
|
||||
@@ -281,6 +258,40 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: computeFrustum
|
||||
// purpose : Internal function that checks if a current selecting frustum
|
||||
// needs to be scaled and transformed for the entity and performs
|
||||
// necessary calculations
|
||||
//=======================================================================
|
||||
void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
|
||||
const gp_Trsf& theInvTrsf,
|
||||
SelectMgr_FrustumCache& theCachedMgrs,
|
||||
SelectMgr_SelectingVolumeManager& theResMgr)
|
||||
{
|
||||
Standard_Integer aScale = 1;
|
||||
const Standard_Boolean toScale = isToScaleFrustum (theEnt);
|
||||
if (toScale)
|
||||
{
|
||||
aScale = sensitivity (theEnt);
|
||||
}
|
||||
if (theEnt->HasInitLocation())
|
||||
{
|
||||
theResMgr =
|
||||
mySelectingVolumeMgr.ScaleAndTransform (aScale, theEnt->InvInitLocation() * theInvTrsf);
|
||||
}
|
||||
else if (toScale)
|
||||
{
|
||||
if (!theCachedMgrs.IsBound (aScale))
|
||||
{
|
||||
theCachedMgrs.Bind (aScale,
|
||||
mySelectingVolumeMgr.ScaleAndTransform(aScale, theInvTrsf));
|
||||
}
|
||||
|
||||
theResMgr = theCachedMgrs.Find (aScale);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: traverseObject
|
||||
// purpose : Internal function that checks if there is possible overlap
|
||||
@@ -321,10 +332,10 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
|
||||
}
|
||||
|
||||
SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
|
||||
? mySelectingVolumeMgr.Transform (aInversedTrsf)
|
||||
? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
|
||||
: mySelectingVolumeMgr;
|
||||
|
||||
NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
|
||||
SelectMgr_FrustumCache aScaledTrnsfFrustums;
|
||||
|
||||
Standard_Integer aNode = 0; // a root node
|
||||
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
|
||||
@@ -379,16 +390,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
|
||||
{
|
||||
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
|
||||
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
|
||||
if (isToScaleFrustum (anEnt))
|
||||
{
|
||||
if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
|
||||
{
|
||||
aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
|
||||
scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
|
||||
}
|
||||
|
||||
aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
|
||||
}
|
||||
computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
|
||||
checkOverlap (anEnt, anIdx, aTmpMgr);
|
||||
}
|
||||
}
|
||||
|
@@ -54,6 +54,8 @@ typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Hand
|
||||
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities;
|
||||
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer>::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator;
|
||||
|
||||
typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
|
||||
|
||||
//! An internal class for calculation of current largest tolerance value which will be applied
|
||||
//! for creation of selecting frustum by default. Each time the selection set is deactivated,
|
||||
//! maximum tolerance value will be recalculated. If a user enables custom precision using
|
||||
@@ -70,31 +72,31 @@ public:
|
||||
|
||||
//! Adds the value given to map, checks if the current tolerance value
|
||||
//! should be replaced by theTolerance
|
||||
Standard_EXPORT void Add (const Standard_Real& theTolerance);
|
||||
Standard_EXPORT void Add (const Standard_Integer& theTolerance);
|
||||
|
||||
//! Decrements a counter of the tolerance given, checks if the current tolerance value
|
||||
//! should be recalculated
|
||||
Standard_EXPORT void Decrement (const Standard_Real& theTolerance);
|
||||
Standard_EXPORT void Decrement (const Standard_Integer& theTolerance);
|
||||
|
||||
//! Returns a current tolerance that must be applied
|
||||
inline Standard_Real Tolerance() const;
|
||||
inline Standard_Integer Tolerance() const;
|
||||
|
||||
//! Sets tolerance to the given one and disables adaptive checks
|
||||
inline void SetCustomTolerance (const Standard_Real theTolerance);
|
||||
inline void SetCustomTolerance (const Standard_Integer theTolerance);
|
||||
|
||||
//! Unsets a custom tolerance and enables adaptive checks
|
||||
inline void ResetDefaults();
|
||||
|
||||
//! Returns the value of custom tolerance regardless of it validity
|
||||
inline Standard_Real CustomTolerance() const;
|
||||
inline Standard_Integer CustomTolerance() const;
|
||||
|
||||
//! Returns true if custom tolerance value is greater than zero
|
||||
inline Standard_Boolean IsCustomTolSet() const;
|
||||
|
||||
private:
|
||||
NCollection_DataMap<Standard_Real, Standard_Integer> myTolerances;
|
||||
Standard_Real myLargestKey;
|
||||
Standard_Real myCustomTolerance;
|
||||
NCollection_DataMap<Standard_Integer, Standard_Integer> myTolerances;
|
||||
Standard_Integer myLargestKey;
|
||||
Standard_Integer myCustomTolerance;
|
||||
};
|
||||
|
||||
//! A framework to define finding, sorting the sensitive
|
||||
@@ -295,11 +297,7 @@ private:
|
||||
|
||||
//! In case if custom tolerance is set, this method will return sum of entity sensitivity and
|
||||
//! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
|
||||
Standard_Real sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
|
||||
|
||||
//! Applies given scale and transformation matrices to the default selecting volume manager
|
||||
SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
|
||||
const gp_Trsf& theTrsf);
|
||||
Standard_Integer sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
|
||||
|
||||
void Activate (const Handle(SelectMgr_Selection)& theSelection);
|
||||
|
||||
@@ -308,6 +306,14 @@ private:
|
||||
//! removes a Selection from the Selector
|
||||
void Remove (const Handle(SelectMgr_Selection)& aSelection);
|
||||
|
||||
//! Internal function that checks if a current selecting frustum
|
||||
//! needs to be scaled and transformed for the entity and performs
|
||||
//! necessary calculations
|
||||
void computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
|
||||
const gp_Trsf& theInvTrsf,
|
||||
SelectMgr_FrustumCache& theCachedMgrs,
|
||||
SelectMgr_SelectingVolumeManager& theResMgr);
|
||||
|
||||
protected:
|
||||
|
||||
Standard_Boolean preferclosest;
|
||||
|
@@ -16,19 +16,19 @@
|
||||
// function: Tolerance
|
||||
// purpose : Returns a current tolerance that must be applied
|
||||
//=======================================================================
|
||||
inline Standard_Real SelectMgr_ToleranceMap::Tolerance() const
|
||||
inline Standard_Integer SelectMgr_ToleranceMap::Tolerance() const
|
||||
{
|
||||
if (myLargestKey < Precision::Confusion())
|
||||
return 2.0; // default tolerance value
|
||||
return 2; // default tolerance value
|
||||
|
||||
return myCustomTolerance < 0.0 ? myLargestKey : myLargestKey + myCustomTolerance;
|
||||
return myCustomTolerance < 0 ? myLargestKey : myLargestKey + myCustomTolerance;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: SetCustomTolerance
|
||||
// purpose : Sets tolerance to the given one and disables adaptive checks
|
||||
//=======================================================================
|
||||
inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
|
||||
inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Integer theTolerance)
|
||||
{
|
||||
myCustomTolerance = theTolerance;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theT
|
||||
// function: CustomTolerance
|
||||
// purpose : Returns current value of custom tolerance regardless of it is set or not
|
||||
//=======================================================================
|
||||
inline Standard_Real SelectMgr_ToleranceMap::CustomTolerance() const
|
||||
inline Standard_Integer SelectMgr_ToleranceMap::CustomTolerance() const
|
||||
{
|
||||
return myCustomTolerance;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ inline Standard_Real SelectMgr_ToleranceMap::CustomTolerance() const
|
||||
//=======================================================================
|
||||
inline Standard_Boolean SelectMgr_ToleranceMap::IsCustomTolSet() const
|
||||
{
|
||||
return myCustomTolerance > 0.0;
|
||||
return myCustomTolerance > 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -57,7 +57,7 @@ inline Standard_Boolean SelectMgr_ToleranceMap::IsCustomTolSet() const
|
||||
//=======================================================================
|
||||
inline void SelectMgr_ToleranceMap::ResetDefaults()
|
||||
{
|
||||
myCustomTolerance = -1.0;
|
||||
myCustomTolerance = -1;
|
||||
}
|
||||
|
||||
inline Standard_Real SelectMgr_ViewerSelector::Sensitivity() const
|
||||
|
Reference in New Issue
Block a user