1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0032547: Visualization, Select3D_SensitiveCylinder - implement picking of a hollow cylinder

Select3D_SensitiveCircle now inherits directly from Select3D_SensitiveEntity.
The sensitive circle sector is created using the Select3D_SensitivePoly class directly.

Added appropriate methods for selecting sensitive circles.
Added parameter myIsHollow to Select3D_SensitiveCylinder class.
It allows you to search for intersections with cylinders without covers.

The Draw vcircle command has been extended with UStart and UEnd parameters
to create a sector of a circle.

Added tests: vselect/cone_cylinder/circle_sector
             vselect/cone_cylinder/circle_wire
             vselect/cone_cylinder/filled_circle
             vselect/cone_cylinder/transformed
             vselect/cone_cylinder/hollow_cone_cyl
This commit is contained in:
mzernova
2022-08-18 17:12:03 +03:00
committed by smoskvin
parent da76ea432b
commit 7aaed2ce3b
38 changed files with 2117 additions and 784 deletions

View File

@@ -16,195 +16,29 @@
#include <Select3D_SensitiveCircle.hxx>
#include <ElCLib.hxx>
#include <Precision.hxx>
#include <Select3D_SensitiveTriangle.hxx>
#include <gp_Ax3.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle,Select3D_SensitivePoly)
namespace
{
static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle,
const Standard_Integer theNbPnts)
{
// Check if number of points is invalid.
// In this case myPolyg raises Standard_ConstructionError
// exception (see constructor below).
if (theNbPnts <= 0)
return 0;
if (theCircle.Radius() > Precision::Confusion())
return 2 * theNbPnts + 1;
// The radius is too small and circle degenerates into point
return 1;
}
//! Definition of circle polyline
static void initCircle (Select3D_PointData& thePolygon,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Integer theNbPnts)
{
const Standard_Real aStep = (theU2 - theU1) / theNbPnts;
const Standard_Real aRadius = theCircle.Radius();
Standard_Integer aPntIdx = 0;
Standard_Real aCurU = theU1;
gp_Pnt aP1;
gp_Vec aV1;
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep)
{
ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1);
thePolygon.SetPnt (aPntIdx++, aP1);
aV1.Normalize();
const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius;
thePolygon.SetPnt (aPntIdx++, aP2);
}
aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius());
thePolygon.SetPnt (theNbPnts * 2, aP1);
}
}
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
//=======================================================================
//function : Select3D_SensitiveCircle (constructor)
//purpose : Definition of a sensitive circle
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
myCircle (theCircle),
myStart (0.0),
myEnd (2.0 * M_PI)
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myCenter3D = theCircle.Position().Location();
if (myPolyg.Size() != 1)
{
initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
}
// Radius = 0.0
else
{
myPolyg.SetPnt (0, theCircle.Position().Location());
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6);
}
}
//=======================================================================
//function : Select3D_SensitiveCircle (constructor)
//purpose : Definition of a sensitive arc
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
myCircle (theCircle),
myStart (Min (theU1, theU2)),
myEnd (Max (theU1, theU2))
const Standard_Boolean theIsFilled)
: Select3D_SensitiveEntity (theOwnerId)
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myCenter3D = theCircle.Position().Location();
if (myPolyg.Size() != 1)
{
initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
}
else
{
myPolyg.SetPnt (0, theCircle.Position().Location());
}
myRadius = theCircle.Radius();
myTrsf.SetTransformation (theCircle.Position(), gp::XOY());
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6);
}
}
//=======================================================================
//function : Select3D_SensitiveCircle
//purpose :
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
myStart (0),
myEnd (0)
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
computeCenter3D();
else
myCenter3D = myPolyg.Pnt (0);
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6);
}
}
//=======================================================================
//function : Select3D_SensitiveCircle
//purpose :
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePnts3d,
const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled),
myStart (0),
myEnd (0)
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
computeCenter3D();
else
myCenter3D = myPolyg.Pnt (0);
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6);
}
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for a circle's edge segments if needed
//=======================================================================
void Select3D_SensitiveCircle::BVH()
{
if (mySensType == Select3D_TOS_BOUNDARY)
{
Select3D_SensitivePoly::BVH();
}
}
//=======================================================================
// function : ToBuildBVH
// purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::ToBuildBVH() const
{
if (mySensType != Select3D_TOS_BOUNDARY)
{
return Standard_False;
}
return Select3D_SensitivePoly::ToBuildBVH();
}
//=======================================================================
// function : Matches
// purpose : Checks whether the circle overlaps current selecting volume
@@ -212,40 +46,26 @@ Standard_Boolean Select3D_SensitiveCircle::ToBuildBVH() const
Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
if (mySensType == Select3D_TOS_BOUNDARY)
const Standard_Boolean aIsFilled = mySensType == Select3D_TOS_INTERIOR;
if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point)
{
if (!Select3D_SensitivePoly::Matches (theMgr, thePickResult))
{
return Standard_False;
}
}
else if (mySensType == Select3D_TOS_INTERIOR)
{
Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
Points3D (anArrayOfPnt);
if (!theMgr.IsOverlapAllowed())
{
if (theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), mySensType, aDummy);
}
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{
if (!theMgr.OverlapsPoint (anArrayOfPnt->Value(aPntIdx)))
{
return Standard_False;
}
}
return Standard_True;
bool isInside = true;
return theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, &isInside) && isInside;
}
if (!theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), Select3D_TOS_INTERIOR, thePickResult))
else
{
return Standard_False;
return theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, NULL);
}
thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
}
if (!theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, thePickResult))
{
return false;
}
thePickResult.SetDistToGeomCenter (theMgr.DistToGeometryCenter (CenterOfGeometry()));
return Standard_True;
}
@@ -254,81 +74,36 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected()
{
Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR;
// Create a copy of this
Handle(Select3D_SensitiveEntity) aNewEntity;
// this was constructed using Handle(Geom_Circle)
if (!Precision::IsInfinite (myCircle.Radius()))
{
if ((myEnd - myStart) > Precision::Confusion())
{
// Arc
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled);
}
else
{
// Circle
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled);
}
}
// this was constructed using TColgp_Array1OfPnt
else
{
Standard_Integer aSize = myPolyg.Size();
TColgp_Array1OfPnt aPolyg (1, aSize);
for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
{
aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1));
}
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled);
}
Standard_Boolean anIsFilled = mySensType == Select3D_TOS_INTERIOR;
Handle(Select3D_SensitiveEntity) aNewEntity = new Select3D_SensitiveCircle (myOwnerId,
Circle(),
anIsFilled);
return aNewEntity;
}
//=======================================================================
//function : computeCenter3D
//purpose :
//=======================================================================
void Select3D_SensitiveCircle::computeCenter3D()
//==================================================
// Function: BoundingBox
// Purpose :
//==================================================
Select3D_BndBox3d Select3D_SensitiveCircle::BoundingBox()
{
gp_XYZ aCenter;
Standard_Integer aNbPnts = myPolyg.Size();
if (aNbPnts != 1)
{
// The mass of points system
Standard_Integer aMass = aNbPnts - 1;
// Find the circle barycenter
for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex)
{
aCenter += myPolyg.Pnt(anIndex);
}
myCenter3D = aCenter / aMass;
}
else
{
myCenter3D = myPolyg.Pnt(0);
}
Graphic3d_Mat4d aTrsf;
myTrsf.GetMat4 (aTrsf);
Select3D_BndBox3d aBox (SelectMgr_Vec3 (-myRadius, -myRadius, 0),
SelectMgr_Vec3 (myRadius, myRadius, 0));
aBox.Transform (aTrsf);
return aBox;
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the circle. If location transformation
// is set, it will be applied
//=======================================================================
//==================================================
// Function: CenterOfGeometry
// Purpose :
//==================================================
gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const
{
return myCenter3D;
}
//=======================================================================
// function : distanceToCOG
// purpose :
//=======================================================================
Standard_Real Select3D_SensitiveCircle::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
return theMgr.DistToGeometryCenter (myCenter3D);
return gp_Pnt (myTrsf.TranslationPart());
}

