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:
@@ -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());
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user