mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
# Perform localized extrema search in ComputeApproxOnPolarSurface
This commit is contained in:
@@ -112,25 +112,25 @@ void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
|
||||
Standard_Real U, V;
|
||||
PS.Parameter(U, V);
|
||||
if (myS->IsUPeriodic()) {
|
||||
U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
|
||||
U = ElCLib::InPeriod(U, myLocUMin, myLocUMin + myS->UPeriod());
|
||||
|
||||
// Handle trimmed surfaces.
|
||||
if (U > myusup + mytolu)
|
||||
if (U > myLocUMax + mytolu)
|
||||
U -= myS->UPeriod();
|
||||
if (U < myuinf - mytolu)
|
||||
if (U < myLocUMin - mytolu)
|
||||
U += myS->UPeriod();
|
||||
}
|
||||
if (myS->IsVPeriodic()) {
|
||||
V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
|
||||
V = ElCLib::InPeriod(V, myLocVMin, myLocVMin + myS->VPeriod());
|
||||
|
||||
// Handle trimmed surfaces.
|
||||
if (V > myvsup + mytolv)
|
||||
if (V > myLocVMax + mytolv)
|
||||
V -= myS->VPeriod();
|
||||
if (V < myvinf - mytolv)
|
||||
if (V < myLocVMin - mytolv)
|
||||
V += myS->VPeriod();
|
||||
}
|
||||
if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
|
||||
(myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
|
||||
if ((myLocUMin-U) <= mytolu && (U-myLocUMax) <= mytolu &&
|
||||
(myLocVMin-V) <= mytolv && (V-myLocVMax) <= mytolv) {
|
||||
myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
|
||||
mySqDist.Append(Val);
|
||||
}
|
||||
@@ -237,6 +237,11 @@ void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
|
||||
if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
|
||||
if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
|
||||
|
||||
myLocUMin = myuinf;
|
||||
myLocUMax = myusup;
|
||||
myLocVMin = myvinf;
|
||||
myLocVMax = myvsup;
|
||||
|
||||
mytolu = theTolU;
|
||||
mytolv = theTolV;
|
||||
mytype = myS->GetType();
|
||||
@@ -272,12 +277,29 @@ void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_ExtPS::Perform (const gp_Pnt& thePoint)
|
||||
{
|
||||
Perform (thePoint, myuinf, myusup, myvinf, myvsup);
|
||||
}
|
||||
|
||||
void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_ExtPS::Perform (const gp_Pnt& thePoint,
|
||||
const Standard_Real theLocUMin,
|
||||
const Standard_Real theLocUMax,
|
||||
const Standard_Real theLocVMin,
|
||||
const Standard_Real theLocVMax)
|
||||
{
|
||||
myPoints.Clear();
|
||||
mySqDist.Clear();
|
||||
|
||||
myLocUMin = Max (theLocUMin, myuinf);
|
||||
myLocUMax = Min (theLocUMax, myusup);
|
||||
myLocVMin = Max (theLocVMin, myvinf);
|
||||
myLocVMax = Min (theLocVMax, myvsup);
|
||||
|
||||
switch (mytype)
|
||||
{
|
||||
case GeomAbs_Cylinder:
|
||||
@@ -350,7 +372,7 @@ void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
|
||||
|
||||
default:
|
||||
{
|
||||
myExtPS->Perform (thePoint);
|
||||
myExtPS->Perform (thePoint, myLocUMin, myLocUMax, myLocVMin, myLocVMax);
|
||||
myDone = myExtPS->IsDone();
|
||||
if (myDone)
|
||||
{
|
||||
|
@@ -100,6 +100,15 @@ public:
|
||||
//! initialized.
|
||||
Standard_EXPORT void Perform (const gp_Pnt& P);
|
||||
|
||||
//! Performs localized extrema search.
|
||||
//! The solution to be found in the given parametric space, which
|
||||
//! is required to be inside the initialized parametric space.
|
||||
Standard_EXPORT void Perform (const gp_Pnt& P,
|
||||
const Standard_Real theLocUMin,
|
||||
const Standard_Real theLocUMax,
|
||||
const Standard_Real theLocVMin,
|
||||
const Standard_Real theLocVMax);
|
||||
|
||||
//! Returns True if the distances are found.
|
||||
Standard_EXPORT Standard_Boolean IsDone() const;
|
||||
|
||||
@@ -152,6 +161,10 @@ private:
|
||||
Standard_Real myvsup;
|
||||
Standard_Real mytolu;
|
||||
Standard_Real mytolv;
|
||||
Standard_Real myLocUMin; //!< Localized parametric space boundary (required to be inside the main parametric space)
|
||||
Standard_Real myLocUMax; //!< Localized parametric space boundary (required to be inside the main parametric space)
|
||||
Standard_Real myLocVMin; //!< Localized parametric space boundary (required to be inside the main parametric space)
|
||||
Standard_Real myLocVMax; //!< Localized parametric space boundary (required to be inside the main parametric space)
|
||||
Standard_Real d11;
|
||||
Standard_Real d12;
|
||||
Standard_Real d21;
|
||||
|
@@ -108,6 +108,10 @@ Extrema_GenExtPS::Extrema_GenExtPS()
|
||||
myNbVSamples (0),
|
||||
myTolU (Precision::PConfusion()),
|
||||
myTolV (Precision::PConfusion()),
|
||||
myLocUMin (RealLast()),
|
||||
myLocUMax (RealFirst()),
|
||||
myLocVMin (RealLast()),
|
||||
myLocVMax (RealFirst()),
|
||||
myTarget (Extrema_ExtFlag_MINMAX),
|
||||
mySqDistance (-1),
|
||||
myIsDone (Standard_False)
|
||||
@@ -211,6 +215,11 @@ void Extrema_GenExtPS::Initialize (const Adaptor3d_Surface& theS,
|
||||
myTolU = theTolU;
|
||||
myTolV = theTolV;
|
||||
|
||||
myLocUMin = myUMin;
|
||||
myLocUMax = myUMax;
|
||||
myLocVMin = myVMin;
|
||||
myLocVMax = myVMax;
|
||||
|
||||
if (myNbUSamples < 2 || myNbVSamples < 2)
|
||||
{
|
||||
throw Standard_OutOfRange ("Extrema_GenExtPS::Initialize - number of samples is too small");
|
||||
@@ -228,12 +237,30 @@ void Extrema_GenExtPS::Initialize (const Adaptor3d_Surface& theS,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint)
|
||||
{
|
||||
Perform (thePoint, myUMin, myUMax, myVMin, myVMax);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint,
|
||||
const Standard_Real theUMin,
|
||||
const Standard_Real theUMax,
|
||||
const Standard_Real theVMin,
|
||||
const Standard_Real theVMax)
|
||||
{
|
||||
myIsDone = Standard_False;
|
||||
myPoint = BVH_Vec3d (thePoint.X(), thePoint.Y(), thePoint.Z());
|
||||
myF.SetPoint (thePoint, myTarget);
|
||||
mySolutions.clear();
|
||||
|
||||
myLocUMin = Max (theUMin, myUMin);
|
||||
myLocUMax = Min (theUMax, myUMax);
|
||||
myLocVMin = Max (theVMin, myVMin);
|
||||
myLocVMax = Min (theVMax, myVMax);
|
||||
|
||||
if (myUParams.IsNull() || myVParams.IsNull())
|
||||
{
|
||||
// Prepare surface sampling
|
||||
@@ -318,7 +345,7 @@ void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint)
|
||||
// Copy solutions
|
||||
for (Standard_Integer i = 1; i <= myF.NbExt(); ++i)
|
||||
{
|
||||
mySolutions.push_back (Extrema_GenExtPS::ExtPSResult (myF.Point (i), myF.SquareDistance (i)));
|
||||
mySolutions.push_back (Extrema_GenExtPS_ExtPSResult (myF.Point (i), myF.SquareDistance (i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -331,7 +358,7 @@ void Extrema_GenExtPS::Perform (const gp_Pnt& thePoint)
|
||||
for (Standard_Integer i = 1; i <= myF.NbExt(); ++i)
|
||||
{
|
||||
if (Abs (mySqDistance - myF.SquareDistance (i)) < Precision::SquareConfusion())
|
||||
mySolutions.push_back (Extrema_GenExtPS::ExtPSResult (myF.Point (i), myF.SquareDistance (i)));
|
||||
mySolutions.push_back (Extrema_GenExtPS_ExtPSResult (myF.Point (i), myF.SquareDistance (i)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +433,7 @@ void Extrema_GenExtPS::BuildTree()
|
||||
// Builder for low-level BVH sets
|
||||
opencascade::handle<BVH_LinearBuilder<Standard_Real, 3> > aLBuilder = new BVH_LinearBuilder<Standard_Real, 3>();
|
||||
|
||||
myBVHBoxSet = new BVH_IndexedBoxSet<Standard_Real, 3, Handle (Extrema_GenExtPS_GridCellBoxSet)> (
|
||||
myBVHBoxSet = new BVH_IndexedBoxSet<Standard_Real, 3, Extrema_GenExtPS_LocalizedSurf> (
|
||||
new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeSingle));
|
||||
|
||||
// create hierarchy of BVH trees
|
||||
@@ -433,12 +460,27 @@ void Extrema_GenExtPS::BuildTree()
|
||||
{
|
||||
for (Standard_Integer iV = V1; iV <= V2; ++iV)
|
||||
{
|
||||
aGridSet->Add (GridCell (iU, iV), BVH_Box<Standard_Real, 3>());
|
||||
aGridSet->Add (Extrema_GenExtPS_GridCell (iU, iV), BVH_Box<Standard_Real, 3>());
|
||||
}
|
||||
}
|
||||
V1 = V2 + 1;
|
||||
|
||||
myBVHBoxSet->Add (aGridSet, BVH_Box<Standard_Real, 3>());
|
||||
Extrema_GenExtPS_GridCell aMinCell = aGridSet->Element (0);
|
||||
Extrema_GenExtPS_GridCell aMaxCell = aGridSet->Element (aGridSet->Size() - 1);
|
||||
|
||||
Standard_Integer aUCoeff = (aMaxCell.UIndex < myNbUSamples) ? 1 : 0;
|
||||
Standard_Integer aVCoeff = (aMaxCell.VIndex < myNbVSamples) ? 1 : 0;
|
||||
|
||||
const Extrema_POnSurf& aPMin = myPoints->Value (aMinCell.UIndex, aMinCell.VIndex);
|
||||
const Extrema_POnSurf& aPMax = myPoints->Value (aMaxCell.UIndex + aUCoeff, aMaxCell.VIndex + aVCoeff);
|
||||
|
||||
Standard_Real aUMin, aUMax, aVMin, aVMax;
|
||||
aPMin.Parameter (aUMin, aVMin);
|
||||
aPMax.Parameter (aUMax, aVMax);
|
||||
|
||||
myBVHBoxSet->Add (
|
||||
Extrema_GenExtPS_LocalizedSurf (aUMin, aUMax, aVMin, aVMax, aGridSet),
|
||||
BVH_Box<Standard_Real, 3>());
|
||||
}
|
||||
U1 = U2 + 1;
|
||||
V1 = 1;
|
||||
@@ -451,14 +493,14 @@ void Extrema_GenExtPS::BuildTree()
|
||||
const Standard_Integer aNbSets = myBVHBoxSet->Size();
|
||||
for (Standard_Integer iSet = 0; iSet < aNbSets; ++iSet)
|
||||
{
|
||||
Handle (Extrema_GenExtPS_GridCellBoxSet) aGridSet = myBVHBoxSet->Element (iSet);
|
||||
Extrema_GenExtPS_LocalizedSurf aGridSet = myBVHBoxSet->Element (iSet);
|
||||
|
||||
// Box of the set
|
||||
Bnd_Box aSetBox;
|
||||
const Standard_Integer aNbCells = aGridSet->Size();
|
||||
const Standard_Integer aNbCells = aGridSet.CellBoxSet->Size();
|
||||
for (Standard_Integer iCell = 0; iCell < aNbCells; ++iCell)
|
||||
{
|
||||
const GridCell& aCell = aGridSet->Element (iCell);
|
||||
const Extrema_GenExtPS_GridCell& aCell = aGridSet.CellBoxSet->Element (iCell);
|
||||
Standard_Integer iU = aCell.UIndex, iV = aCell.VIndex;
|
||||
|
||||
Standard_Integer aUCoeff = (iU < myNbUSamples) ? 1 : 0;
|
||||
@@ -496,7 +538,7 @@ void Extrema_GenExtPS::BuildTree()
|
||||
//Standard_Real anAvSqExt = aSetBox.SquareExtent() / (aGridSet->Size() - 1);
|
||||
//aGridBox.Enlarge (Sqrt (anAvSqExt));
|
||||
}
|
||||
aGridSet->UpdateBox (iCell, Bnd_Tools::Bnd2BVH (aGridBox));
|
||||
aGridSet.CellBoxSet->UpdateBox (iCell, Bnd_Tools::Bnd2BVH (aGridBox));
|
||||
|
||||
aSetBox.Add (aGridBox);
|
||||
}
|
||||
@@ -653,10 +695,14 @@ Standard_Boolean Extrema_GenExtPS::Accept (const Standard_Integer theIndex,
|
||||
{
|
||||
if (myBVHSet == NULL)
|
||||
{
|
||||
Handle (Extrema_GenExtPS_GridCellBoxSet) aGridSet = myBVHBoxSet->Element (theIndex);
|
||||
aGridSet->Build();
|
||||
Extrema_GenExtPS_LocalizedSurf aGridSet = myBVHBoxSet->Element (theIndex);
|
||||
if ((aGridSet.UMax < myLocUMin || aGridSet.UMin > myLocUMax) &&
|
||||
(aGridSet.VMax < myLocVMin || aGridSet.VMin > myLocVMax))
|
||||
return 0;
|
||||
|
||||
aGridSet.CellBoxSet->Build();
|
||||
// Set low-level BVH set for inner selection
|
||||
SetBVHSet (aGridSet.get());
|
||||
SetBVHSet (aGridSet.CellBoxSet.get());
|
||||
Standard_Integer aNb = Select();
|
||||
// Unset the inner set and continue with high level BVH traverse
|
||||
SetBVHSet (NULL);
|
||||
@@ -664,7 +710,7 @@ Standard_Boolean Extrema_GenExtPS::Accept (const Standard_Integer theIndex,
|
||||
}
|
||||
else
|
||||
{
|
||||
GridCell aCell = myBVHSet->Element (theIndex);
|
||||
Extrema_GenExtPS_GridCell aCell = myBVHSet->Element (theIndex);
|
||||
return FindSolution (aCell.UIndex, aCell.VIndex, myTarget);
|
||||
}
|
||||
}
|
||||
@@ -677,13 +723,21 @@ Standard_Boolean Extrema_GenExtPS::FindSolution (const Standard_Integer theNU,
|
||||
const Standard_Integer theNV,
|
||||
const Extrema_ExtFlag theTarget)
|
||||
{
|
||||
|
||||
// Fill corner points with square distance to myPoint
|
||||
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);
|
||||
|
||||
{
|
||||
Standard_Real U1, U2, V1, V2;
|
||||
aParam00.Parameter (U1, V1);
|
||||
aParam11.Parameter (U2, V2);
|
||||
if ((U2 < myLocUMin || U1 > myLocUMax) &&
|
||||
(V2 < myLocVMin || V1 > myLocVMax))
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
gp_Pnt aPoint (myPoint.x(), myPoint.y(), myPoint.z());
|
||||
|
||||
fillSqDist (aParam00, aPoint);
|
||||
|
@@ -45,18 +45,18 @@ class Extrema_POnSurfParams;
|
||||
|
||||
//! Grid cell defined by (U, V) indices of the minimal
|
||||
//! corner of the cell
|
||||
struct GridCell
|
||||
struct Extrema_GenExtPS_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)
|
||||
Extrema_GenExtPS_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;
|
||||
typedef BVH_BoxSet <Standard_Real, 3, Extrema_GenExtPS_GridCell> Extrema_GenExtPS_GridCellBoxSet;
|
||||
|
||||
|
||||
//! It calculates the extreme distances between a point and a surface.
|
||||
@@ -219,7 +219,15 @@ public: //! @name Performing projection
|
||||
//! Allows multiple points be projected on the same surface.
|
||||
Standard_EXPORT void Perform (const gp_Pnt& theP);
|
||||
|
||||
|
||||
//! Performs localized extrema search.
|
||||
//! The localized boundaries are required to be inside the
|
||||
//! main (initialized) surface parametric space.
|
||||
Standard_EXPORT void Perform (const gp_Pnt& theP,
|
||||
const Standard_Real theUMin,
|
||||
const Standard_Real theUMax,
|
||||
const Standard_Real theVMin,
|
||||
const Standard_Real theVMax);
|
||||
|
||||
public: //! @name Getting the results
|
||||
|
||||
//! Returns True if the distances are found.
|
||||
@@ -308,23 +316,23 @@ protected: //! @name Rules for BVH traverse
|
||||
protected: //! @name Auxiliary types
|
||||
|
||||
//! Structure to keep and sort the results
|
||||
struct ExtPSResult
|
||||
struct Extrema_GenExtPS_ExtPSResult
|
||||
{
|
||||
Extrema_POnSurf UV; //! UV coordinates of extrema solution
|
||||
Standard_Real SqDistance; //! Square distance to target point
|
||||
|
||||
ExtPSResult()
|
||||
Extrema_GenExtPS_ExtPSResult()
|
||||
: SqDistance (-1)
|
||||
{}
|
||||
|
||||
ExtPSResult (const Extrema_POnSurf& theUV,
|
||||
const Standard_Real theSqDist)
|
||||
Extrema_GenExtPS_ExtPSResult (const Extrema_POnSurf& theUV,
|
||||
const Standard_Real theSqDist)
|
||||
: UV (theUV),
|
||||
SqDistance (theSqDist)
|
||||
{}
|
||||
|
||||
//! IsLess operator
|
||||
Standard_Boolean operator< (const ExtPSResult& Other) const
|
||||
Standard_Boolean operator< (const Extrema_GenExtPS_ExtPSResult& Other) const
|
||||
{
|
||||
if (SqDistance != Other.SqDistance)
|
||||
return SqDistance < Other.SqDistance;
|
||||
@@ -336,6 +344,29 @@ protected: //! @name Auxiliary types
|
||||
}
|
||||
};
|
||||
|
||||
//! Localized parametric space of surface on which the single
|
||||
//! BVH tree is built
|
||||
struct Extrema_GenExtPS_LocalizedSurf
|
||||
{
|
||||
Standard_Real UMin;
|
||||
Standard_Real UMax;
|
||||
Standard_Real VMin;
|
||||
Standard_Real VMax;
|
||||
Handle(Extrema_GenExtPS_GridCellBoxSet) CellBoxSet;
|
||||
|
||||
Extrema_GenExtPS_LocalizedSurf ()
|
||||
: UMin (0.0), UMax (0.0), VMin (0.0), VMax (0.0), CellBoxSet (NULL)
|
||||
{}
|
||||
|
||||
Extrema_GenExtPS_LocalizedSurf (const Standard_Real theUMin,
|
||||
const Standard_Real theUMax,
|
||||
const Standard_Real theVMin,
|
||||
const Standard_Real theVMax,
|
||||
const Handle(Extrema_GenExtPS_GridCellBoxSet)& theCellBoxSet)
|
||||
: UMin (theUMin), UMax (theUMax), VMin (theVMin), VMax (theVMax), CellBoxSet (theCellBoxSet)
|
||||
{}
|
||||
};
|
||||
|
||||
protected: //! @name Fields
|
||||
|
||||
// Inputs
|
||||
@@ -354,6 +385,11 @@ protected: //! @name Fields
|
||||
Standard_Real myTolU; //!< U parametric tolerance
|
||||
Standard_Real myTolV; //!< V parametric tolerance
|
||||
|
||||
Standard_Real myLocUMin; //!< Localized surface parametric range: UMin
|
||||
Standard_Real myLocUMax; //!< Localized surface parametric range: UMax
|
||||
Standard_Real myLocVMin; //!< Localized surface parametric range: VMin
|
||||
Standard_Real myLocVMax; //!< Localized surface parametric range: VMax
|
||||
|
||||
Extrema_ExtFlag myTarget; //!< Extrema objective
|
||||
|
||||
// Intermediate data
|
||||
@@ -368,11 +404,11 @@ protected: //! @name Fields
|
||||
|
||||
Standard_Real mySqDistance; //!< Min/Max found square distance used in BVH tree traverse
|
||||
opencascade::handle
|
||||
<BVH_IndexedBoxSet<Standard_Real, 3, Handle(Extrema_GenExtPS_GridCellBoxSet)> > myBVHBoxSet; //!< High-level BVH of BVH organized grid cells
|
||||
<BVH_IndexedBoxSet<Standard_Real, 3, Extrema_GenExtPS_LocalizedSurf> > myBVHBoxSet; //!< High-level BVH of BVH organized grid cells
|
||||
|
||||
// Results
|
||||
std::vector <ExtPSResult> mySolutions; //!< Found solutions (sorted first by distance to target point,
|
||||
//! second by the ascending U,V coordinates)
|
||||
std::vector <Extrema_GenExtPS_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
|
||||
};
|
||||
|
||||
|
@@ -95,6 +95,7 @@ struct aFuncStruct
|
||||
Handle(Adaptor3d_HSurface) mySurf; // Surface where to project.
|
||||
Handle(Adaptor3d_HCurve) myCurve; // Curve to project.
|
||||
Handle(Adaptor2d_HCurve2d) myInitCurve2d; // Initial 2dcurve projection.
|
||||
mutable Extrema_ExtPS myGlobExtPS; // Extrema initialized on whole parameter space of the surface
|
||||
Standard_Real mySqProjOrtTol; // Used to filter non-orthogonal projected point.
|
||||
Standard_Real myTolU;
|
||||
Standard_Real myTolV;
|
||||
@@ -190,6 +191,73 @@ static Standard_Real anOrthogSqValue(const gp_Pnt& aBasePnt,
|
||||
return (aFirstPart * aFirstPart + aSecondPart * aSecondPart);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : checkSolution
|
||||
//purpose : checks if the current solution is better than initial point
|
||||
//=======================================================================
|
||||
static Standard_Boolean checkSolution (const Extrema_POnSurf& theSol,
|
||||
const Standard_Real theProjSqDist,
|
||||
const Handle(Adaptor3d_HSurface)& theSurf,
|
||||
const Standard_Real theUPeriod,
|
||||
const Standard_Real theVPeriod,
|
||||
const Standard_Integer theNbU,
|
||||
const Standard_Integer theNbV,
|
||||
const gp_Pnt& thePoint,
|
||||
const Standard_Real theProjTol,
|
||||
const Standard_Real theDist,
|
||||
gp_Pnt2d& thePOnSurf)
|
||||
{
|
||||
Standard_Real U, V;
|
||||
theSol.Parameter (U, V);
|
||||
Standard_Real Dist2Min = anOrthogSqValue (thePoint, theSurf, U, V);
|
||||
if (Dist2Min < theProjTol && // Point is projection.
|
||||
theProjSqDist < theDist + Precision::SquareConfusion()) // Point better than initial.
|
||||
{
|
||||
thePOnSurf.SetXY (gp_XY (U - theNbU * theUPeriod, V - theNbV * theVPeriod));
|
||||
return Standard_True;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : checkSolution
|
||||
//purpose : checks solutions found by extrema
|
||||
//=======================================================================
|
||||
static Standard_Boolean checkSolution (const Extrema_ExtPS& theExtrema,
|
||||
const Handle(Adaptor3d_HSurface)& theSurf,
|
||||
const Standard_Real theUPeriod,
|
||||
const Standard_Real theVPeriod,
|
||||
const Standard_Integer theNbU,
|
||||
const Standard_Integer theNbV,
|
||||
const gp_Pnt& thePoint,
|
||||
const Standard_Real theProjTol,
|
||||
const Standard_Real theDist,
|
||||
gp_Pnt2d& theSolution)
|
||||
{
|
||||
if (!theExtrema.IsDone() || !theExtrema.NbExt())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real aDist2Min = RealLast();
|
||||
Standard_Integer iGoodValue = -1;
|
||||
|
||||
for (Standard_Integer i = 1; i <= theExtrema.NbExt(); i++)
|
||||
{
|
||||
if (aDist2Min > theExtrema.SquareDistance(i))
|
||||
{
|
||||
aDist2Min = theExtrema.SquareDistance(i);
|
||||
iGoodValue = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (iGoodValue < 1)
|
||||
return Standard_False;
|
||||
|
||||
return checkSolution (theExtrema.Point (iGoodValue), theExtrema.SquareDistance (iGoodValue),
|
||||
theSurf, theUPeriod, theVPeriod, theNbU, theNbV,
|
||||
thePoint, theProjTol, theDist, theSolution);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
|
||||
@@ -298,10 +366,8 @@ static gp_Pnt2d Function_Value(const Standard_Real theU,
|
||||
}
|
||||
|
||||
// Non-analytical case.
|
||||
Standard_Real Dist2Min = RealLast();
|
||||
Standard_Real uperiod = theData.myPeriod[0],
|
||||
vperiod = theData.myPeriod[1],
|
||||
u, v;
|
||||
vperiod = theData.myPeriod[1];
|
||||
|
||||
// U0 and V0 are the points within the initialized period.
|
||||
if(U0 < Uinf)
|
||||
@@ -379,36 +445,31 @@ static gp_Pnt2d Function_Value(const Standard_Real theU,
|
||||
locext.Perform(p, U0, V0);
|
||||
if (locext.IsDone())
|
||||
{
|
||||
locext.Point().Parameter(u, v);
|
||||
Dist2Min = anOrthogSqValue(p, theData.mySurf, u, v);
|
||||
if (Dist2Min < theData.mySqProjOrtTol && // Point is projection.
|
||||
locext.SquareDistance() < aSurfPntDist + Precision::SquareConfusion()) // Point better than initial.
|
||||
gp_Pnt2d pnt;
|
||||
if (checkSolution (locext.Point(), locext.SquareDistance(),
|
||||
theData.mySurf, uperiod, vperiod, decalU, decalV,
|
||||
p, theData.mySqProjOrtTol, aSurfPntDist, pnt))
|
||||
{
|
||||
gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
|
||||
return pnt;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform whole param space search.
|
||||
Extrema_ExtPS ext(p, SurfLittle, theData.myTolU, theData.myTolV);
|
||||
// Perform search on the whole parametric space using preinitialized extrema.
|
||||
theData.myGlobExtPS.Perform (p, uInfLi, uSupLi, vInfLi, vSupLi);
|
||||
gp_Pnt2d pnt;
|
||||
if (checkSolution (theData.myGlobExtPS, theData.mySurf, uperiod, vperiod, decalU, decalV,
|
||||
p, theData.mySqProjOrtTol, aSurfPntDist, pnt))
|
||||
{
|
||||
return pnt;
|
||||
}
|
||||
|
||||
// Perform search on the decreased parametric space.
|
||||
Extrema_ExtPS ext(p, SurfLittle, theData.myTolU, theData.myTolV, Extrema_ExtFlag_MIN);
|
||||
if (ext.IsDone() && ext.NbExt() >= 1)
|
||||
{
|
||||
Dist2Min = ext.SquareDistance(1);
|
||||
Standard_Integer GoodValue = 1;
|
||||
for (Standard_Integer i = 2 ; i <= ext.NbExt() ; i++ )
|
||||
if (checkSolution (ext, theData.mySurf, uperiod, vperiod, decalU, decalV,
|
||||
p, theData.mySqProjOrtTol, aSurfPntDist, pnt))
|
||||
{
|
||||
if( Dist2Min > ext.SquareDistance(i))
|
||||
{
|
||||
Dist2Min = ext.SquareDistance(i);
|
||||
GoodValue = i;
|
||||
}
|
||||
}
|
||||
ext.Point(GoodValue).Parameter(u, v);
|
||||
Dist2Min = anOrthogSqValue(p, theData.mySurf, u, v);
|
||||
if (Dist2Min < theData.mySqProjOrtTol && // Point is projection.
|
||||
ext.SquareDistance(GoodValue) < aSurfPntDist + Precision::SquareConfusion()) // Point better than initial.
|
||||
{
|
||||
gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
|
||||
return pnt;
|
||||
}
|
||||
}
|
||||
@@ -445,6 +506,14 @@ class ProjLib_PolarFunction : public AppCont_Function
|
||||
myStruct.mySqProjOrtTol = 10000.0 * Tol3d * Tol3d;
|
||||
myStruct.myTolU = Surf->UResolution(Tol3d);
|
||||
myStruct.myTolV = Surf->VResolution(Tol3d);
|
||||
|
||||
Standard_Real Uinf, Usup, Vinf, Vsup;
|
||||
Uinf = Surf->Surface().FirstUParameter();
|
||||
Usup = Surf->Surface().LastUParameter();
|
||||
Vinf = Surf->Surface().FirstVParameter();
|
||||
Vsup = Surf->Surface().LastVParameter();
|
||||
myStruct.myGlobExtPS.Initialize (Surf->Surface(), Uinf, Usup, Vinf, Vsup, myStruct.myTolU, myStruct.myTolV);
|
||||
myStruct.myGlobExtPS.SetFlag (Extrema_ExtFlag_MIN);
|
||||
}
|
||||
|
||||
~ProjLib_PolarFunction() {}
|
||||
|
Reference in New Issue
Block a user