View File

@@ -17,93 +17,70 @@
#ifndef _Select3D_SensitiveCircle_HeaderFile
#define _Select3D_SensitiveCircle_HeaderFile
#include <gp_Circ.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <Select3D_SensitiveEntity.hxx>
//! A framework to define sensitive 3D arcs and circles.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
class Select3D_SensitiveCircle : public Select3D_SensitivePoly
#include <gp_Circ.hxx>
//! A framework to define sensitive 3D circles.
class Select3D_SensitiveCircle : public Select3D_SensitiveEntity
{
DEFINE_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitivePoly)
DEFINE_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
public:
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the circle theCircle and the boolean theIsFilled.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Boolean theIsFilled = Standard_False);
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the circle theCircle, the boolean
//! theIsFilled and the number of points theNbPnts.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Boolean theIsFilled = Standard_False,
const Standard_Integer theNbPnts = 12);
//! Constructs the sensitive arc object defined by the
//! owner theOwnerId, the circle theCircle, the parameters theU1
//! and theU2, the boolean theIsFilled and the number of points theNbPnts.
//! theU1 and theU2 define the first and last points of the arc on theCircle.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled = Standard_False,
const Standard_Integer theNbPnts = 12);
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the array of triangles thePnts3d, and the boolean theIsFilled.
//! thePnts3d is an array of consecutive triangles on the
//! circle. The triangle i+1 lies on the intersection of the
//! tangents to the circle of i and i+2. Note, that the first point of thePnts3d
//! must be equal to the last point of thePnts3d.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled = Standard_False);
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the array of points thePnts3d, and the boolean theIsFilled.
//! If the length of thePnts3d is more then 1, the first point of thePnts3d
//! must be equal to the last point of thePnts3d.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePnts3d,
const Standard_Boolean theIsFilled = Standard_False);
Standard_DEPRECATED("Deprecated constructor, theNbPnts parameter will be ignored")
Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Boolean theIsFilled,
const Standard_Integer /*theNbPnts*/)
: Select3D_SensitiveCircle (theOwnerId, theCircle, theIsFilled)
{ }
//! Checks whether the circle overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns a copy of this sensitive circle
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Returns center of the circle. If location
//! transformation is set, it will be applied
//! Returns bounding box of the circle.
//! If location transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Always returns Standard_False
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
//! Returns the amount of points
virtual Standard_Integer NbSubElements() const Standard_OVERRIDE { return 1; }
//! Returns center of the circle with transformation applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Builds BVH tree for a circle's edge segments if needed
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
//! The transformation for gp::XOY() with center in gp::Origin(),
//! it specifies the position and orientation of the circle.
const gp_Trsf& Transformation() const { return myTrsf; }
//! Returns TRUE if BVH tree is in invalidated state
Standard_EXPORT virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE;
//! Returns circle
gp_Circ Circle() const { return gp_Circ (gp::XOY().Transformed (myTrsf), myRadius); }
protected:
//! Calculates distance from the 3d projection of used-picked screen point
//! to center of the geometry
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
//! Returns circle radius
Standard_Real Radius() const { return myRadius; }
private:
//! Computes myCenter3D as the barycenter of points from mypolyg3d
void computeCenter3D();
private:
Select3D_TypeOfSensitivity mySensType; //!< True if type of selection is interior, false otherwise
gp_Pnt myCenter3D; //!< Center of a circle
gp_Circ myCircle; //!< Points of the circle
Standard_Real myStart; //!< Sensitive arc parameter
Standard_Real myEnd; //!< Sensitive arc parameter
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior
gp_Trsf myTrsf; //!< Circle transformation to apply
Standard_Real myRadius; //!< Circle radius
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitivePoly)
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
#endif // _Select3D_SensitiveCircle_HeaderFile

