mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-29 14:00:49 +03:00
# build hierarchy of BVH trees
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <BRepLib_MakeFace.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <BRepTopAdaptor_FClass2d.hxx>
|
||||
#include <GCPnts.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
@@ -178,39 +179,6 @@ BRepLib_FindSurface::BRepLib_FindSurface(const TopoDS_Shape& S,
|
||||
|
||||
namespace
|
||||
{
|
||||
static void fillParams (const TColStd_Array1OfReal& theKnots,
|
||||
Standard_Integer theDegree,
|
||||
Standard_Real theParMin,
|
||||
Standard_Real theParMax,
|
||||
NCollection_Vector<Standard_Real>& theParams)
|
||||
{
|
||||
Standard_Real aPrevPar = theParMin;
|
||||
theParams.Append (aPrevPar);
|
||||
|
||||
Standard_Integer aNbP = Max (theDegree, 1);
|
||||
|
||||
for (Standard_Integer i = 1;
|
||||
(i < theKnots.Length()) && (theKnots (i) < (theParMax - Precision::PConfusion())); ++i)
|
||||
{
|
||||
if (theKnots (i + 1) < theParMin + Precision::PConfusion())
|
||||
continue;
|
||||
|
||||
Standard_Real aStep = (theKnots (i + 1) - theKnots (i)) / aNbP;
|
||||
for (Standard_Integer k = 1; k <= aNbP ; ++k)
|
||||
{
|
||||
Standard_Real aPar = theKnots (i) + k * aStep;
|
||||
if (aPar > theParMax - Precision::PConfusion())
|
||||
break;
|
||||
|
||||
if (aPar > aPrevPar + Precision::PConfusion())
|
||||
{
|
||||
theParams.Append (aPar);
|
||||
aPrevPar = aPar;
|
||||
}
|
||||
}
|
||||
}
|
||||
theParams.Append (theParMax);
|
||||
}
|
||||
|
||||
static void fillPoints (const BRepAdaptor_Curve& theCurve,
|
||||
const NCollection_Vector<Standard_Real> theParams,
|
||||
@@ -358,13 +326,13 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
aKnots.SetValue (1, GC->FirstParameter());
|
||||
aKnots.SetValue (2, GC->LastParameter());
|
||||
|
||||
fillParams (aKnots, GC->Degree(), dfUf, dfUl, aParams);
|
||||
GCPnts::FillParams (aKnots, GC->Degree(), dfUf, dfUl, aParams);
|
||||
break;
|
||||
}
|
||||
case GeomAbs_BSplineCurve:
|
||||
{
|
||||
Handle(Geom_BSplineCurve) GC = c.BSpline();
|
||||
fillParams (GC->Knots(), GC->Degree(), dfUf, dfUl, aParams);
|
||||
GCPnts::FillParams (GC->Knots(), GC->Degree(), dfUf, dfUl, aParams);
|
||||
break;
|
||||
}
|
||||
case GeomAbs_Line:
|
||||
@@ -391,7 +359,7 @@ void BRepLib_FindSurface::Init(const TopoDS_Shape& S,
|
||||
aBounds.SetValue (1, dfUf);
|
||||
aBounds.SetValue (2, dfUl);
|
||||
|
||||
fillParams (aBounds, iNbPoints - 1, dfUf, dfUl, aParams);
|
||||
GCPnts::FillParams (aBounds, iNbPoints - 1, dfUf, dfUl, aParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <BndLib_AddSurface.hxx>
|
||||
#include <BVH_LinearBuilder.hxx>
|
||||
#include <BVH_Tools.hxx>
|
||||
#include <GCPnts.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
@@ -37,83 +38,59 @@ IMPLEMENT_STANDARD_RTTIEXT (Extrema_GenExtPS, Standard_Transient)
|
||||
// Static methods definition
|
||||
namespace
|
||||
{
|
||||
//=======================================================================
|
||||
//function : fillParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillParams (const TColStd_Array1OfReal& theKnots,
|
||||
Standard_Integer theDegree,
|
||||
Standard_Real theParMin,
|
||||
Standard_Real theParMax,
|
||||
Handle (TColStd_HArray1OfReal)& theParams,
|
||||
Standard_Integer theNbSample)
|
||||
{
|
||||
NCollection_Vector<Standard_Real> aParams;
|
||||
Standard_Integer i = 1;
|
||||
Standard_Real aPrevPar = theParMin;
|
||||
aParams.Append (aPrevPar);
|
||||
// Calculation the array of parametric points depending on the knots array variation and degree of given surface
|
||||
for (; i < theKnots.Length() && theKnots (i) < (theParMax - Precision::PConfusion()); i++)
|
||||
//=======================================================================
|
||||
//function : fillParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillParams (const TColStd_Array1OfReal& theKnots,
|
||||
const Standard_Integer theDegree,
|
||||
const Standard_Real theParMin,
|
||||
const Standard_Real theParMax,
|
||||
Standard_Integer theNbSamples,
|
||||
Handle (TColStd_HArray1OfReal)& theParams)
|
||||
{
|
||||
if (theKnots (i + 1) < theParMin + Precision::PConfusion())
|
||||
continue;
|
||||
NCollection_Vector<Standard_Real> aParams;
|
||||
GCPnts::FillParams (theKnots, theDegree, theParMin, theParMax, aParams);
|
||||
Standard_Integer nbPar = aParams.Length();
|
||||
|
||||
Standard_Real aStep = (theKnots (i + 1) - theKnots (i)) / Max (theDegree, 2);
|
||||
Standard_Integer k = 1;
|
||||
for (; k <= theDegree; k++)
|
||||
{
|
||||
Standard_Real aPar = theKnots (i) + k * aStep;
|
||||
if (aPar > theParMax - Precision::PConfusion())
|
||||
break;
|
||||
if (aPar > aPrevPar + Precision::PConfusion())
|
||||
{
|
||||
aParams.Append (aPar);
|
||||
aPrevPar = aPar;
|
||||
}
|
||||
}
|
||||
// In case of an insufficient number of points the grid will be built later
|
||||
if (nbPar < theNbSamples)
|
||||
return;
|
||||
|
||||
theParams = new TColStd_HArray1OfReal (1, nbPar);
|
||||
for (Standard_Integer i = 0; i < nbPar; i++)
|
||||
theParams->SetValue (i + 1, aParams (i));
|
||||
}
|
||||
|
||||
aParams.Append (theParMax);
|
||||
Standard_Integer nbPar = aParams.Length();
|
||||
//=======================================================================
|
||||
//function : fillParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillParams (Standard_Real theParMin,
|
||||
Standard_Real theParMax,
|
||||
Handle (TColStd_HArray1OfReal)& theParams,
|
||||
Standard_Integer theNbSamples)
|
||||
{
|
||||
Standard_Real PasU = theParMax - theParMin;
|
||||
Standard_Real U0 = PasU / theNbSamples / 100.;
|
||||
PasU = (PasU - U0) / (theNbSamples - 1);
|
||||
U0 = U0 / 2. + theParMin;
|
||||
theParams = new TColStd_HArray1OfReal (1, theNbSamples);
|
||||
Standard_Real U = U0;
|
||||
for (int NoU = 1; NoU <= theNbSamples; NoU++, U += PasU)
|
||||
theParams->SetValue (NoU, U);
|
||||
}
|
||||
|
||||
// In case of an insufficient number of points the grid will be built later
|
||||
if (nbPar < theNbSample)
|
||||
return;
|
||||
|
||||
theParams = new TColStd_HArray1OfReal (1, nbPar);
|
||||
for (i = 0; i < nbPar; i++)
|
||||
theParams->SetValue (i + 1, aParams (i));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : fillParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillParams (Standard_Real theParMin,
|
||||
Standard_Real theParMax,
|
||||
Handle (TColStd_HArray1OfReal)& theParams,
|
||||
Standard_Integer theNbSamples)
|
||||
{
|
||||
Standard_Real PasU = theParMax - theParMin;
|
||||
Standard_Real U0 = PasU / theNbSamples / 100.;
|
||||
PasU = (PasU - U0) / (theNbSamples - 1);
|
||||
U0 = U0 / 2. + theParMin;
|
||||
theParams = new TColStd_HArray1OfReal (1, theNbSamples);
|
||||
Standard_Real U = U0;
|
||||
for (int NoU = 1; NoU <= theNbSamples; NoU++, U += PasU)
|
||||
theParams->SetValue (NoU, U);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : fillSqDist
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillSqDist (Extrema_POnSurfParams& theParams,
|
||||
const gp_Pnt& thePoint)
|
||||
{
|
||||
if (theParams.GetSqrDistance() < -0.5)
|
||||
theParams.SetSqrDistance (theParams.Value().SquareDistance (thePoint));
|
||||
}
|
||||
//=======================================================================
|
||||
//function : fillSqDist
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void fillSqDist (Extrema_POnSurfParams& theParams,
|
||||
const gp_Pnt& thePoint)
|
||||
{
|
||||
if (theParams.GetSqrDistance() < -0.5)
|
||||
theParams.SetSqrDistance (theParams.Value().SquareDistance (thePoint));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -316,7 +293,7 @@ void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint)
|
||||
myFacePntParams->ChangeValue (0, iV).SetSqrDistance (RealLast());
|
||||
myFacePntParams->ChangeValue (myNbUSamples, iV).SetSqrDistance (RealLast());
|
||||
}
|
||||
|
||||
|
||||
for (int iU = 1; iU < myNbUSamples; ++iU)
|
||||
{
|
||||
myFacePntParams->ChangeValue (iU, 0).SetSqrDistance (RealLast());
|
||||
@@ -327,18 +304,20 @@ void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint)
|
||||
if (myTarget == Extrema_ExtFlag_MINMAX)
|
||||
{
|
||||
// Perform standard solution search (no tree)
|
||||
const Standard_Integer aNbCells = myGridBoxSet->Size();
|
||||
for (Standard_Integer i = 0; i < aNbCells; ++i)
|
||||
for (Standard_Integer iTarget = 0; iTarget < 2; ++iTarget)
|
||||
{
|
||||
FindSolution (i, 0.0, Extrema_ExtFlag_MIN);
|
||||
}
|
||||
for (Standard_Integer i = 0; i < aNbCells; ++i)
|
||||
{
|
||||
FindSolution (i, 0.0, Extrema_ExtFlag_MAX);
|
||||
const Extrema_ExtFlag aTarget = static_cast<Extrema_ExtFlag> (iTarget);
|
||||
for (int iU = 1; iU <= myNbUSamples; iU++)
|
||||
{
|
||||
for (int iV = 1; iV <= myNbVSamples; iV++)
|
||||
{
|
||||
FindSolution (iU, iV, aTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy solutions
|
||||
for (Standard_Integer i = 1; i <= myF.NbExt (); ++i)
|
||||
for (Standard_Integer i = 1; i <= myF.NbExt(); ++i)
|
||||
{
|
||||
mySolutions.push_back (Extrema_GenExtPS::ExtPSResult (myF.Point (i), myF.SquareDistance (i)));
|
||||
}
|
||||
@@ -404,62 +383,102 @@ void Extrema_GenExtPS::BuildTree()
|
||||
// so fill the tree with elements with empty boxes
|
||||
if (myGridBoxSet.IsNull())
|
||||
{
|
||||
myGridBoxSet = new BVH_BoxSet<Standard_Real, 3, GridCell>(new BVH_LinearBuilder<Standard_Real, 3>());
|
||||
// Builder for low-level BVH sets
|
||||
opencascade::handle<BVH_LinearBuilder<Standard_Real, 3> > aLBuilder = new BVH_LinearBuilder<Standard_Real, 3>();
|
||||
|
||||
myGridBoxSet->SetSize (myNbUSamples * myNbVSamples);
|
||||
myGridBoxSet = new BVH_IndexedBoxSet<Standard_Real, 3, Handle (Extrema_GenExtPS_GridCellBoxSet)> (
|
||||
new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle));
|
||||
|
||||
for (int iU = 1; iU <= myNbUSamples; iU++)
|
||||
// create hierarchy of BVH trees
|
||||
const Standard_Integer aCoeff = static_cast<Standard_Integer> (Sqrt (Min (myNbUSamples, myNbVSamples)));
|
||||
const Standard_Integer aNbUT = myNbUSamples / aCoeff;
|
||||
const Standard_Integer aNbVT = myNbVSamples / aCoeff;
|
||||
const Standard_Integer aNbU = myNbUSamples / aNbUT;
|
||||
const Standard_Integer aNbV = myNbVSamples / aNbVT;
|
||||
const Standard_Integer aSize = aNbU * aNbV;
|
||||
|
||||
myGridBoxSet->SetSize (aNbUT * aNbVT);
|
||||
|
||||
Standard_Integer U1 = 1, V1 = 1, U2 = 1, V2 = 1;
|
||||
for (Standard_Integer iUT = 1; iUT <= aNbUT; ++iUT)
|
||||
{
|
||||
for (int iV = 1; iV <= myNbVSamples; iV++)
|
||||
U2 = (iUT == aNbUT) ? myNbUSamples : iUT * aNbU;
|
||||
for (Standard_Integer iVT = 1; iVT <= aNbVT; ++iVT)
|
||||
{
|
||||
myGridBoxSet->Add (GridCell (iU, iV), BVH_Box<Standard_Real, 3>());
|
||||
Handle (Extrema_GenExtPS_GridCellBoxSet) aGridSet = new Extrema_GenExtPS_GridCellBoxSet (aLBuilder);
|
||||
aGridSet->SetSize (aSize);
|
||||
|
||||
V2 = (iVT == aNbVT) ? myNbVSamples : iVT * aNbV;
|
||||
for (Standard_Integer iU = U1; iU <= U2; ++iU)
|
||||
{
|
||||
for (Standard_Integer iV = V1; iV <= V2; ++iV)
|
||||
{
|
||||
aGridSet->Add (GridCell (iU, iV), BVH_Box<Standard_Real, 3>());
|
||||
}
|
||||
}
|
||||
V1 = V2 + 1;
|
||||
|
||||
myGridBoxSet->Add (aGridSet, BVH_Box<Standard_Real, 3>());
|
||||
}
|
||||
U1 = U2 + 1;
|
||||
V1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (myGridBoxSet->IsDirty() && myTarget != Extrema_ExtFlag_MINMAX)
|
||||
{
|
||||
// Fill the tree with the real boxes
|
||||
const Standard_Integer aNbCells = myGridBoxSet->Size();
|
||||
for (Standard_Integer iCell = 0; iCell < aNbCells; ++iCell)
|
||||
const Standard_Integer aNbSets = myGridBoxSet->Size();
|
||||
for (Standard_Integer iSet = 0; iSet < aNbSets; ++iSet)
|
||||
{
|
||||
const GridCell& aCell = myGridBoxSet->Element (iCell);
|
||||
Standard_Integer iU = aCell.myUInd, iV = aCell.myVInd;
|
||||
Handle (Extrema_GenExtPS_GridCellBoxSet) aGridSet = myGridBoxSet->Element (iSet);
|
||||
|
||||
Standard_Integer aUCoeff = (iU < myNbUSamples) ? 1 : 0;
|
||||
Standard_Integer aVCoeff = (iV < myNbVSamples) ? 1 : 0;
|
||||
|
||||
// Build box for the cell
|
||||
Bnd_Box aBox;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
for (int j = 0; j < 2; ++j)
|
||||
aBox.Add (myPoints->Value (iU + i * aUCoeff, iV + j * aVCoeff).Value());
|
||||
|
||||
aBox.Enlarge (Precision::Confusion());
|
||||
|
||||
const Extrema_POnSurf& aPMin = myPoints->Value (iU, iV);
|
||||
const Extrema_POnSurf& aPMax = myPoints->Value (iU + aUCoeff, iV + aVCoeff);
|
||||
|
||||
Standard_Real U1, V1, U2, V2;
|
||||
aPMin.Parameter (U1, V1);
|
||||
aPMax.Parameter (U2, V2);
|
||||
|
||||
// Enlarge box to make sure the whole cell is covered
|
||||
if (U1 != U2 || V1 != V2)
|
||||
// Box of the set
|
||||
Bnd_Box aSetBox;
|
||||
const Standard_Integer aNbCells = aGridSet->Size();
|
||||
for (Standard_Integer iCell = 0; iCell < aNbCells; ++iCell)
|
||||
{
|
||||
gp_Pnt aPMid = myS->Value ((U1 + U2) * 0.5, (V1 + V2) * 0.5);
|
||||
aBox.Add (aPMid);
|
||||
const GridCell& aCell = aGridSet->Element (iCell);
|
||||
Standard_Integer iU = aCell.UIndex, iV = aCell.VIndex;
|
||||
|
||||
gp_Vec aDir(aPMin.Value(), aPMax.Value());
|
||||
if (aDir.SquareMagnitude() > gp::Resolution())
|
||||
Standard_Integer aUCoeff = (iU < myNbUSamples) ? 1 : 0;
|
||||
Standard_Integer aVCoeff = (iV < myNbVSamples) ? 1 : 0;
|
||||
|
||||
// Build box for the cell
|
||||
Bnd_Box aGridBox;
|
||||
aGridBox.Add (myPoints->Value (iU, iV).Value());
|
||||
aGridBox.Add (myPoints->Value (iU + 1, iV).Value());
|
||||
aGridBox.Add (myPoints->Value (iU, iV + 1).Value());
|
||||
aGridBox.Add (myPoints->Value (iU + 1, iV + 1).Value());
|
||||
aGridBox.Enlarge (Precision::Confusion());
|
||||
|
||||
const Extrema_POnSurf& aPMin = myPoints->Value (iU, iV);
|
||||
const Extrema_POnSurf& aPMax = myPoints->Value (iU + aUCoeff, iV + aVCoeff);
|
||||
|
||||
Standard_Real U1, V1, U2, V2;
|
||||
aPMin.Parameter (U1, V1);
|
||||
aPMax.Parameter (U2, V2);
|
||||
|
||||
// Enlarge box to make sure the whole cell is covered
|
||||
if (U1 != U2 || V1 != V2)
|
||||
{
|
||||
aBox.Enlarge (gp_Lin (aPMin.Value(), aDir).Distance (aPMid));
|
||||
}
|
||||
}
|
||||
gp_Pnt aPMid = myS->Value ((U1 + U2) * 0.5, (V1 + V2) * 0.5);
|
||||
aGridBox.Add (aPMid);
|
||||
|
||||
myGridBoxSet->UpdateBox (iCell, Bnd_Tools::Bnd2BVH (aBox));
|
||||
gp_Vec aDir (aPMin.Value(), aPMax.Value());
|
||||
if (aDir.SquareMagnitude() > gp::Resolution())
|
||||
{
|
||||
aGridBox.Enlarge (gp_Lin (aPMin.Value(), aDir).Distance (aPMid));
|
||||
}
|
||||
}
|
||||
aGridSet->UpdateBox (iCell, Bnd_Tools::Bnd2BVH (aGridBox));
|
||||
|
||||
aSetBox.Add (aGridBox);
|
||||
}
|
||||
myGridBoxSet->UpdateBox (iSet, Bnd_Tools::Bnd2BVH (aSetBox));
|
||||
}
|
||||
|
||||
// Build only high level BVH tree
|
||||
myGridBoxSet->Build();
|
||||
}
|
||||
}
|
||||
@@ -485,8 +504,8 @@ void Extrema_GenExtPS::GetGridPoints (const Adaptor3d_Surface& theSurf)
|
||||
aBspl->UKnots (aUKnots);
|
||||
TColStd_Array1OfReal aVKnots (1, aBspl->NbVKnots());
|
||||
aBspl->VKnots (aVKnots);
|
||||
fillParams (aUKnots, aBspl->UDegree(), myUMin, myUMax, myUParams, myNbUSamples);
|
||||
fillParams (aVKnots, aBspl->VDegree(), myVMin, myVMax, myVParams, myNbVSamples);
|
||||
fillParams (aUKnots, aBspl->UDegree(), myUMin, myUMax, myNbUSamples, myUParams);
|
||||
fillParams (aVKnots, aBspl->VDegree(), myVMin, myVMax, myNbVSamples, myVParams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,8 +518,8 @@ void Extrema_GenExtPS::GetGridPoints (const Adaptor3d_Surface& theSurf)
|
||||
TColStd_Array1OfReal aUKnots (1, 2);
|
||||
TColStd_Array1OfReal aVKnots (1, 2);
|
||||
aBezier->Bounds (aUKnots (1), aUKnots (2), aVKnots (1), aVKnots (2));
|
||||
fillParams (aUKnots, aBezier->UDegree(), myUMin, myUMax, myUParams, myNbUSamples);
|
||||
fillParams (aVKnots, aBezier->VDegree(), myVMin, myVMax, myVParams, myNbVSamples);
|
||||
fillParams (aUKnots, aBezier->UDegree(), myUMin, myUMax, myNbUSamples, myUParams);
|
||||
fillParams (aVKnots, aBezier->VDegree(), myVMin, myVMax, myNbVSamples, myVParams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,9 +554,9 @@ void Extrema_GenExtPS::GetGridPoints (const Adaptor3d_Surface& theSurf)
|
||||
if (anArrKnots.IsNull())
|
||||
return;
|
||||
if (theSurf.GetType() == GeomAbs_SurfaceOfRevolution)
|
||||
fillParams (anArrKnots->Array1(), aDegree, myVMin, myVMax, myVParams, myNbVSamples);
|
||||
fillParams (anArrKnots->Array1(), aDegree, myVMin, myVMax, myNbVSamples, myVParams);
|
||||
else
|
||||
fillParams (anArrKnots->Array1(), aDegree, myUMin, myUMax, myUParams, myNbUSamples);
|
||||
fillParams (anArrKnots->Array1(), aDegree, myUMin, myUMax, myNbUSamples, myUParams);
|
||||
}
|
||||
|
||||
// Update the number of points in sample
|
||||
@@ -605,27 +624,40 @@ Standard_Boolean Extrema_GenExtPS::IsMetricBetter (const Standard_Real& theLeft,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Extrema_GenExtPS::Accept (const Standard_Integer theIndex,
|
||||
const Standard_Real& theMetric)
|
||||
const Standard_Real&)
|
||||
{
|
||||
return FindSolution (theIndex, theMetric, myTarget);
|
||||
if (myBVHSet == NULL)
|
||||
{
|
||||
Handle (Extrema_GenExtPS_GridCellBoxSet) aGridSet = myGridBoxSet->Element (theIndex);
|
||||
aGridSet->Build();
|
||||
// Set low-level BVH set for inner selection
|
||||
SetBVHSet (aGridSet.get());
|
||||
Standard_Integer aNb = Select();
|
||||
// Unset the inner set and continue with high level BVH traverse
|
||||
SetBVHSet (NULL);
|
||||
return aNb > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
GridCell aCell = myBVHSet->Element (theIndex);
|
||||
return FindSolution (aCell.UIndex, aCell.VIndex, myTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Accept
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex,
|
||||
const Standard_Real&,
|
||||
Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theNU,
|
||||
const Standard_Integer theNV,
|
||||
const Extrema_ExtFlag theTarget)
|
||||
{
|
||||
const GridCell& aCell = myGridBoxSet->Element (theIndex);
|
||||
|
||||
// Fill corner points with square distance to myPoint
|
||||
Standard_Integer nU = aCell.myUInd, nV = aCell.myVInd;
|
||||
Extrema_POnSurfParams& aParam00 = myPoints->ChangeValue (nU, nV);
|
||||
Extrema_POnSurfParams& aParam01 = myPoints->ChangeValue (nU, nV + 1);
|
||||
Extrema_POnSurfParams& aParam10 = myPoints->ChangeValue (nU + 1, nV);
|
||||
Extrema_POnSurfParams& aParam11 = myPoints->ChangeValue (nU + 1, nV + 1);
|
||||
Extrema_POnSurfParams& aParam00 = myPoints->ChangeValue (theNU, theNV);
|
||||
Extrema_POnSurfParams& aParam01 = myPoints->ChangeValue (theNU, theNV + 1);
|
||||
Extrema_POnSurfParams& aParam10 = myPoints->ChangeValue (theNU + 1, theNV);
|
||||
Extrema_POnSurfParams& aParam11 = myPoints->ChangeValue (theNU + 1, theNV + 1);
|
||||
|
||||
gp_Pnt aPoint (myPoint.x(), myPoint.y(), myPoint.z());
|
||||
|
||||
@@ -634,15 +666,15 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex
|
||||
fillSqDist (aParam10, aPoint);
|
||||
fillSqDist (aParam11, aPoint);
|
||||
|
||||
if (nU != myNbUSamples && nV != myNbVSamples &&
|
||||
(theTarget == Extrema_ExtFlag_MIN || theTarget == Extrema_ExtFlag_MINMAX))
|
||||
if (theNU != myNbUSamples && theNV != myNbVSamples &&
|
||||
(theTarget == Extrema_ExtFlag_MIN || theTarget == Extrema_ExtFlag_MINMAX))
|
||||
{
|
||||
// Find minimum
|
||||
|
||||
const Extrema_POnSurfParams& aParam = ComputeFaceParameters (nU, nV, aPoint);
|
||||
const Extrema_POnSurfParams& aParam = ComputeFaceParameters (theNU, theNV, aPoint);
|
||||
|
||||
Standard_Boolean isMin = Standard_False;
|
||||
Extrema_ElementType anElemType = aParam.GetElementType ();
|
||||
Extrema_ElementType anElemType = aParam.GetElementType();
|
||||
|
||||
if (anElemType == Extrema_Face)
|
||||
{
|
||||
@@ -665,19 +697,19 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex
|
||||
else if (anElemType == Extrema_Node)
|
||||
{
|
||||
isMin = (iU == 1 || iU == myNbUSamples) &&
|
||||
(iV == 1 || iV == myNbVSamples);
|
||||
(iV == 1 || iV == myNbVSamples);
|
||||
}
|
||||
|
||||
if (!isMin)
|
||||
{
|
||||
// This is a middle element.
|
||||
if (anElemType == Extrema_UIsoEdge ||
|
||||
(anElemType == Extrema_Node && (iU == 1 || iU == myNbUSamples)))
|
||||
(anElemType == Extrema_Node && (iU == 1 || iU == myNbUSamples)))
|
||||
{
|
||||
// Check the down face.
|
||||
const Extrema_POnSurfParams &aDownParam = ComputeFaceParameters (nU, nV - 1, aPoint);
|
||||
const Extrema_POnSurfParams &aDownParam = ComputeFaceParameters (theNU, theNV - 1, aPoint);
|
||||
|
||||
if (aDownParam.GetElementType () == anElemType)
|
||||
if (aDownParam.GetElementType() == anElemType)
|
||||
{
|
||||
Standard_Integer iU2, iV2;
|
||||
aDownParam.GetIndices (iU2, iV2);
|
||||
@@ -685,32 +717,32 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex
|
||||
}
|
||||
}
|
||||
else if (anElemType == Extrema_VIsoEdge ||
|
||||
(anElemType == Extrema_Node && (iV == 1 || iV == myNbVSamples)))
|
||||
(anElemType == Extrema_Node && (iV == 1 || iV == myNbVSamples)))
|
||||
{
|
||||
// Check the right face.
|
||||
const Extrema_POnSurfParams &aRightParam = ComputeFaceParameters (nU - 1, nV, aPoint);
|
||||
const Extrema_POnSurfParams &aRightParam = ComputeFaceParameters (theNU - 1, theNV, aPoint);
|
||||
|
||||
if (aRightParam.GetElementType () == anElemType)
|
||||
if (aRightParam.GetElementType() == anElemType)
|
||||
{
|
||||
Standard_Integer iU2, iV2;
|
||||
aRightParam.GetIndices (iU2, iV2);
|
||||
isMin = (iU == iU2 && iV == iV2);
|
||||
}
|
||||
}
|
||||
else if (iU == nU && iV == nV)
|
||||
else if (iU == theNU && iV == theNV)
|
||||
{
|
||||
// Check the lower-left node. For this purpose it is necessary
|
||||
// to check lower-left, lower and left faces.
|
||||
isMin = Standard_True;
|
||||
|
||||
const Extrema_POnSurfParams *anOtherParam[3] = {
|
||||
&ComputeFaceParameters (nU, nV - 1, aPoint), // Down
|
||||
&ComputeFaceParameters (nU - 1, nV - 1, aPoint), // Lower-left
|
||||
&ComputeFaceParameters (nU - 1, nV, aPoint) }; // Left
|
||||
&ComputeFaceParameters (theNU, theNV - 1, aPoint), // Down
|
||||
&ComputeFaceParameters (theNU - 1, theNV - 1, aPoint), // Lower-left
|
||||
&ComputeFaceParameters (theNU - 1, theNV, aPoint) }; // Left
|
||||
|
||||
for (int i = 0; i < 3 && isMin; i++)
|
||||
{
|
||||
if (anOtherParam[i]->GetElementType () == Extrema_Node)
|
||||
if (anOtherParam[i]->GetElementType() == Extrema_Node)
|
||||
{
|
||||
Standard_Integer iU2, iV2;
|
||||
anOtherParam[i]->GetIndices (iU2, iV2);
|
||||
@@ -734,14 +766,14 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex
|
||||
if (theTarget == Extrema_ExtFlag_MAX || theTarget == Extrema_ExtFlag_MINMAX)
|
||||
{
|
||||
// Find maximum
|
||||
Extrema_POnSurfParams &aParam1 = myPoints->ChangeValue (nU - 1, nV - 1);
|
||||
Extrema_POnSurfParams &aParam2 = myPoints->ChangeValue (nU - 1, nV);
|
||||
Extrema_POnSurfParams &aParam3 = myPoints->ChangeValue (nU - 1, nV + 1);
|
||||
Extrema_POnSurfParams &aParam4 = myPoints->ChangeValue (nU, nV - 1);
|
||||
Extrema_POnSurfParams &aParam5 = myPoints->ChangeValue (nU, nV + 1);
|
||||
Extrema_POnSurfParams &aParam6 = myPoints->ChangeValue (nU + 1, nV - 1);
|
||||
Extrema_POnSurfParams &aParam7 = myPoints->ChangeValue (nU + 1, nV);
|
||||
Extrema_POnSurfParams &aParam8 = myPoints->ChangeValue (nU + 1, nV + 1);
|
||||
Extrema_POnSurfParams &aParam1 = myPoints->ChangeValue (theNU - 1, theNV - 1);
|
||||
Extrema_POnSurfParams &aParam2 = myPoints->ChangeValue (theNU - 1, theNV);
|
||||
Extrema_POnSurfParams &aParam3 = myPoints->ChangeValue (theNU - 1, theNV + 1);
|
||||
Extrema_POnSurfParams &aParam4 = myPoints->ChangeValue (theNU, theNV - 1);
|
||||
Extrema_POnSurfParams &aParam5 = myPoints->ChangeValue (theNU, theNV + 1);
|
||||
Extrema_POnSurfParams &aParam6 = myPoints->ChangeValue (theNU + 1, theNV - 1);
|
||||
Extrema_POnSurfParams &aParam7 = myPoints->ChangeValue (theNU + 1, theNV);
|
||||
Extrema_POnSurfParams &aParam8 = myPoints->ChangeValue (theNU + 1, theNV + 1);
|
||||
|
||||
fillSqDist (aParam1, aPoint);
|
||||
fillSqDist (aParam2, aPoint);
|
||||
@@ -752,7 +784,7 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theIndex
|
||||
Standard_Real aDist = aParam00.GetSqrDistance();
|
||||
|
||||
if ((aParam1.GetSqrDistance() <= aDist) &&
|
||||
(aParam2.GetSqrDistance() <= aDist) &&
|
||||
(aParam2.GetSqrDistance() <= aDist) &&
|
||||
(aParam3.GetSqrDistance() <= aDist) &&
|
||||
(aParam4.GetSqrDistance() <= aDist) &&
|
||||
(aParam5.GetSqrDistance() <= aDist) &&
|
||||
@@ -798,13 +830,13 @@ void Extrema_GenExtPS::FindSolution (const Extrema_POnSurfParams &theParams)
|
||||
{
|
||||
for (Standard_Integer i = aNbFuncSol + 1; i <= myF.NbExt(); ++i)
|
||||
{
|
||||
Standard_Real aDist = myF.SquareDistance(i);
|
||||
Standard_Real aDist = myF.SquareDistance (i);
|
||||
if ((myTarget == Extrema_ExtFlag_MIN && aDist <= mySqDistance) ||
|
||||
(myTarget == Extrema_ExtFlag_MAX && aDist >= mySqDistance))
|
||||
(myTarget == Extrema_ExtFlag_MAX && aDist >= mySqDistance))
|
||||
{
|
||||
if (aDist != mySqDistance)
|
||||
mySolutions.clear();
|
||||
mySolutions.push_back (Extrema_GenExtPS::ExtPSResult (myF.Point(i), aDist));
|
||||
mySolutions.push_back (Extrema_GenExtPS::ExtPSResult (myF.Point (i), aDist));
|
||||
mySqDistance = aDist;
|
||||
}
|
||||
}
|
||||
@@ -823,7 +855,7 @@ const Extrema_POnSurfParams& Extrema_GenExtPS::
|
||||
const gp_Pnt &thePoint,
|
||||
const Standard_Real theDiffTol)
|
||||
{
|
||||
const Handle(Extrema_HArray2OfPOnSurfParams)& anEdgeParams = IsUEdge ? myUEdgePntParams : myVEdgePntParams;
|
||||
const Handle (Extrema_HArray2OfPOnSurfParams)& anEdgeParams = IsUEdge ? myUEdgePntParams : myVEdgePntParams;
|
||||
Standard_Integer iU, iV;
|
||||
theParam0.GetIndices (iU, iV);
|
||||
if (anEdgeParams->Value (iU, iV).GetSqrDistance() < 0)
|
||||
@@ -985,14 +1017,14 @@ const Extrema_POnSurfParams& Extrema_GenExtPS::
|
||||
}
|
||||
}
|
||||
|
||||
return myFacePntParams->Value(theU, theV);
|
||||
return myFacePntParams->Value (theU, theV);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbExt
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer Extrema_GenExtPS::NbExt () const
|
||||
Standard_Integer Extrema_GenExtPS::NbExt() const
|
||||
{
|
||||
if (!IsDone())
|
||||
{
|
||||
@@ -1012,7 +1044,7 @@ Standard_Real Extrema_GenExtPS::SquareDistance (const Standard_Integer N) const
|
||||
throw Standard_OutOfRange();
|
||||
}
|
||||
|
||||
return mySolutions[N - 1].mySqDistance;
|
||||
return mySolutions[N - 1].SqDistance;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1026,5 +1058,5 @@ const Extrema_POnSurf& Extrema_GenExtPS::Point (const Standard_Integer N) const
|
||||
throw Standard_OutOfRange();
|
||||
}
|
||||
|
||||
return mySolutions[N - 1].myUV;
|
||||
return mySolutions[N - 1].UV;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <Adaptor3d_SurfacePtr.hxx>
|
||||
#include <BVH_BoxSet.hxx>
|
||||
#include <BVH_IndexedBoxSet.hxx>
|
||||
#include <BVH_Traverse.hxx>
|
||||
#include <Extrema_HArray2OfPOnSurfParams.hxx>
|
||||
#include <Extrema_FuncPSNorm.hxx>
|
||||
@@ -42,6 +43,22 @@ class Extrema_POnSurf;
|
||||
class Extrema_POnSurfParams;
|
||||
|
||||
|
||||
//! Grid cell defined by (U, V) indices of the minimal
|
||||
//! corner of the cell
|
||||
struct GridCell
|
||||
{
|
||||
Standard_Integer UIndex; //!< U index of the minimal corner
|
||||
Standard_Integer VIndex; //!< V index of the minimal corner
|
||||
|
||||
GridCell (Standard_Integer theUInd = -1, Standard_Integer theVInd = -1)
|
||||
: UIndex (theUInd), VIndex (theVInd)
|
||||
{}
|
||||
};
|
||||
|
||||
//! typedef to BVH tree of the grid cells
|
||||
typedef BVH_BoxSet <Standard_Real, 3, GridCell> Extrema_GenExtPS_GridCellBoxSet;
|
||||
|
||||
|
||||
//! It calculates the extreme distances between a point and a surface.
|
||||
//! These distances can be minimum or maximum.
|
||||
//!
|
||||
@@ -68,28 +85,14 @@ class Extrema_POnSurfParams;
|
||||
//! The class is BVH enhanced - the grid cells are stored into BVH-organized
|
||||
//! structure. Depending on the Extrema target the traverse of the BVH tree
|
||||
//! is different.
|
||||
class Extrema_GenExtPS: protected BVH_Traverse <Standard_Real, 3>,
|
||||
public Standard_Transient
|
||||
class Extrema_GenExtPS:
|
||||
protected BVH_Traverse <Standard_Real, 3, Extrema_GenExtPS_GridCellBoxSet>,
|
||||
public Standard_Transient
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT (Extrema_GenExtPS, Standard_Transient)
|
||||
|
||||
public: //! @name public types
|
||||
|
||||
//! Grid cell is defined just by (U, V) indices of the minimal
|
||||
//! corner of the cell.
|
||||
struct GridCell
|
||||
{
|
||||
GridCell (Standard_Integer theUInd = -1, Standard_Integer theVInd = -1)
|
||||
: myUInd (theUInd), myVInd (theVInd)
|
||||
{}
|
||||
|
||||
Standard_Integer myUInd; //!< U index of the minimal corner
|
||||
Standard_Integer myVInd; //!< V index of the minimal corner
|
||||
};
|
||||
|
||||
|
||||
public: //! @name Constructors computing the distances
|
||||
|
||||
//! Constructor for computation of the distances between specified point and surface.
|
||||
@@ -188,7 +191,7 @@ public: //! @name Specifying the search options
|
||||
//! Specifies what solutions are necessary:
|
||||
//! - *Extrema_ExtFlag_MIN* - only minimal solutions
|
||||
//! - *Extrema_ExtFlag_MAX* - only maximal solutions
|
||||
//! - *Extrema_ExtFlag_MINMAX - all solutions.
|
||||
//! - *Extrema_ExtFlag_MINMAX - all solutions (default value).
|
||||
void SetTarget (const Extrema_ExtFlag theTarget)
|
||||
{
|
||||
myTarget = theTarget;
|
||||
@@ -217,52 +220,29 @@ public: //! @name Performing projection
|
||||
Standard_EXPORT void Perform (const gp_Pnt& theP);
|
||||
|
||||
|
||||
public: //! @name Rules for BVH traverse
|
||||
|
||||
//! Rejection of the node by bounding box.
|
||||
//! Metric is computed to choose the best branch.
|
||||
//! Returns true if the node should be rejected, false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
RejectNode (const BVH_Vec3d& theCornerMin,
|
||||
const BVH_Vec3d& theCornerMax,
|
||||
Standard_Real& theMetric) const Standard_OVERRIDE;
|
||||
|
||||
//! Rejects the node by the metric
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
RejectMetric (const Standard_Real& theMetric) const Standard_OVERRIDE;
|
||||
|
||||
//! Compares the two metrics and chooses the best one.
|
||||
//! Returns true if the first metric is better than the second,
|
||||
//! false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
IsMetricBetter (const Standard_Real& theLeft,
|
||||
const Standard_Real& theRight) const Standard_OVERRIDE;
|
||||
|
||||
//! Leaf element acceptance.
|
||||
//! Metric of the parent leaf-node is passed to avoid the check on the
|
||||
//! element and accept it unconditionally.
|
||||
//! Returns true if the element has been accepted, false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
Accept (const Standard_Integer theIndex,
|
||||
const Standard_Real& theMetric) Standard_OVERRIDE;
|
||||
|
||||
|
||||
public: //! @name Getting the results
|
||||
|
||||
//! Returns True if the distances are found.
|
||||
Standard_Boolean IsDone() const { return myIsDone; }
|
||||
|
||||
//! Returns the number of extrema distances found.
|
||||
//! @throws StdFail_NotDone if extrema search has failed.
|
||||
Standard_EXPORT Standard_Integer NbExt() const;
|
||||
|
||||
//! Returns the value of the Nth resulting square distance.
|
||||
//! @throws StdFail_NotDone if extrema search has failed.
|
||||
//! @throws Standard_OutOfRange if given index is out of range of found
|
||||
//! solutions ((N < 1) || (N > NbExt()).
|
||||
Standard_EXPORT Standard_Real SquareDistance (const Standard_Integer theN) const;
|
||||
|
||||
//! Returns the point of the Nth resulting distance.
|
||||
//! @throws StdFail_NotDone if extrema search has failed.
|
||||
//! @throws Standard_OutOfRange if given index is out of range of found
|
||||
//! solutions ((N < 1) || (N > NbExt()).
|
||||
Standard_EXPORT const Extrema_POnSurf& Point (const Standard_Integer theN) const;
|
||||
|
||||
|
||||
private: //! @name Private methods performing the job
|
||||
protected: //! @name Protected methods performing the job
|
||||
|
||||
//! Creation of grid of parametric points (sampling of the surface)
|
||||
Standard_EXPORT void BuildGrid();
|
||||
@@ -291,39 +271,72 @@ private: //! @name Private methods performing the job
|
||||
const Standard_Real theDiffTol);
|
||||
|
||||
//! Looks for the Min or Max Solution (depending on the given target).
|
||||
Standard_EXPORT Standard_Boolean FindSolution (const Standard_Integer theIndex,
|
||||
const Standard_Real& theMetric,
|
||||
Standard_EXPORT Standard_Boolean FindSolution (const Standard_Integer theUIndex,
|
||||
const Standard_Integer theVIndex,
|
||||
const Extrema_ExtFlag theTarget);
|
||||
|
||||
//! structure to keep the results
|
||||
|
||||
protected: //! @name Rules for BVH traverse
|
||||
|
||||
//! Rejection of the node by bounding box.
|
||||
//! Metric is computed to choose the best branch.
|
||||
//! Returns true if the node should be rejected, false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
RejectNode (const BVH_Vec3d& theCornerMin,
|
||||
const BVH_Vec3d& theCornerMax,
|
||||
Standard_Real& theMetric) const Standard_OVERRIDE;
|
||||
|
||||
//! Rejects the node by the metric
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
RejectMetric (const Standard_Real& theMetric) const Standard_OVERRIDE;
|
||||
|
||||
//! Compares the two metrics and chooses the best one.
|
||||
//! Returns true if the first metric is better than the second,
|
||||
//! false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
IsMetricBetter (const Standard_Real& theLeft,
|
||||
const Standard_Real& theRight) const Standard_OVERRIDE;
|
||||
|
||||
//! Leaf element acceptance.
|
||||
//! Metric of the parent leaf-node is passed to avoid the check on the
|
||||
//! element and accept it unconditionally.
|
||||
//! Returns true if the element has been accepted, false otherwise.
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
Accept (const Standard_Integer theIndex,
|
||||
const Standard_Real& theMetric) Standard_OVERRIDE;
|
||||
|
||||
protected: //! @name Auxiliary types
|
||||
|
||||
//! Structure to keep and sort the results
|
||||
struct ExtPSResult
|
||||
{
|
||||
ExtPSResult ()
|
||||
: mySqDistance (-1)
|
||||
Extrema_POnSurf UV; //! UV coordinates of extrema solution
|
||||
Standard_Real SqDistance; //! Square distance to target point
|
||||
|
||||
ExtPSResult()
|
||||
: SqDistance (-1)
|
||||
{}
|
||||
|
||||
ExtPSResult (const Extrema_POnSurf& theUV,
|
||||
const Standard_Real theSqDist)
|
||||
: myUV (theUV),
|
||||
mySqDistance (theSqDist)
|
||||
: UV (theUV),
|
||||
SqDistance (theSqDist)
|
||||
{}
|
||||
|
||||
//! IsLess operator
|
||||
Standard_Boolean operator< (const ExtPSResult& Other) const
|
||||
{
|
||||
if (mySqDistance != Other.mySqDistance)
|
||||
return mySqDistance < Other.mySqDistance;
|
||||
if (SqDistance != Other.SqDistance)
|
||||
return SqDistance < Other.SqDistance;
|
||||
|
||||
Standard_Real U1, U2, V1, V2;
|
||||
myUV.Parameter (U1, V1);
|
||||
Other.myUV.Parameter (U2, V2);
|
||||
UV.Parameter (U1, V1);
|
||||
Other.UV.Parameter (U2, V2);
|
||||
return (U1 < U2 || (U1 == U2 && V1 < V2));
|
||||
}
|
||||
|
||||
Extrema_POnSurf myUV;
|
||||
Standard_Real mySqDistance;
|
||||
};
|
||||
|
||||
private: //! @name Fields
|
||||
protected: //! @name Fields
|
||||
|
||||
// Inputs
|
||||
NCollection_Vec3<Standard_Real> myPoint; //!< Point
|
||||
@@ -354,11 +367,13 @@ private: //! @name Fields
|
||||
Handle(Extrema_HArray2OfPOnSurfParams) myVEdgePntParams;
|
||||
|
||||
Standard_Real mySqDistance; //!< Min/Max found square distance used in BVH tree traverse
|
||||
opencascade::handle <BVH_BoxSet <Standard_Real, 3, GridCell>> myGridBoxSet; //!< BVH-organized grid
|
||||
opencascade::handle
|
||||
<BVH_IndexedBoxSet<Standard_Real, 3, Handle(Extrema_GenExtPS_GridCellBoxSet)> > myGridBoxSet; //!< High-level BVH of BVH organized grid cells
|
||||
|
||||
// Results
|
||||
std::vector <ExtPSResult> mySolutions;
|
||||
Standard_Boolean myIsDone; //!< IsDone flag
|
||||
std::vector <ExtPSResult> mySolutions; //!< Found solutions (sorted first by distance to target point,
|
||||
//! second by the ascending U,V coordinates)
|
||||
Standard_Boolean myIsDone; //!< Done/Not done flag
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE (Extrema_GenExtPS, Standard_Transient)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
GCPnts.cxx
|
||||
GCPnts.hxx
|
||||
GCPnts_AbscissaPoint.cxx
|
||||
GCPnts_AbscissaPoint.pxx
|
||||
GCPnts_AbscissaPoint.hxx
|
||||
|
54
src/GCPnts/GCPnts.cxx
Normal file
54
src/GCPnts/GCPnts.cxx
Normal file
@@ -0,0 +1,54 @@
|
||||
// Created on: 2020-05-18
|
||||
// Copyright (c) 1999-2020 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <GCPnts.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
//=======================================================================
|
||||
//function : FillParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void GCPnts::FillParams (const TColStd_Array1OfReal& theKnots,
|
||||
const Standard_Integer theDegree,
|
||||
const Standard_Real theParMin,
|
||||
const Standard_Real theParMax,
|
||||
NCollection_Vector<Standard_Real>& theParams)
|
||||
{
|
||||
Standard_Real aPrevPar = theParMin;
|
||||
theParams.Append (aPrevPar);
|
||||
|
||||
Standard_Integer aNbP = Max (theDegree, 1);
|
||||
|
||||
for (Standard_Integer i = 1;
|
||||
(i < theKnots.Length()) && (theKnots (i) < (theParMax - Precision::PConfusion())); ++i)
|
||||
{
|
||||
if (theKnots (i + 1) < theParMin + Precision::PConfusion())
|
||||
continue;
|
||||
|
||||
Standard_Real aStep = (theKnots (i + 1) - theKnots (i)) / aNbP;
|
||||
for (Standard_Integer k = 1; k <= aNbP ; ++k)
|
||||
{
|
||||
Standard_Real aPar = theKnots (i) + k * aStep;
|
||||
if (aPar > theParMax - Precision::PConfusion())
|
||||
break;
|
||||
|
||||
if (aPar > aPrevPar + Precision::PConfusion())
|
||||
{
|
||||
theParams.Append (aPar);
|
||||
aPrevPar = aPar;
|
||||
}
|
||||
}
|
||||
}
|
||||
theParams.Append (theParMax);
|
||||
}
|
35
src/GCPnts/GCPnts.hxx
Normal file
35
src/GCPnts/GCPnts.hxx
Normal file
@@ -0,0 +1,35 @@
|
||||
// Created on: 2020-05-18
|
||||
// Copyright (c) 1999-2020 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _GCPnts_HeaderFile
|
||||
#define _GCPnts_HeaderFile
|
||||
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
|
||||
//! The GCPnts package provides general utilities for
|
||||
//! Curves analysis.
|
||||
class GCPnts
|
||||
{
|
||||
public:
|
||||
|
||||
//! Fills <theParams> vector with sampling parameters on the curve
|
||||
Standard_EXPORT static void FillParams (const TColStd_Array1OfReal& theKnots,
|
||||
const Standard_Integer theDegree,
|
||||
const Standard_Real theParMin,
|
||||
const Standard_Real theParMax,
|
||||
NCollection_Vector<Standard_Real>& theParams);
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user