// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <Select3D_SensitiveCurve.ixx>
-#include <SelectBasics_BasicTool.hxx>
-#include <gp_Lin2d.hxx>
+#include <Select3D_SensitiveCurve.hxx>
#include <Precision.hxx>
-#include <ElCLib.hxx>
-#include <CSLib_Class2d.hxx>
-#include <Extrema_ExtElC.hxx>
+#include <TColgp_Array1OfPnt.hxx>
-//==================================================
-// Function: Creation
-// Purpose :
-//==================================================
-
-Select3D_SensitiveCurve
-::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
- const Handle(Geom_Curve)& C,
- const Standard_Integer NbPoints):
-Select3D_SensitivePoly(OwnerId, NbPoints),
-mylastseg(0),
-myCurve(C)
-{
- LoadPoints(C,NbPoints);
-}
+IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCurve, Select3D_SensitivePoly)
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCurve, Select3D_SensitivePoly)
//==================================================
// Function: Creation
// Purpose :
//==================================================
-
-Select3D_SensitiveCurve
-::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
- const Handle(TColgp_HArray1OfPnt)& ThePoints):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mylastseg(0)
+Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+ const Handle(Geom_Curve)& theCurve,
+ const Standard_Integer theNbPnts)
+: Select3D_SensitivePoly (theOwnerId, theNbPnts > 2, theNbPnts),
+ myCurve (theCurve)
{
+ loadPoints (theCurve, theNbPnts);
+ SetSensitivityFactor (3.0);
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
+Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+ const Handle(TColgp_HArray1OfPnt)& thePoints)
+: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints->Length() > 2)
-Select3D_SensitiveCurve
-::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
- const TColgp_Array1OfPnt& ThePoints):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mylastseg(0)
{
+ SetSensitivityFactor (3.0);
}
//==================================================
-// Function: Matches
+// Function: Creation
// Purpose :
//==================================================
-
-Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs,
- Standard_Real& theMatchDMin,
- Standard_Real& theMatchDepth)
-{
- Standard_Integer Rank;
- TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
- Points2D(aArrayOf2dPnt);
- if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
- thePickArgs.X(), thePickArgs.Y(),
- thePickArgs.Tolerance(),
- theMatchDMin,
- Rank))
- {
- // remember detected segment (for GetLastDetected)
- mylastseg = Rank;
-
- theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
-
- return !thePickArgs.IsClipped (theMatchDepth);
- }
-
- return Standard_False;
-}
-
-//==================================================
-// Function: Matches
-// Purpose : know if a box touches the projected polygon
-// of the Curve.
-//==================================================
-
-Standard_Boolean Select3D_SensitiveCurve::
-Matches (const Standard_Real XMin,
- const Standard_Real YMin,
- const Standard_Real XMax,
- const Standard_Real YMax,
- const Standard_Real aTol)
+Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+ const TColgp_Array1OfPnt& thePoints)
+: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints.Length() > 2)
{
- Bnd_Box2d BoundBox;
- BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
-
- for(Standard_Integer anIndex=0; anIndex<mypolyg.Size(); ++anIndex)
- {
- if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
- return Standard_False;
- }
- return Standard_True;
-}
-
-//=======================================================================
-//function : Matches
-//purpose :
-//=======================================================================
-
-Standard_Boolean Select3D_SensitiveCurve::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
- const Bnd_Box2d& aBox,
- const Standard_Real aTol)
-{
- Standard_Real Umin,Vmin,Umax,Vmax;
- aBox.Get(Umin,Vmin,Umax,Vmax);
- CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
-
- for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
- {
- Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
- if(RES!=1)
- return Standard_False;
- }
- return Standard_True;
+ SetSensitivityFactor (3.0);
}
//==================================================
-// Function: LoadPoints
+// Function: loadPoints
// Purpose :
//==================================================
-
-void Select3D_SensitiveCurve
-::LoadPoints (const Handle(Geom_Curve)& aCurve,const Standard_Integer NbP)
+void Select3D_SensitiveCurve::loadPoints (const Handle(Geom_Curve)& theCurve, const Standard_Integer theNbPnts)
{
- /*this method is private and it used only inside of constructor.
- That's why check !NbP==mypolyg3d->Length() was removed*/
-
- Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1);
- Standard_Real Curparam = aCurve->FirstParameter();
- for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
+ Standard_Real aStep = (theCurve->LastParameter() - theCurve->FirstParameter()) / (theNbPnts - 1);
+ Standard_Real aParam = theCurve->FirstParameter();
+ for (Standard_Integer aPntIdx = 0; aPntIdx < myPolyg.Size(); ++aPntIdx)
{
- mypolyg.SetPnt(anIndex, aCurve->Value(Curparam));
- Curparam+=Step;
+ myPolyg.SetPnt (aPntIdx, theCurve->Value (aParam));
+ aParam += aStep;
}
}
-//=======================================================================
-//function : Dump
-//purpose :
-//=======================================================================
-
-void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
-{
- S<<"\tSensitiveCurve 3D :"<<endl;
- if (HasLocation())
- S<<"\t\tExisting Location"<<endl;
-
- S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
-
- if(FullDump)
- {
- Select3D_SensitiveEntity::DumpBox(S,mybox2d);
- }
-}
-
-//=======================================================================
-//function : ComputeDepth
-//purpose :
-//=======================================================================
-
-Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
- const Standard_Integer theSegment) const
-{
- Standard_Real aDepth = Precision::Infinite();
- if (theSegment == 0)
- {
- return aDepth;
- }
-
- // In case if theSegment and theSegment + 1 are not valid
- // the depth will be infinite
- if (theSegment >= mypolyg.Size())
- {
- return aDepth;
- }
-
- gp_XYZ aCDG = mypolyg.Pnt (theSegment);
-
- // Check depth of a line forward within the curve.
- if (theSegment + 1 < mypolyg.Size())
- {
- gp_XYZ aCDG1 = mypolyg.Pnt (theSegment + 1);
- if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
- {
- return aDepth;
- }
- }
-
- // Check depth of a line backward within the curve.
- if (theSegment - 1 >= 0)
- {
- gp_XYZ aCDG1 = mypolyg.Pnt (theSegment - 1);
- if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
- {
- return aDepth;
- }
- }
-
- // Calculate the depth in the middle point of
- // a next (forward) segment of the curve.
- if (theSegment + 1 < mypolyg.Size())
- {
- aCDG += mypolyg.Pnt(theSegment + 1);
- aCDG /= 2.;
- }
-
- return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
-}
-
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
-
-Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const TopLoc_Location &theLocation)
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected()
{
// Create a copy of this
Handle(Select3D_SensitiveEntity) aNewEntity;
// this was constructed using Handle(Geom_Curve)
if (!myCurve.IsNull())
{
- aNewEntity = new Select3D_SensitiveCurve(myOwnerId, myCurve);
+ aNewEntity = new Select3D_SensitiveCurve (myOwnerId, myCurve);
}
// this was constructed using TColgp_HArray1OfPnt
else
{
- Standard_Integer aSize = mypolyg.Size();
- Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(1, aSize);
+ Standard_Integer aSize = myPolyg.Size();
+ Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt (1, aSize);
// Fill the array with points from mypolyg3d
for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
{
- aPoints->SetValue(anIndex, mypolyg.Pnt(anIndex-1));
+ aPoints->SetValue (anIndex, myPolyg.Pnt (anIndex-1));
}
- aNewEntity = new Select3D_SensitiveCurve(myOwnerId, aPoints);
+ aNewEntity = new Select3D_SensitiveCurve (myOwnerId, aPoints);
}
- if (HasLocation())
- aNewEntity->SetLocation(Location());
-
- aNewEntity->UpdateLocation(theLocation);
-
return aNewEntity;
}
//=======================================================================
-//function : ComputeDepth()
-//purpose : Computes the depth by means of intersection of
-// a segment of the curve defined by <theP1, theP2> and
-// the eye-line <thePickLine>.
+// function : Matches
+// purpose : Checks whether the curve overlaps current selecting volume
//=======================================================================
-
-Standard_Boolean Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& thePickLine,
- const gp_XYZ& theP1,
- const gp_XYZ& theP2,
- Standard_Real& theDepth) const
+Standard_Boolean Select3D_SensitiveCurve::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+ SelectBasics_PickResult& thePickResult)
{
- // The segment may have null length.
- gp_XYZ aVec = theP2 - theP1;
- Standard_Real aLength = aVec.Modulus();
- if (aLength <= gp::Resolution())
- {
- theDepth = ElCLib::Parameter(thePickLine, theP1);
- return Standard_True;
- }
+ if (myPolyg.Size() > 2)
+ return Select3D_SensitivePoly::Matches (theMgr, thePickResult);
- // Compute an intersection point of the segment-line and the eye-line.
- gp_Lin aLine (theP1, aVec);
- Extrema_ExtElC anExtrema(aLine, thePickLine, Precision::Angular());
- if (anExtrema.IsDone() && !anExtrema.IsParallel() )
+ const gp_Pnt aPnt1 = myPolyg.Pnt3d (0);
+ const gp_Pnt aPnt2 = myPolyg.Pnt3d (1);
+ Standard_Real aDepth = RealLast();
+ Standard_Boolean isMatched = theMgr.Overlaps (aPnt1, aPnt2, aDepth);
+
+ if (isMatched)
{
- // Iterator on solutions (intersection points).
- for (Standard_Integer i = 1; i <= anExtrema.NbExt(); i++)
+ Standard_Real aDistToCOG = RealLast();
+ if (myCOG.X() == RealLast() && myCOG.Y() == RealLast() && myCOG.Z() == RealLast())
{
- // Get the intersection point.
- Extrema_POnCurv aPointOnLine1, aPointOnLine2;
- anExtrema.Points(i, aPointOnLine1, aPointOnLine2);
-
- // Check bounds: the point of intersection should lie within the segment.
- if (aPointOnLine1.Parameter() > 0.0 && aPointOnLine1.Parameter() < aLength)
+ gp_XYZ aCenter (0.0, 0.0, 0.0);
+ for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
{
- theDepth = ElCLib::Parameter(thePickLine, aPointOnLine1.Value());
- return Standard_True;
+ aCenter += myPolyg.Pnt (aIdx);
}
+ myCOG = aCenter / myPolyg.Size();
}
+
+ aDistToCOG = theMgr.DistToGeometryCenter (myCOG);
+
+ thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
+ return Standard_True;
}
return Standard_False;