View File

@@ -25,12 +25,14 @@ Select3D_SensitiveCylinder::Select3D_SensitiveCylinder (const Handle(SelectMgr_E
const Standard_Real theBottomRad,
const Standard_Real theTopRad,
const Standard_Real theHeight,
const gp_Trsf& theTrsf)
const gp_Trsf& theTrsf,
const Standard_Boolean theIsHollow)
: Select3D_SensitiveEntity (theOwnerId),
myTrsf (theTrsf),
myBottomRadius (theBottomRad),
myTopRadius (theTopRad),
myHeight (theHeight)
myHeight (theHeight),
myIsHollow (theIsHollow)
{
}
@@ -46,14 +48,14 @@ Standard_Boolean Select3D_SensitiveCylinder::Matches (SelectBasics_SelectingVolu
if (!theMgr.IsOverlapAllowed())
{
bool isInside = true;
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, &isInside) && isInside;
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, &isInside) && isInside;
}
else
{
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, NULL);
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, NULL);
}
}
if (!theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, thePickResult))
if (!theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, thePickResult))
{
return false;
}

View File

@@ -32,7 +32,8 @@ public:
const Standard_Real theBottomRad,
const Standard_Real theTopRad,
const Standard_Real theHeight,
const gp_Trsf& theTrsf);
const gp_Trsf& theTrsf,
const Standard_Boolean theIsHollow = Standard_False);
//! Checks whether the cylinder overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
@@ -66,11 +67,15 @@ public:
//! Returns cylinder height
Standard_Real Height() const { return myHeight; }
//! Returns true if the cylinder is empty inside
Standard_Boolean IsHollow() const { return myIsHollow; }
protected:
gp_Trsf myTrsf; //!< cylinder transformation to apply
Standard_Real myBottomRadius; //!< cylinder bottom radius
Standard_Real myTopRadius; //!< cylinder top radius
Standard_Real myHeight; //!< cylinder height
gp_Trsf myTrsf; //!< cylinder transformation to apply
Standard_Real myBottomRadius; //!< cylinder bottom radius
Standard_Real myTopRadius; //!< cylinder top radius
Standard_Real myHeight; //!< cylinder height
Standard_Boolean myIsHollow; //!< true if the cylinder is empty inside
};
#endif // _Select3D_SensitiveSphere_HeaderFile

View File

@@ -13,8 +13,71 @@
#include <Select3D_SensitivePoly.hxx>
#include <ElCLib.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly,Select3D_SensitiveSet)
namespace
{
static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle,
const Standard_Integer theNbPnts,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled)
{
// Check if number of points is invalid.
// In this case myPolyg raises Standard_ConstructionError
// exception (see constructor below).
if (theNbPnts <= 0)
{
return 0;
}
if (theCircle.Radius() > Precision::Confusion())
{
const Standard_Boolean isSector = theIsFilled && Abs (Abs (theU2 - theU1) - 2.0 * M_PI) > gp::Resolution();
return 2 * theNbPnts + 1 + (isSector ? 2 : 0);
}
// The radius is too small and circle degenerates into point
return 1;
}
//! Definition of circle polyline
static void initCircle (Select3D_PointData& thePolygon,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
{
const Standard_Real aStep = (theU2 - theU1) / theNbPnts;
const Standard_Real aRadius = theCircle.Radius();
Standard_Integer aPntIdx = 0;
Standard_Real aCurU = theU1;
gp_Pnt aP1;
gp_Vec aV1;
const Standard_Boolean isSector = Abs (theU2 - theU1 - 2.0 * M_PI) > gp::Resolution();
if (isSector && theIsFilled) { thePolygon.SetPnt (aPntIdx++, theCircle.Location()); }
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep)
{
ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1);
thePolygon.SetPnt (aPntIdx++, aP1);
aV1.Normalize();
const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius;
thePolygon.SetPnt (aPntIdx++, aP2);
}
aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius());
thePolygon.SetPnt (aPntIdx++, aP1);
if (isSector && theIsFilled) { thePolygon.SetPnt (aPntIdx++, theCircle.Location()); }
}
}
//==================================================
// Function: Select3D_SensitivePoly
// Purpose :
@@ -23,7 +86,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
const TColgp_Array1OfPnt& thePoints,
const Standard_Boolean theIsBVHEnabled)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (thePoints.Upper() - thePoints.Lower() + 1)
myPolyg (thePoints.Upper() - thePoints.Lower() + 1),
mySensType (Select3D_TOS_BOUNDARY)
{
Standard_Integer aLowerIdx = thePoints.Lower();
Standard_Integer anUpperIdx = thePoints.Upper();
@@ -64,7 +128,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Standard_Boolean theIsBVHEnabled)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (thePoints->Upper() - thePoints->Lower() + 1)
myPolyg (thePoints->Upper() - thePoints->Lower() + 1),
mySensType (Select3D_TOS_BOUNDARY)
{
Standard_Integer aLowerIdx = thePoints->Lower();
Standard_Integer anUpperIdx = thePoints->Upper();
@@ -105,7 +170,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
const Standard_Boolean theIsBVHEnabled,
const Standard_Integer theNbPnts)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (theNbPnts)
myPolyg (theNbPnts),
mySensType (Select3D_TOS_BOUNDARY)
{
if (theIsBVHEnabled)
{
@@ -119,6 +185,80 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
myIsComputed = Standard_False;
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts, theU1, theU2, theIsFilled))
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
{
initCircle (myPolyg, theCircle, Min (theU1, theU2), Max (theU1, theU2), theIsFilled, theNbPnts);
}
else
{
myPolyg.SetPnt (0, theCircle.Position().Location());
}
if (!theIsFilled)
{
SetSensitivityFactor (6);
}
}
//=======================================================================
// function : Matches
// purpose :
//=======================================================================
Standard_Boolean Select3D_SensitivePoly::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
if (mySensType == Select3D_TOS_BOUNDARY)
{
if (!Select3D_SensitiveSet::Matches (theMgr, thePickResult))
{
return Standard_False;
}
}
else if (mySensType == Select3D_TOS_INTERIOR)
{
Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
Points3D (anArrayOfPnt);
if (!theMgr.IsOverlapAllowed())
{
if (theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Polyline)
{
SelectBasics_PickResult aDummy;
return theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), mySensType, aDummy);
}
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{
if (!theMgr.OverlapsPoint (anArrayOfPnt->Value(aPntIdx)))
{
return Standard_False;
}
}
return Standard_True;
}
if (!theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), Select3D_TOS_INTERIOR, thePickResult))
{
return Standard_False;
}
thePickResult.SetDistToGeomCenter (distanceToCOG(theMgr));
}
return Standard_True;
}
//==================================================
// function : BoundingBox
// purpose : Returns bounding box of a polygon. If location

View File

@@ -14,13 +14,13 @@
#ifndef _Select3D_SensitivePoly_HeaderFile
#define _Select3D_SensitivePoly_HeaderFile
#include <gp_Circ.hxx>
#include <Select3D_PointData.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColgp_HArray1OfPnt.hxx>
//! Sensitive Entity to make a face selectable.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions from its member Select3D_PointData
@@ -46,13 +46,28 @@ public:
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Standard_Boolean theIsBVHEnabled);
//! Constructs the sensitive circle object defined by the
//! owner OwnerId, the circle Circle, the Boolean
//! FilledCircle and the number of points NbOfPoints.
//! Constructs the sensitive arc object defined by the
//! owner theOwnerId, the circle theCircle, the parameters theU1
//! and theU2, the boolean theIsFilled and the number of points theNbPnts.
//! theU1 and theU2 define the first and last points of the arc on theCircle.
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const gp_Circ& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled = Standard_False,
const Standard_Integer theNbPnts = 12);
//! Constructs a sensitive curve or arc object defined by the
//! owner theOwnerId, the theIsBVHEnabled flag, and the
//! maximum number of points on the curve: theNbPnts.
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
const Standard_Boolean theIsBVHEnabled,
const Standard_Integer theNbPnts = 6);
//! Checks whether the poly overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the amount of segments in poly
Standard_EXPORT virtual Standard_Integer NbSubElements() const Standard_OVERRIDE;
@@ -128,11 +143,12 @@ protected:
protected:
Select3D_PointData myPolyg; //!< Points of the poly
mutable gp_Pnt myCOG; //!< Center of the poly
Handle(TColStd_HArray1OfInteger) mySegmentIndexes; //!< Segment indexes for BVH tree build
Select3D_BndBox3d myBndBox; //!< Bounding box of the poly
mutable Standard_Boolean myIsComputed; //!< Is true if all the points and data structures of polygon are initialized
Select3D_PointData myPolyg; //!< Points of the poly
mutable gp_Pnt myCOG; //!< Center of the poly
Handle(TColStd_HArray1OfInteger) mySegmentIndexes; //!< Segment indexes for BVH tree build
Select3D_BndBox3d myBndBox; //!< Bounding box of the poly
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior
mutable Standard_Boolean myIsComputed; //!< Is true if all the points and data structures of polygon are initialized
};
DEFINE_STANDARD_HANDLE(Select3D_SensitivePoly, Select3D_SensitiveSet)