1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030892: Improve Extrema_ExtPS algorithm by unifying the GRAD and TREE methods

Refactoring of the Extrema_GenExtPS class in order to improve performance and robustness of the algorithm by unifying the GRAD and TREE search methods.
This commit is contained in:
emv
2019-08-19 08:41:04 +03:00
parent 68922bccc4
commit 4059fcddcb
43 changed files with 1927 additions and 1427 deletions

View File

@@ -154,7 +154,7 @@ void BRepExtrema_DistShapeShape::DistanceMapMap (const TopTools_IndexedMapOfShap
const TopoDS_Shape& aShape1 = theMap1 (aPair.Index1);
const TopoDS_Shape& aShape2 = theMap2 (aPair.Index2);
BRepExtrema_DistanceSS aDistTool (aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
BRepExtrema_DistanceSS aDistTool (aShape1, aShape2, aBox1, aBox2, myDistRef, myEps, myFlag);
if (aDistTool.IsDone())
{
if (aDistTool.DistValue() < myDistRef - myEps)
@@ -199,8 +199,7 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
myEps (Precision::Confusion()),
myIsInitS1 (Standard_False),
myIsInitS2 (Standard_False),
myFlag (Extrema_ExtFlag_MINMAX),
myAlgo (Extrema_ExtAlgo_Grad)
myFlag (Extrema_ExtFlag_MINMAX)
{
//
}
@@ -211,16 +210,14 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
//=======================================================================
BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
const TopoDS_Shape& Shape2,
const Extrema_ExtFlag F,
const Extrema_ExtAlgo A)
const Extrema_ExtFlag F)
: myDistRef (0.0),
myIsDone (Standard_False),
myInnerSol (Standard_False),
myEps (Precision::Confusion()),
myIsInitS1 (Standard_False),
myIsInitS2 (Standard_False),
myFlag (F),
myAlgo (A)
myFlag (F)
{
LoadS1(Shape1);
LoadS2(Shape2);
@@ -235,16 +232,14 @@ BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape
BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
const TopoDS_Shape& Shape2,
const Standard_Real theDeflection,
const Extrema_ExtFlag F,
const Extrema_ExtAlgo A)
const Extrema_ExtFlag F)
: myDistRef (0.0),
myIsDone (Standard_False),
myInnerSol (Standard_False),
myEps (theDeflection),
myIsInitS1 (Standard_False),
myIsInitS2 (Standard_False),
myFlag (F),
myAlgo (A)
myFlag (F)
{
LoadS1(Shape1);
LoadS2(Shape2);

View File

@@ -18,7 +18,6 @@
#include <BRepExtrema_SeqOfSolution.hxx>
#include <BRepExtrema_SolutionElem.hxx>
#include <BRepExtrema_SupportType.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Extrema_ExtFlag.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS_Shape.hxx>
@@ -39,9 +38,9 @@ class BRepExtrema_DistShapeShape
Standard_EXPORT BRepExtrema_DistShapeShape();
//! computation of the minimum distance (value and pair of points) using default deflection <br>
//! Default value is Precision::Confusion(). <br>
Standard_EXPORT BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,const TopoDS_Shape& Shape2,const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
Standard_EXPORT BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,const TopoDS_Shape& Shape2,const Extrema_ExtFlag F = Extrema_ExtFlag_MIN);
//! create tool and load both shapes into it <br>
Standard_EXPORT BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,const TopoDS_Shape& Shape2,const Standard_Real theDeflection,const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
Standard_EXPORT BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,const TopoDS_Shape& Shape2,const Standard_Real theDeflection,const Extrema_ExtFlag F = Extrema_ExtFlag_MIN);
void SetDeflection(const Standard_Real theDeflection)
{
@@ -129,11 +128,6 @@ class BRepExtrema_DistShapeShape
myFlag = F;
}
void SetAlgo(const Extrema_ExtAlgo A)
{
myAlgo = A;
}
private:
//! computes the minimum distance between two maps of shapes (Face,Edge,Vertex) <br>
@@ -156,7 +150,6 @@ private:
Standard_Boolean myIsInitS1;
Standard_Boolean myIsInitS2;
Extrema_ExtFlag myFlag;
Extrema_ExtAlgo myAlgo;
Bnd_SeqOfBox myBV1;
Bnd_SeqOfBox myBV2;
Bnd_SeqOfBox myBE1;

View File

@@ -772,7 +772,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face&
const Standard_Real Dst=B1.Distance(B2);
if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
{
BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
BRepExtrema_ExtPF Ext(S1,S2,myFlag);
const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
if ( NbExtrema > 0 )
{
@@ -828,7 +828,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex&
const Standard_Real Dst=B1.Distance(B2);
if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
{
BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
BRepExtrema_ExtPF Ext(S2,S1,myFlag);
const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
if ( NbExtrema > 0 )
{

View File

@@ -16,7 +16,6 @@
#include <BRepExtrema_SeqOfSolution.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Precision.hxx>
#include <Standard_DefineAlloc.hxx>
@@ -39,9 +38,8 @@ class BRepExtrema_DistanceSS
BRepExtrema_DistanceSS(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
const Bnd_Box& B1, const Bnd_Box& B2,
const Standard_Real DstRef,
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad)
: myDstRef(DstRef), myModif(Standard_False), myEps(Precision::Confusion()), myFlag(F), myAlgo(A)
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX)
: myDstRef(DstRef), myModif(Standard_False), myEps(Precision::Confusion()), myFlag(F)
{
Perform(S1, S2, B1, B2);
}
@@ -52,9 +50,8 @@ class BRepExtrema_DistanceSS
BRepExtrema_DistanceSS(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
const Bnd_Box& B1, const Bnd_Box& B2,
const Standard_Real DstRef, const Standard_Real aDeflection,
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad)
: myDstRef(DstRef), myModif(Standard_False), myEps(aDeflection), myFlag(F), myAlgo(A)
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX)
: myDstRef(DstRef), myModif(Standard_False), myEps(aDeflection), myFlag(F)
{
Perform(S1, S2, B1, B2);
}
@@ -83,11 +80,6 @@ class BRepExtrema_DistanceSS
{
myFlag = F;
}
//! sets the flag controlling ...
void SetAlgo(const Extrema_ExtAlgo A)
{
myAlgo = A;
}
private:
@@ -130,7 +122,6 @@ class BRepExtrema_DistanceSS
Standard_Boolean myModif;
Standard_Real myEps;
Extrema_ExtFlag myFlag;
Extrema_ExtAlgo myAlgo;
};
#endif

View File

@@ -32,9 +32,9 @@
//=======================================================================
BRepExtrema_ExtPF::BRepExtrema_ExtPF(const TopoDS_Vertex& TheVertex, const TopoDS_Face& TheFace,
const Extrema_ExtFlag TheFlag, const Extrema_ExtAlgo TheAlgo)
const Extrema_ExtFlag TheFlag)
{
Initialize(TheFace,TheFlag,TheAlgo);
Initialize(TheFace,TheFlag);
Perform(TheVertex,TheFace);
}
@@ -44,7 +44,7 @@ BRepExtrema_ExtPF::BRepExtrema_ExtPF(const TopoDS_Vertex& TheVertex, const TopoD
//=======================================================================
void BRepExtrema_ExtPF::Initialize(const TopoDS_Face& TheFace,
const Extrema_ExtFlag TheFlag, const Extrema_ExtAlgo TheAlgo)
const Extrema_ExtFlag TheFlag)
{
// cette surface doit etre en champ. Extrema ne fait
// pas de copie et prend seulement un pointeur dessus.
@@ -60,7 +60,6 @@ void BRepExtrema_ExtPF::Initialize(const TopoDS_Face& TheFace,
Standard_Real U1, U2, V1, V2;
BRepTools::UVBounds(TheFace, U1, U2, V1, V2);
myExtPS.SetFlag(TheFlag);
myExtPS.SetAlgo(TheAlgo);
myExtPS.Initialize(mySurf, U1, U2, V1, V2, aTolU, aTolV);
}

View File

@@ -21,7 +21,6 @@
#include <Extrema_SequenceOfPOnSurf.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Extrema_ExtAlgo.hxx>
class TopoDS_Vertex;
class TopoDS_Face;
@@ -38,12 +37,10 @@ class BRepExtrema_ExtPF
{}
//! It calculates all the distances. <br>
Standard_EXPORT BRepExtrema_ExtPF(const TopoDS_Vertex& TheVertex,const TopoDS_Face& TheFace,
const Extrema_ExtFlag TheFlag = Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo TheAlgo = Extrema_ExtAlgo_Grad);
const Extrema_ExtFlag TheFlag = Extrema_ExtFlag_MINMAX);
Standard_EXPORT void Initialize(const TopoDS_Face& TheFace,
const Extrema_ExtFlag TheFlag = Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo TheAlgo = Extrema_ExtAlgo_Grad);
const Extrema_ExtFlag TheFlag = Extrema_ExtFlag_MINMAX);
//! An exception is raised if the fields have not been initialized. <br>
//! Be careful: this method uses the Face only for classify not for the fields. <br>
@@ -79,11 +76,6 @@ class BRepExtrema_ExtPF
myExtPS.SetFlag(F);
}
void SetAlgo(const Extrema_ExtAlgo A)
{
myExtPS.SetAlgo(A);
}
private:
Extrema_ExtPS myExtPS;

View File

@@ -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>
@@ -181,39 +182,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,
@@ -361,13 +329,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:
@@ -394,7 +362,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);
}
}

View File

@@ -73,7 +73,7 @@ static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const
if (n == 5)
aDeflection = Draw::Atof(a[4]);
BRepExtrema_DistShapeShape dst(S1 ,S2, aDeflection);
BRepExtrema_DistShapeShape dst(S1 ,S2, aDeflection, Extrema_ExtFlag_MIN);
if (dst.IsDone())
{

View File

@@ -619,9 +619,9 @@ static Standard_Integer getedgeregul
//=======================================================================
static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
if (n < 3 || n > 5) {
if (n < 3 || n > 4) {
di << "Project point on the face.\n";
di << "Usage: projponf face pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]\n";
di << "Usage: projponf face pnt [extrema flag: -min/-max/-minmax]\n";
return 1;
}
// get face
@@ -644,7 +644,6 @@ static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const
//
// get projection options
// default values;
Extrema_ExtAlgo anExtAlgo = Extrema_ExtAlgo_Grad;
Extrema_ExtFlag anExtFlag = Extrema_ExtFlag_MINMAX;
//
for (Standard_Integer i = 3; i < n; ++i) {
@@ -657,12 +656,6 @@ static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const
else if (!strcasecmp(a[i], "-minmax")) {
anExtFlag = Extrema_ExtFlag_MINMAX;
}
else if (!strcasecmp(a[i], "-t")) {
anExtAlgo = Extrema_ExtAlgo_Tree;
}
else if (!strcasecmp(a[i], "-g")) {
anExtAlgo = Extrema_ExtAlgo_Grad;
}
}
//
// get surface
@@ -679,7 +672,6 @@ static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const
GeomAPI_ProjectPointOnSurf aProjPS;
aProjPS.Init(aSurf, aUMin, aUMax, aVMin, aVMax);
// set the options
aProjPS.SetExtremaAlgo(anExtAlgo);
aProjPS.SetExtremaFlag(anExtFlag);
// perform projection
aProjPS.Perform(aP);
@@ -768,7 +760,7 @@ void BRepTest::SurfaceCommands(Draw_Interpretor& theCommands)
theCommands.Add ("getedgeregularity", "getedgeregularity edge face1 [face2]", __FILE__,getedgeregul,g);
theCommands.Add ("projponf",
"projponf face pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]\n"
"projponf face pnt [extrema flag: -min/-max/-minmax]\n"
"\t\tProject point on the face.",
__FILE__, projponf, g);
}

View File

@@ -66,6 +66,18 @@ public: //! @name Adding elements in BVH
BVH_Object<NumType, Dimension>::myIsDirty = Standard_True;
}
//! Allows to update the box of the element while the tree is not yet built
virtual void UpdateBox (const Standard_Integer theId, const BVH_Box<NumType, Dimension>& theNewBox)
{
if (BVH_Object<NumType, Dimension>::myIsDirty)
{
if (theId >= 0 && theId < Size())
{
myBoxes[theId] = theNewBox;
}
}
}
public: //! @name BVH construction
//! BVH construction

View File

@@ -84,7 +84,7 @@ public: //! @name Necessary overrides for BVH construction
//! Returns the bounding box with the given index.
virtual BVH_Box <NumType, Dimension> Box (const Standard_Integer theIndex) const Standard_OVERRIDE
{
return myBoxes[myIndices[theIndex]];
return this->myBoxes[myIndices[theIndex]];
}
//! Swaps indices of two specified boxes.
@@ -95,9 +95,9 @@ public: //! @name Necessary overrides for BVH construction
}
//! Returns the Element with the index theIndex.
virtual DataType Element (const Standard_Integer theIndex) const
virtual DataType Element (const Standard_Integer theIndex) const Standard_OVERRIDE
{
return myElements[myIndices[theIndex]];
return this->myElements[myIndices[theIndex]];
}
protected: //! @name Fields

View File

@@ -88,6 +88,24 @@ public: //! @name Point-Box Square distance
return aDist;
}
//! Computes Max square distance between point and bounding box
static T PointBoxMaxSquareDistance (const BVH_VecNt& thePoint,
const BVH_VecNt& theCMin,
const BVH_VecNt& theCMax)
{
T aDist = 0;
for (int i = 0; i < N; ++i)
{
T dmin = 0, dmax = 0;
if (thePoint[i] > theCMin[i]) { dmin = thePoint[i] - theCMin[i]; }
if (thePoint[i] < theCMax[i]) { dmax = theCMax[i] - thePoint[i]; }
T d = dmin > dmax ? dmin : dmax;
d *= d;
aDist += d;
}
return aDist;
}
public: //! @name Point-Box projection
//! Computes projection of point on bounding box
@@ -110,7 +128,6 @@ public: //! @name Point-Box projection
{
return thePoint.cwiseMax (theCMin).cwiseMin (theCMax);
}
public: //! @name Point-Triangle Square distance
//! Computes square distance between point and triangle

View File

@@ -18,6 +18,10 @@
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <Bnd_OBB.hxx>
#include <Bnd_Box.hxx>
#include <Draw_Box.hxx>
// This file defines global functions not declared in any public header,
// intended for use from debugger prompt (Command Window in Visual Studio)
@@ -40,3 +44,47 @@ Standard_EXPORT const char* Draw_Eval (const char *theCommandStr)
return anException.GetMessageString();
}
}
//=======================================================================
//function : DBRep_SetOBB
//purpose : Draw OBB
//=======================================================================
Standard_EXPORT const char* Draw_SetOBB(const char* theNameStr, void* theBox)
{
if (theNameStr == 0 || theBox == 0)
{
return "Error: name or box is null";
}
try {
Bnd_OBB B = *(Bnd_OBB*)theBox;
Handle(Draw_Box) DB = new Draw_Box (B, Draw_orange);
Draw::Set (theNameStr, DB);
return theNameStr;
}
catch (Standard_Failure const& anException)
{
return anException.GetMessageString();
}
}
//=======================================================================
//function : DBRep_SetBox
//purpose : Draw Box
//=======================================================================
Standard_EXPORT const char* Draw_SetBox(const char* theNameStr, void* theBox)
{
if (theNameStr == 0 || theBox == 0)
{
return "Error: name or box is null";
}
try {
Bnd_Box B = *(Bnd_Box*)theBox;
Handle(Draw_Box) DB = new Draw_Box (B, Draw_orange);
Draw::Set (theNameStr, DB);
return theNameStr;
}
catch (Standard_Failure const& anException)
{
return anException.GetMessageString();
}
}

View File

@@ -1,27 +0,0 @@
// Created on: 1991-02-26
// Created by: Isabelle GRIGNON
// Copyright (c) 1991-1999 Matra Datavision
// Copyright (c) 1999-2014 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 _Extrema_ExtAlgo_HeaderFile
#define _Extrema_ExtAlgo_HeaderFile
enum Extrema_ExtAlgo
{
Extrema_ExtAlgo_Grad,
Extrema_ExtAlgo_Tree
};
#endif // _Extrema_ExtAlgo_HeaderFile

View File

@@ -17,12 +17,16 @@
#ifndef _Extrema_ExtFlag_HeaderFile
#define _Extrema_ExtFlag_HeaderFile
//! Enumeration describes the objective for extrema algorithms.
//! Generally:
//! - *Extrema_ExtFlag_MIN* - means that only minimal solutions are required
//! - *Extrema_ExtFlag_MAX* - means that only maximal solutions are required
//! - *Extrema_ExtFlag_MINMAX* - means that all solutions are required
enum Extrema_ExtFlag
{
Extrema_ExtFlag_MIN,
Extrema_ExtFlag_MAX,
Extrema_ExtFlag_MINMAX
Extrema_ExtFlag_MIN,
Extrema_ExtFlag_MAX,
Extrema_ExtFlag_MINMAX
};
#endif // _Extrema_ExtFlag_HeaderFile

View File

@@ -144,7 +144,7 @@ void Extrema_ExtPExtS::MakePreciser (Standard_Real& U,
}
//=============================================================================
Extrema_ExtPExtS::Extrema_ExtPExtS()
Extrema_ExtPExtS::Extrema_ExtPExtS (const Handle (Extrema_GenExtPS)& theExtPS)
: myuinf(0.0),
myusup(0.0),
mytolu(0.0),
@@ -153,7 +153,8 @@ Extrema_ExtPExtS::Extrema_ExtPExtS()
mytolv(0.0),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
myNbExt(0)
myNbExt(0),
myExtPS (theExtPS)
{
for (size_t anIdx = 0; anIdx < sizeof (mySqDist) / sizeof (mySqDist[0]); anIdx++)
{
@@ -170,7 +171,8 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
const Standard_Real theVmin,
const Standard_Real theVsup,
const Standard_Real theTolU,
const Standard_Real theTolV)
const Standard_Real theTolV,
const Handle(Extrema_GenExtPS)& theExtPS)
: myuinf(theUmin),
myusup(theUsup),
mytolu(theTolU),
@@ -180,7 +182,8 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
myS (theS),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
myNbExt(0)
myNbExt(0),
myExtPS (theExtPS)
{
for (size_t anIdx = 0; anIdx < sizeof (mySqDist) / sizeof (mySqDist[0]); anIdx++)
{
@@ -201,7 +204,8 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt& theP,
const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& theS,
const Standard_Real theTolU,
const Standard_Real theTolV)
const Standard_Real theTolV,
const Handle(Extrema_GenExtPS)& theExtPS)
: myuinf(theS->FirstUParameter()),
myusup(theS->LastUParameter()),
mytolu(theTolU),
@@ -211,7 +215,8 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
myS (theS),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
myNbExt(0)
myNbExt(0),
myExtPS (theExtPS)
{
for (size_t anIdx = 0; anIdx < sizeof (mySqDist) / sizeof (mySqDist[0]); anIdx++)
{
@@ -265,15 +270,18 @@ void Extrema_ExtPExtS::Initialize (const Handle(GeomAdaptor_HSurfaceOfLinearExtr
if (!myIsAnalyticallyComputable)
{
myExtPS.Initialize (theS->ChangeSurface(),
32,
32,
theUinf,
theUsup,
theVinf,
theVsup,
theTolU,
theTolV);
if (myExtPS.IsNull())
myExtPS = new Extrema_GenExtPS();
myExtPS->Initialize (theS->ChangeSurface(),
32,
32,
theUinf,
theUsup,
theVinf,
theVsup,
theTolU,
theTolV);
}
}
@@ -292,11 +300,9 @@ void Extrema_ExtPExtS::Perform (const gp_Pnt& P)
myNbExt = 0;
if (!myIsAnalyticallyComputable) {
myExtPS.Perform(P);
myDone = myExtPS.IsDone();
// modified by NIZHNY-EAP Wed Nov 17 12:59:08 1999 ___BEGIN___
myNbExt = myExtPS.NbExt();
// modified by NIZHNY-EAP Wed Nov 17 12:59:09 1999 ___END___
myExtPS->Perform(P);
myDone = myExtPS->IsDone();
myNbExt = myExtPS->NbExt();
return;
}
@@ -455,10 +461,8 @@ Standard_Boolean Extrema_ExtPExtS::IsDone () const { return myDone; }
Standard_Integer Extrema_ExtPExtS::NbExt () const
{
if (!IsDone()) { throw StdFail_NotDone(); }
if (myIsAnalyticallyComputable)
return myNbExt;
else
return myExtPS.NbExt();
return myNbExt;
}
//=============================================================================
@@ -474,7 +478,7 @@ Standard_Real Extrema_ExtPExtS::SquareDistance (const Standard_Integer N) const
return mySqDist[N-1];
// modified by NIZHNY-MKK Thu Sep 18 14:48:42 2003.END
else
return myExtPS.SquareDistance(N);
return myExtPS->SquareDistance(N);
}
//=============================================================================
@@ -491,7 +495,7 @@ const Extrema_POnSurf& Extrema_ExtPExtS::Point (const Standard_Integer N) const
}
// modified by NIZHNY-MKK Thu Sep 18 14:47:43 2003.END
else
return myExtPS.Point(N);
return myExtPS->Point(N);
}
//=============================================================================

View File

@@ -50,15 +50,21 @@ class Extrema_ExtPExtS : public Standard_Transient
public:
Standard_EXPORT Extrema_ExtPExtS();
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPExtS(const Handle(Extrema_GenExtPS)& theExtPS);
//! It calculates all the distances between a point
//! from gp and a Surface.
Standard_EXPORT Extrema_ExtPExtS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& S, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPExtS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& S, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV, const Handle(Extrema_GenExtPS)& theExtPS = NULL);
//! It calculates all the distances between a point
//! from gp and a Surface.
Standard_EXPORT Extrema_ExtPExtS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& S, const Standard_Real TolU, const Standard_Real TolV);
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPExtS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& S, const Standard_Real TolU, const Standard_Real TolV, const Handle(Extrema_GenExtPS)& theExtPS = NULL);
//! Initializes the fields of the algorithm.
Standard_EXPORT void Initialize (const Handle(GeomAdaptor_HSurfaceOfLinearExtrusion)& S, const Standard_Real Uinf, const Standard_Real Usup, const Standard_Real Vinf, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
@@ -103,13 +109,12 @@ private:
Handle(GeomAdaptor_HSurfaceOfLinearExtrusion) myS;
gp_Vec myDirection;
gp_Ax2 myPosition;
Extrema_GenExtPS myExtPS;
Standard_Boolean myIsAnalyticallyComputable;
Standard_Boolean myDone;
Standard_Integer myNbExt;
Standard_Real mySqDist[4];
Extrema_POnSurf myPoint[4];
Handle(Extrema_GenExtPS) myExtPS;
};

View File

@@ -208,7 +208,9 @@ static Standard_Boolean IsExtremum (const Standard_Real U, const Standard_Real V
//purpose :
//=======================================================================
Extrema_ExtPRevS::Extrema_ExtPRevS()
Extrema_ExtPRevS::Extrema_ExtPRevS(const Handle(Extrema_GenExtPS)& theExtPS)
:
myExtPS (theExtPS)
{
myvinf = myvsup = 0.0;
mytolv = Precision::Confusion();
@@ -233,7 +235,10 @@ Extrema_ExtPRevS::Extrema_ExtPRevS (const gp_Pnt&
const Standard_Real theVmin,
const Standard_Real theVsup,
const Standard_Real theTolU,
const Standard_Real theTolV)
const Standard_Real theTolV,
const Handle(Extrema_GenExtPS)& theExtPS)
:
myExtPS (theExtPS)
{
Initialize (theS,
theUmin,
@@ -253,7 +258,10 @@ Extrema_ExtPRevS::Extrema_ExtPRevS (const gp_Pnt&
Extrema_ExtPRevS::Extrema_ExtPRevS (const gp_Pnt& theP,
const Handle(GeomAdaptor_HSurfaceOfRevolution)& theS,
const Standard_Real theTolU,
const Standard_Real theTolV)
const Standard_Real theTolV,
const Handle(Extrema_GenExtPS)& theExtPS)
:
myExtPS (theExtPS)
{
Initialize (theS,
theS->FirstUParameter(),
@@ -305,15 +313,18 @@ void Extrema_ExtPRevS::Initialize (const Handle(GeomAdaptor_HSurfaceOfRevolution
aNbv = 100;
}
myExtPS.Initialize (theS->ChangeSurface(),
aNbu,
aNbv,
theUmin,
theUsup,
theVmin,
theVsup,
theTolU,
theTolV);
if (myExtPS.IsNull())
myExtPS = new Extrema_GenExtPS();
myExtPS->Initialize (theS->ChangeSurface(),
aNbu,
aNbv,
theUmin,
theUsup,
theVmin,
theVsup,
theTolU,
theTolV);
}
}
//=======================================================================
@@ -326,11 +337,11 @@ void Extrema_ExtPRevS::Perform(const gp_Pnt& P)
myDone = Standard_False;
myNbExt = 0;
if (!myIsAnalyticallyComputable) {
myExtPS.Perform(P);
myDone = myExtPS.IsDone();
myNbExt = myExtPS.NbExt();
if (!myIsAnalyticallyComputable)
{
myExtPS->Perform(P);
myDone = myExtPS->IsDone();
myNbExt = myExtPS->NbExt();
return;
}
@@ -555,7 +566,7 @@ Standard_Real Extrema_ExtPRevS::SquareDistance(const Standard_Integer N) const
if (myIsAnalyticallyComputable)
return mySqDist[N-1];
else
return myExtPS.SquareDistance(N);
return myExtPS->SquareDistance(N);
}
//=======================================================================
//function : Point
@@ -571,7 +582,7 @@ const Extrema_POnSurf& Extrema_ExtPRevS::Point(const Standard_Integer N) const
if (myIsAnalyticallyComputable)
return myPoint[N-1];
else
return myExtPS.Point(N);
return myExtPS->Point(N);
}

View File

@@ -45,16 +45,21 @@ class Extrema_ExtPRevS : public Standard_Transient
public:
Standard_EXPORT Extrema_ExtPRevS();
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPRevS(const Handle(Extrema_GenExtPS)& theExtPS = NULL);
//! It calculates all the distances between a point
//! from gp and a SurfacePtr from Adaptor3d.
Standard_EXPORT Extrema_ExtPRevS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfRevolution)& S, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPRevS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfRevolution)& S, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV, const Handle(Extrema_GenExtPS)& theExtPS = NULL);
//! It calculates all the distances between a point
//! from gp and a SurfacePtr from Adaptor3d.
Standard_EXPORT Extrema_ExtPRevS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfRevolution)& S, const Standard_Real TolU, const Standard_Real TolV);
//! theExtPS is used to compute the solutions in case
//! it cannot be found analytically.
Standard_EXPORT Extrema_ExtPRevS(const gp_Pnt& P, const Handle(GeomAdaptor_HSurfaceOfRevolution)& S, const Standard_Real TolU, const Standard_Real TolV, const Handle(Extrema_GenExtPS)& theExtPS = NULL);
Standard_EXPORT void Initialize (const Handle(GeomAdaptor_HSurfaceOfRevolution)& S, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
@@ -90,13 +95,12 @@ private:
Standard_Real myvsup;
Standard_Real mytolv;
gp_Ax2 myPosition;
Extrema_GenExtPS myExtPS;
Standard_Boolean myIsAnalyticallyComputable;
Standard_Boolean myDone;
Standard_Integer myNbExt;
Standard_Real mySqDist[8];
Extrema_POnSurf myPoint[8];
Handle(Extrema_GenExtPS) myExtPS;
};

View File

@@ -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);
}
@@ -169,12 +169,8 @@ Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
const Adaptor3d_Surface& theS,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Extrema_ExtFlag theF,
const Extrema_ExtAlgo theA)
const Extrema_ExtFlag theTarget)
{
myExtPS.SetFlag (theF);
myExtPS.SetAlgo (theA);
Initialize (theS,
theS.FirstUParameter(),
theS.LastUParameter(),
@@ -183,6 +179,8 @@ Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
theTolU,
theTolV);
myExtPS->SetTarget (theTarget);
Perform (theP);
}
@@ -199,12 +197,8 @@ Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
const Standard_Real theVsup,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Extrema_ExtFlag theF,
const Extrema_ExtAlgo theA)
const Extrema_ExtFlag theTarget)
{
myExtPS.SetFlag (theF);
myExtPS.SetAlgo (theA);
Initialize (theS,
theUinf,
theUsup,
@@ -213,6 +207,8 @@ Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
theTolU,
theTolV);
myExtPS->SetTarget (theTarget);
Perform (theP);
}
@@ -241,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();
@@ -263,7 +264,10 @@ void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
if(bUIsoIsDeg) nbU = 300;
if(bVIsoIsDeg) nbV = 300;
myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
if (myExtPS.IsNull())
myExtPS = new Extrema_GenExtPS();
myExtPS->Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
myExtPExtS.Nullify();
myExtPRevS.Nullify();
@@ -273,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:
@@ -304,7 +325,7 @@ void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
Handle(GeomAdaptor_HSurfaceOfLinearExtrusion) aS (new GeomAdaptor_HSurfaceOfLinearExtrusion (
GeomAdaptor_SurfaceOfLinearExtrusion (myS->BasisCurve(), myS->Direction())));
myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv, myExtPS);
}
else
{
@@ -330,7 +351,7 @@ void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
Handle(GeomAdaptor_HSurfaceOfRevolution) aS (new GeomAdaptor_HSurfaceOfRevolution (
GeomAdaptor_SurfaceOfRevolution (myS->BasisCurve(), myS->AxeOfRevolution())));
myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv, myExtPS);
}
else
{
@@ -351,13 +372,13 @@ void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
default:
{
myExtPS.Perform (thePoint);
myDone = myExtPS.IsDone();
myExtPS->Perform (thePoint, myLocUMin, myLocUMax, myLocVMin, myLocVMax);
myDone = myExtPS->IsDone();
if (myDone)
{
for (Standard_Integer anIdx = 1; anIdx <= myExtPS.NbExt(); ++anIdx)
for (Standard_Integer anIdx = 1; anIdx <= myExtPS->NbExt(); ++anIdx)
{
TreatSolution (myExtPS.Point (anIdx), myExtPS.SquareDistance (anIdx));
TreatSolution (myExtPS->Point (anIdx), myExtPS->SquareDistance (anIdx));
}
}
return;
@@ -423,10 +444,8 @@ void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
{
myExtPS.SetFlag(F);
}
if (myExtPS.IsNull())
myExtPS = new Extrema_GenExtPS();
void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
{
myExtPS.SetAlgo(A);
myExtPS->SetTarget(F);
}

View File

@@ -31,7 +31,6 @@
#include <TColStd_SequenceOfReal.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Standard_Integer.hxx>
class Extrema_ExtPExtS;
class Extrema_ExtPRevS;
@@ -63,7 +62,11 @@ public:
//! TolU et TolV are used to determine the conditions
//! to stop the iterations; at the iteration number n:
//! (Un - Un-1) < TolU and (Vn - Vn-1) < TolV .
Standard_EXPORT Extrema_ExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S, const Standard_Real TolU, const Standard_Real TolV, const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX, const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
Standard_EXPORT Extrema_ExtPS(const gp_Pnt& P,
const Adaptor3d_Surface& S,
const Standard_Real TolU,
const Standard_Real TolV,
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX);
//! It calculates all the distances.
//! NbU and NbV are used to locate the close points
@@ -73,16 +76,39 @@ public:
//! TolU et TolV are used to determine the conditions
//! to stop the iterations; at the iteration number n:
//! (Un - Un-1) < TolU and (Vn - Vn-1) < TolV .
Standard_EXPORT Extrema_ExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S, const Standard_Real Uinf, const Standard_Real Usup, const Standard_Real Vinf, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV, const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX, const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
Standard_EXPORT Extrema_ExtPS(const gp_Pnt& P,
const Adaptor3d_Surface& S,
const Standard_Real Uinf,
const Standard_Real Usup,
const Standard_Real Vinf,
const Standard_Real Vsup,
const Standard_Real TolU,
const Standard_Real TolV,
const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX);
//! Initializes the fields of the algorithm.
Standard_EXPORT void Initialize (const Adaptor3d_Surface& S, const Standard_Real Uinf, const Standard_Real Usup, const Standard_Real Vinf, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
Standard_EXPORT void Initialize (const Adaptor3d_Surface& S,
const Standard_Real Uinf,
const Standard_Real Usup,
const Standard_Real Vinf,
const Standard_Real Vsup,
const Standard_Real TolU,
const Standard_Real TolV);
//! Computes the distances.
//! An exception is raised if the fieds have not been
//! 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;
@@ -107,9 +133,6 @@ public:
Standard_EXPORT void TrimmedSquareDistances (Standard_Real& dUfVf, Standard_Real& dUfVl, Standard_Real& dUlVf, Standard_Real& dUlVl, gp_Pnt& PUfVf, gp_Pnt& PUfVl, gp_Pnt& PUlVf, gp_Pnt& PUlVl) const;
Standard_EXPORT void SetFlag (const Extrema_ExtFlag F);
Standard_EXPORT void SetAlgo (const Extrema_ExtAlgo A);
@@ -130,7 +153,7 @@ private:
Adaptor3d_SurfacePtr myS;
Standard_Boolean myDone;
Extrema_ExtPElS myExtPElS;
Extrema_GenExtPS myExtPS;
Handle(Extrema_GenExtPS) myExtPS;
Extrema_SequenceOfPOnSurf myPoints;
Standard_Real myuinf;
Standard_Real myusup;
@@ -138,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;

View File

@@ -25,25 +25,31 @@
#include <Precision.hxx>
#include <Standard_TypeMismatch.hxx>
Extrema_FuncPSNorm::Extrema_FuncPSNorm ()
: myS(NULL),
Extrema_FuncPSNorm::Extrema_FuncPSNorm()
:
myS(NULL),
myU(0.0),
myV(0.0)
myV(0.0),
myPinit (Standard_False),
mySinit (Standard_False),
myTarget (Extrema_ExtFlag_MINMAX),
myBestSqDistance (-1)
{
myPinit = Standard_False;
mySinit = Standard_False;
}
//=============================================================================
Extrema_FuncPSNorm::Extrema_FuncPSNorm (const gp_Pnt& P,
const Adaptor3d_Surface& S)
: myU(0.0),
myV(0.0)
const Adaptor3d_Surface& S)
:
myP (P),
myS ((Adaptor3d_SurfacePtr)&S),
myU(0.0),
myV(0.0),
myPinit (Standard_True),
mySinit (Standard_True),
myTarget (Extrema_ExtFlag_MINMAX),
myBestSqDistance (-1)
{
myP = P;
myS = (Adaptor3d_SurfacePtr)&S;
myPinit = Standard_True;
mySinit = Standard_True;
}
//=============================================================================
@@ -51,18 +57,23 @@ void Extrema_FuncPSNorm::Initialize(const Adaptor3d_Surface& S)
{
myS = (Adaptor3d_SurfacePtr)&S;
mySinit = Standard_True;
myPoint.Clear();
mySqDist.Clear();
myPoints.clear();
mySqDistances.clear();
myTarget = Extrema_ExtFlag_MINMAX;
myBestSqDistance = -1;
}
//=============================================================================
void Extrema_FuncPSNorm::SetPoint(const gp_Pnt& P)
void Extrema_FuncPSNorm::SetPoint (const gp_Pnt& P,
const Extrema_ExtFlag theTarget)
{
myP = P;
myPinit = Standard_True;
myPoint.Clear();
mySqDist.Clear();
myTarget = theTarget;
myBestSqDistance = (myTarget == Extrema_ExtFlag_MIN ? RealLast() : RealFirst());
myPoints.clear();
mySqDistances.clear();
}
//=============================================================================
@@ -124,45 +135,66 @@ Standard_Boolean Extrema_FuncPSNorm::Values (const math_Vector& UV,
return Standard_True;
}
//=============================================================================
Standard_Integer Extrema_FuncPSNorm::GetStateNumber ()
//=============================================================================
Standard_Integer Extrema_FuncPSNorm::GetStateNumber()
{
if (!myPinit || !mySinit) throw Standard_TypeMismatch();
//comparison of solution with previous solutions
Standard_Integer i = 1, nbSol = mySqDist.Length();
Standard_Real tol2d = Precision::PConfusion() * Precision::PConfusion();
for( ; i <= nbSol; i++)
Standard_Real aNewSqDist = myPs.SquareDistance (myP);
if ((myTarget == Extrema_ExtFlag_MIN && aNewSqDist > myBestSqDistance) ||
(myTarget == Extrema_ExtFlag_MAX && aNewSqDist < myBestSqDistance))
return 0;
myBestSqDistance = aNewSqDist;
// Comparison of solution with previous solutions
Standard_Real tol2d = Precision::SquarePConfusion();
std::size_t i = 0, nbSol = mySqDistances.size();
for (; i < nbSol; i++)
{
Standard_Real aU, aV;
myPoint(i).Parameter(aU, aV);
if( ((myU - aU ) * (myU - aU ) + (myV - aV ) * (myV - aV )) <= tol2d )
Extrema_POnSurf& aPOnSurf = myPoints[i];
aPOnSurf.Parameter (aU, aV);
if (((myU - aU) * (myU - aU) + (myV - aV) * (myV - aV)) <= tol2d)
{
// The points are almost the same in the parametric space.
if (myTarget != Extrema_ExtFlag_MINMAX)
{
// Check if new solution gives better distance than the existing solution.
Standard_Real& anOldSqDist = mySqDistances[i];
if ((myTarget == Extrema_ExtFlag_MIN && aNewSqDist < anOldSqDist) ||
(myTarget == Extrema_ExtFlag_MAX && aNewSqDist > anOldSqDist))
{
aPOnSurf.SetParameters (myU, myV, myPs);
anOldSqDist = aNewSqDist;
}
}
break;
}
}
if( i <= nbSol)
return 0;
mySqDist.Append(myPs.SquareDistance(myP));
myPoint.Append(Extrema_POnSurf(myU,myV,myPs));
if (i < nbSol)
return 0;
mySqDistances.push_back (aNewSqDist);
myPoints.push_back (Extrema_POnSurf (myU, myV, myPs));
return 0;
}
//=============================================================================
Standard_Integer Extrema_FuncPSNorm::NbExt () const
{
return mySqDist.Length();
return static_cast<Standard_Integer>(mySqDistances.size());
}
//=============================================================================
Standard_Real Extrema_FuncPSNorm::SquareDistance (const Standard_Integer N) const
{
if (!myPinit || !mySinit) throw Standard_TypeMismatch();
return mySqDist.Value(N);
return mySqDistances [N - 1];
}
//=============================================================================
const Extrema_POnSurf& Extrema_FuncPSNorm::Point (const Standard_Integer N) const
{
if (!myPinit || !mySinit) throw Standard_TypeMismatch();
return myPoint.Value(N);
return myPoints [N - 1];
}

View File

@@ -23,12 +23,12 @@
#include <gp_Pnt.hxx>
#include <Adaptor3d_SurfacePtr.hxx>
#include <Standard_Real.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <Extrema_SequenceOfPOnSurf.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Standard_Boolean.hxx>
#include <math_FunctionSetWithDerivatives.hxx>
#include <Standard_Integer.hxx>
#include <math_Vector.hxx>
#include <vector>
class Standard_OutOfRange;
class gp_Pnt;
class Adaptor3d_Surface;
@@ -71,8 +71,10 @@ public:
//! sets the field mysurf of the function.
Standard_EXPORT void Initialize (const Adaptor3d_Surface& S);
//! sets the field mysurf of the function.
Standard_EXPORT void SetPoint (const gp_Pnt& P);
//! Initializes the function with the point and
//! target (MIN, MAX or MINMAX). MINMAX is used as default target.
Standard_EXPORT void SetPoint (const gp_Pnt& P,
const Extrema_ExtFlag theTarget = Extrema_ExtFlag_MINMAX);
Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE;
@@ -99,6 +101,19 @@ public:
//! Returns the Nth extremum.
Standard_EXPORT const Extrema_POnSurf& Point (const Standard_Integer N) const;
//! Returns the target (MIN, MAX or MINMAX).
Extrema_ExtFlag Target() const
{
return myTarget;
}
//! Returns the best (min or max, depending on the mode) found
//! square distance. Does not make sense for MINMAX mode.
Standard_Real BestSquareDistance() const
{
return myBestSqDistance;
}
private:
gp_Pnt myP;
@@ -106,9 +121,11 @@ private:
Standard_Real myU;
Standard_Real myV;
gp_Pnt myPs;
TColStd_SequenceOfReal mySqDist;
Extrema_SequenceOfPOnSurf myPoint;
std::vector<Standard_Real> mySqDistances;
std::vector<Extrema_POnSurf> myPoints;
Standard_Boolean myPinit;
Standard_Boolean mySinit;
Extrema_ExtFlag myTarget;
Standard_Real myBestSqDistance;
};
#endif // _Extrema_FunctPSNorm_HeaderFile

File diff suppressed because it is too large Load Diff

View File

@@ -21,18 +21,19 @@
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Adaptor3d_SurfacePtr.hxx>
#include <BVH_BoxSet.hxx>
#include <BVH_IndexedBoxSet.hxx>
#include <BVH_Traverse.hxx>
#include <Extrema_HArray2OfPOnSurfParams.hxx>
#include <Extrema_FuncPSNorm.hxx>
#include <Extrema_POnSurfParams.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
#include <Standard_Integer.hxx>
#include <Extrema_HArray2OfPOnSurfParams.hxx>
#include <Extrema_HUBTreeOfSphere.hxx>
#include <Bnd_HArray1OfSphere.hxx>
#include <Extrema_FuncPSNorm.hxx>
#include <Adaptor3d_SurfacePtr.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Standard_Transient.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <Extrema_POnSurfParams.hxx>
class StdFail_NotDone;
class Standard_OutOfRange;
class Standard_TypeMismatch;
@@ -42,130 +43,375 @@ class Extrema_POnSurf;
class Extrema_POnSurfParams;
//! It calculates all the extremum distances
//! between a point and a surface.
//! Grid cell defined by (U, V) indices of the minimal
//! corner of the cell
struct Extrema_GenExtPS_GridCell
{
Standard_Integer UIndex; //!< U index of the minimal corner
Standard_Integer VIndex; //!< V index of the minimal corner
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, Extrema_GenExtPS_GridCell> Extrema_GenExtPS_GridCellBoxSet;
//! It calculates the extreme distances between a point and a surface.
//! These distances can be minimum or maximum.
class Extrema_GenExtPS
//!
//! The function F(u,v) = distance (P, S(u,v)) has an extrema when
//! gradient(F) = 0. The algorithm searches all the zeros inside
//! the definition ranges of the surface.
//!
//! When defining the surface, the number of samples in U and V direction
//! should be specified. These numbers should be great enough such
//! that if there exist N extreme distances between the point and the surface,
//! so there also exist N extrema between the point and the grid.
//!
//! It is possible to look for extrema distances in the whole parametric
//! space of the surface or limit it with the specified range which can be
//! useful when it is needed to look for local extrema distances.
//!
//! Parametric tolerances are used to determine the conditions to stop the
//! iterations - at the iteration number n:
//! (Un - Un-1) < TolU and (Vn - Vn-1) < TolV
//!
//! It is possible to look for only Minimal or Maximal distances,
//! as well as for all solutions.
//!
//! 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, Extrema_GenExtPS_GridCellBoxSet>,
public Standard_Transient
{
public:
DEFINE_STANDARD_ALLOC
DEFINE_STANDARD_RTTIEXT (Extrema_GenExtPS, Standard_Transient)
public: //! @name Constructors computing the distances
//! Constructor for computation of the distances between specified point and surface.
//! The whole parametric space of the surfaces is taken into account.
//!
//! Constructor is mostly used for one time projection of the point on the surface,
//! but still the instances of extrema can be used for projecting other points on the surface
//! with *Perform()* method.
//!
//! @param theP point
//! @param theS Surface
//! @param theNbU Number of samples in U direction
//! @param theNbV Number of samples in V direction
//! @param theTolU U Parametric tolerance
//! @param theTolV V Parametric tolerance
//! @param theTarget defines what solutions are required
Standard_EXPORT Extrema_GenExtPS (const gp_Pnt& theP,
const Adaptor3d_Surface& theS,
const Standard_Integer theNbU,
const Standard_Integer theNbV,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Extrema_ExtFlag theTarget = Extrema_ExtFlag_MINMAX);
//! Constructor for computation of the distances between specified point and surface.
//! Only the specified parametric range of the surface is taken into account.
//!
//! Constructor is mostly used for one time projection of the point on the surface,
//! but still the instances of extrema can be used for projecting other points on the surface
//! with *Perform()* method.
//!
//! @param theP point
//! @param theS Surface
//! @param theNbU Number of samples in U direction
//! @param theNbV Number of samples in V direction
//! @param theUMin Lower U bound
//! @param theUMax Upper U bound
//! @param theVMin Lower V bound
//! @param theVMax Upper V bound
//! @param theTolU U Parametric tolerance
//! @param theTolV V Parametric tolerance
//! @param theTarget defines what solutions are required
Standard_EXPORT Extrema_GenExtPS (const gp_Pnt& theP,
const Adaptor3d_Surface& theS,
const Standard_Integer theNbU,
const Standard_Integer theNbV,
const Standard_Real theUMin,
const Standard_Real theUMax,
const Standard_Real theVMin,
const Standard_Real theVMax,
const Standard_Real theTolU,
const Standard_Real theTolV,
const Extrema_ExtFlag theTarget = Extrema_ExtFlag_MINMAX);
public: //! @name Empty constructor + Initialization step
//! Empty constructor
Standard_EXPORT Extrema_GenExtPS();
//! Initializes Extrema algorithm with the surfaces.
//! Search is performed in whole parametric range of the surface.
//! @param theS Surface
//! @param theNbU Number of samples in U direction
//! @param theNbV Number of samples in V direction
//! @param theTolU U Parametric tolerance
//! @param theTolV V Parametric tolerance
Standard_EXPORT void Initialize (const Adaptor3d_Surface& theS,
const Standard_Integer theNbU,
const Standard_Integer theNbV,
const Standard_Real theTolU,
const Standard_Real theTolV);
//! Initializes Extrema algorithm with the surfaces.
//! Search is performed in the given parametric range.
//! @param S Surface
//! @param theNbU Number of samples in U direction
//! @param theNbV Number of samples in V direction
//! @param theUMin Lower U bound
//! @param theUMax Upper U bound
//! @param theVMin Lower V bound
//! @param theVMax Upper V bound
//! @param theTolU U Parametric tolerance
//! @param theTolV V Parametric tolerance
Standard_EXPORT void Initialize (const Adaptor3d_Surface& theS,
const Standard_Integer theNbU,
const Standard_Integer theNbV,
const Standard_Real theUMin,
const Standard_Real theUMax,
const Standard_Real theVMin,
const Standard_Real theVMax,
const Standard_Real theTolU,
const Standard_Real theTolV);
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 (default value).
void SetTarget (const Extrema_ExtFlag theTarget)
{
myTarget = theTarget;
}
//! Returns the Extrema target type
Extrema_ExtFlag Target() const { return myTarget; }
//! Sets the tolerance for the search.
//! These tolerances are used for projection of the point,
//! and not used for surface initialization, so can be changed
//! from point to point.
void SetTolerance (const Standard_Real theTolU,
const Standard_Real theTolV)
{
myTolU = theTolU;
myTolV = theTolV;
}
public: //! @name Performing projection
//! Performs projection of the point on the surface.
//! Extrema must already be initialized with the surface.
//! 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);
//! It calculates all the distances.
//! The function F(u,v)=distance(P,S(u,v)) has an
//! extremum when gradient(F)=0. The algorithm searchs
//! all the zeros inside the definition ranges of the
//! surface.
//! NbU and NbV are used to locate the close points
//! to find the zeros. They must be great enough
//! such that if there is N extrema, there will
//! be N extrema between P and the grid.
//! TolU et TolV are used to determine the conditions
//! to stop the iterations; at the iteration number n:
//! (Un - Un-1) < TolU and (Vn - Vn-1) < TolV .
Standard_EXPORT Extrema_GenExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S, const Standard_Integer NbU, const Standard_Integer NbV, const Standard_Real TolU, const Standard_Real TolV, const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX, const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
//! It calculates all the distances.
//! The function F(u,v)=distance(P,S(u,v)) has an
//! extremum when gradient(F)=0. The algorithm searchs
//! all the zeros inside the definition ranges of the
//! surface.
//! NbU and NbV are used to locate the close points
//! to find the zeros. They must be great enough
//! such that if there is N extrema, there will
//! be N extrema between P and the grid.
//! TolU et TolV are used to determine the conditions
//! to stop the iterations; at the iteration number n:
//! (Un - Un-1) < TolU and (Vn - Vn-1) < TolV .
Standard_EXPORT Extrema_GenExtPS(const gp_Pnt& P, const Adaptor3d_Surface& S, const Standard_Integer NbU, const Standard_Integer NbV, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV, const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX, const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Initialize (const Adaptor3d_Surface& S, const Standard_Integer NbU, const Standard_Integer NbV, const Standard_Real TolU, const Standard_Real TolV);
Standard_EXPORT void Initialize (const Adaptor3d_Surface& S, const Standard_Integer NbU, const Standard_Integer NbV, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real TolU, const Standard_Real TolV);
//! the algorithm is done with the point P.
//! An exception is raised if the fields have not
//! been initialized.
Standard_EXPORT void Perform (const gp_Pnt& P);
Standard_EXPORT void SetFlag (const Extrema_ExtFlag F);
Standard_EXPORT void SetAlgo (const Extrema_ExtAlgo A);
public: //! @name Getting the results
//! Returns True if the distances are found.
Standard_EXPORT Standard_Boolean IsDone() const;
//! Returns the number of extremum distances.
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.
Standard_EXPORT Standard_Real SquareDistance (const Standard_Integer N) const;
//! @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.
Standard_EXPORT const Extrema_POnSurf& Point (const Standard_Integer N) const;
//! @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;
protected: //! @name Protected methods performing the job
//! Creation of grid of parametric points (sampling of the surface)
Standard_EXPORT void BuildGrid();
protected:
private:
Standard_EXPORT Adaptor3d_SurfacePtr Bidon() const;
Standard_EXPORT void BuildTree();
Standard_EXPORT void FindSolution (const gp_Pnt& P, const Extrema_POnSurfParams& theParams);
//! Selection of points to build grid, depending on the type of surface
Standard_EXPORT void GetGridPoints (const Adaptor3d_Surface& theSurf);
//! Creation of grid of parametric points
Standard_EXPORT void BuildGrid (const gp_Pnt& thePoint);
//! Builds the BVH tree with bounding boxes of the cells of the grid
Standard_EXPORT void BuildTree();
//! Looks for the solution starting at given point
Standard_EXPORT Standard_Boolean FindSolution (const Extrema_POnSurfParams& theParams);
//! Compute new edge parameters.
Standard_EXPORT const Extrema_POnSurfParams& ComputeEdgeParameters (const Standard_Boolean IsUEdge, const Extrema_POnSurfParams& theParam0, const Extrema_POnSurfParams& theParam1, const gp_Pnt& thePoints, const Standard_Real theDiffTol);
Standard_EXPORT const Extrema_POnSurfParams&
ComputeFaceParameters (const Standard_Integer theU,
const Standard_Integer theV);
//! Compute new edge parameters.
Standard_EXPORT const Extrema_POnSurfParams&
ComputeEdgeParameters (const Standard_Boolean IsUEdge,
const Extrema_POnSurfParams& theParam0,
const Extrema_POnSurfParams& theParam1,
const Standard_Real theDiffTol);
//! Looks for the Min or Max Solution (depending on the given target).
Standard_EXPORT Standard_Boolean FindSolution (const Standard_Integer theUIndex,
const Standard_Integer theVIndex,
const Extrema_ExtFlag theTarget);
Standard_Boolean myDone;
Standard_Boolean myInit;
Standard_Real myumin;
Standard_Real myusup;
Standard_Real myvmin;
Standard_Real myvsup;
Standard_Integer myusample;
Standard_Integer myvsample;
Standard_Real mytolu;
Standard_Real mytolv;
Handle(Extrema_HArray2OfPOnSurfParams) myPoints;
Extrema_HUBTreeOfSphere mySphereUBTree;
Handle(Bnd_HArray1OfSphere) mySphereArray;
Extrema_FuncPSNorm myF;
Adaptor3d_SurfacePtr myS;
Extrema_ExtFlag myFlag;
Extrema_ExtAlgo myAlgo;
Handle(TColStd_HArray1OfReal) myUParams;
Handle(TColStd_HArray1OfReal) myVParams;
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 Extrema_GenExtPS_ExtPSResult
{
Extrema_POnSurf UV; //! UV coordinates of extrema solution
Standard_Real SqDistance; //! Square distance to target point
Extrema_GenExtPS_ExtPSResult()
: SqDistance (-1)
{}
Extrema_GenExtPS_ExtPSResult (const Extrema_POnSurf& theUV,
const Standard_Real theSqDist)
: UV (theUV),
SqDistance (theSqDist)
{}
//! IsLess operator
Standard_Boolean operator< (const Extrema_GenExtPS_ExtPSResult& Other) const
{
if (SqDistance != Other.SqDistance)
return SqDistance < Other.SqDistance;
Standard_Real U1, U2, V1, V2;
UV.Parameter (U1, V1);
Other.UV.Parameter (U2, V2);
return (U1 < U2 || (U1 == U2 && V1 < V2));
}
};
//! Localized parametric space of surface on which the single
//! BVH tree is built
struct Extrema_GenExtPS_LocalizedGrid
{
Standard_Integer IdUMin;
Standard_Integer IdUMax;
Standard_Integer IdVMin;
Standard_Integer IdVMax;
Handle(Extrema_GenExtPS_GridCellBoxSet) CellBoxSet;
Extrema_GenExtPS_LocalizedGrid ()
: IdUMin (0), IdUMax (0), IdVMin (0), IdVMax (0), CellBoxSet (NULL)
{}
Extrema_GenExtPS_LocalizedGrid (const Standard_Integer theUMin,
const Standard_Integer theUMax,
const Standard_Integer theVMin,
const Standard_Integer theVMax,
const Handle(Extrema_GenExtPS_GridCellBoxSet)& theCellBoxSet)
: IdUMin (theUMin), IdUMax (theUMax),
IdVMin (theVMin), IdVMax (theVMax),
CellBoxSet (theCellBoxSet)
{}
};
protected: //! @name Fields
// Inputs
gp_Pnt myPoint; //!< Point
Adaptor3d_SurfacePtr myS; //!< Surface
Extrema_FuncPSNorm myF; //!< Function
Standard_Real myUMin; //!< Surface parametric range: UMin
Standard_Real myUMax; //!< Surface parametric range: UMax
Standard_Real myVMin; //!< Surface parametric range: VMin
Standard_Real myVMax; //!< Surface parametric range: VMax
Standard_Integer myNbUSamples; //!< Number of samples in U parametric direction
Standard_Integer myNbVSamples; //!< Number of samples in V parametric direction
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
Handle(Extrema_HArray2OfPOnSurfParams) myPoints; //!< Grid points
Handle(TColStd_HArray1OfReal) myUParams; //!< Grid parameters in U parametric direction
Handle(TColStd_HArray1OfReal) myVParams; //!< Grid parameters in V parametric direction
Handle(Extrema_HArray2OfPOnSurfParams) myFacePntParams;
Handle(Extrema_HArray2OfPOnSurfParams) myUEdgePntParams;
Handle(Extrema_HArray2OfPOnSurfParams) myVEdgePntParams;
Extrema_POnSurfParams myGridParam;
Standard_Real mySqDistance; //!< Min/Max found square distance used in BVH tree traverse
opencascade::handle
<BVH_IndexedBoxSet<Standard_Real, 3, Extrema_GenExtPS_LocalizedGrid> > myBVHBoxSet; //!< High-level BVH of BVH organized grid cells
// Results
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
};
DEFINE_STANDARD_HANDLE (Extrema_GenExtPS, Standard_Transient)
#endif // _Extrema_GenExtPS_HeaderFile

View File

@@ -12,7 +12,7 @@
// commercial license or contractual agreement.
inline Extrema_POnSurfParams::Extrema_POnSurfParams()
: mySqrDistance (0.),
: mySqrDistance (-1),
myElementType (Extrema_Node),
myIndexU (0),
myIndexV (0)
@@ -22,7 +22,7 @@ inline Extrema_POnSurfParams::Extrema_POnSurfParams()
inline Extrema_POnSurfParams::Extrema_POnSurfParams
(const Standard_Real theU, const Standard_Real theV, const gp_Pnt &thePnt)
: Extrema_POnSurf (theU, theV, thePnt),
mySqrDistance (0.),
mySqrDistance (-1),
myElementType (Extrema_Node),
myIndexU (0),
myIndexV (0)

View File

@@ -33,7 +33,6 @@ Extrema_EPCOfExtPC.hxx
Extrema_EPCOfExtPC2d.hxx
Extrema_EPCOfExtPC2d_0.cxx
Extrema_EPCOfExtPC_0.cxx
Extrema_ExtAlgo.hxx
Extrema_ExtCC.cxx
Extrema_ExtCC.hxx
Extrema_ExtCC2d.cxx

View File

@@ -1,3 +1,5 @@
GCPnts.cxx
GCPnts.hxx
GCPnts_AbscissaPoint.cxx
GCPnts_AbscissaPoint.pxx
GCPnts_AbscissaPoint.hxx

54
src/GCPnts/GCPnts.cxx Normal file
View 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
View 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

View File

@@ -40,10 +40,9 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
//purpose :
//=======================================================================
GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf (const gp_Pnt& P,
const Handle(Geom_Surface)& Surface,
const Extrema_ExtAlgo theProjAlgo)
const Handle(Geom_Surface)& Surface)
{
Init (P, Surface, theProjAlgo);
Init (P, Surface);
}
//=======================================================================
//function : GeomAPI_ProjectPointOnSurf
@@ -51,10 +50,9 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
//=======================================================================
GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf (const gp_Pnt& P,
const Handle(Geom_Surface)& Surface,
const Standard_Real Tolerance,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Tolerance)
{
Init (P, Surface, Tolerance, theProjAlgo);
Init (P, Surface, Tolerance);
}
//=======================================================================
//function : GeomAPI_ProjectPointOnSurf
@@ -65,11 +63,10 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Umin,
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Vsup)
{
Init (P, Surface, Umin, Usup, Vmin, Vsup, theProjAlgo);
Init (P, Surface, Umin, Usup, Vmin, Vsup);
}
//=======================================================================
//function : GeomAPI_ProjectPointOnSurf
@@ -81,11 +78,10 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Standard_Real Tolerance,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Tolerance)
{
Init (P, Surface, Umin, Usup, Vmin, Vsup, Tolerance, theProjAlgo);
Init (P, Surface, Umin, Usup, Vmin, Vsup, Tolerance);
}
//=======================================================================
//function : Init
@@ -114,11 +110,10 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
//purpose :
//=======================================================================
void GeomAPI_ProjectPointOnSurf::Init (const gp_Pnt& P,
const Handle(Geom_Surface)& Surface,
const Extrema_ExtAlgo theProjAlgo)
const Handle(Geom_Surface)& Surface)
{
Init (P, Surface, Precision::Confusion(), theProjAlgo);
Init (P, Surface, Precision::Confusion());
}
//=======================================================================
//function : Init
@@ -126,27 +121,15 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
//=======================================================================
void GeomAPI_ProjectPointOnSurf::Init(const gp_Pnt& P,
const Handle(Geom_Surface)& Surface,
const Standard_Real Tolerance,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Tolerance)
{
//modified by NIZNHY-PKV Thu Apr 4 10:37:55 2002 f
//GeomAdaptor_Surface TheSurface (Surface);
//myExtPS = Extrema_ExtPS (P, TheSurface, Tolerance, Tolerance);
//modified by NIZNHY-PKV Mon Apr 8 11:13:37 2002 f XXX
Standard_Real Umin, Usup, Vmin, Vsup;
Surface->Bounds(Umin, Usup, Vmin, Vsup);
myGeomAdaptor.Load(Surface, Umin, Usup, Vmin, Vsup);
//
//myExtPS = Extrema_ExtPS();
myExtPS.SetAlgo(theProjAlgo);
myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
myExtPS.Perform(P);
//XXXmyExtPS = Extrema_ExtPS (P, myGeomAdaptor, Tolerance, Tolerance);
//modified by NIZNHY-PKV Mon Apr 8 11:13:44 2002 t XXX
//modified by NIZNHY-PKV Thu Apr 4 10:37:58 2002 t
Init ();
}
@@ -160,20 +143,12 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Umin,
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Vsup)
{
Standard_Real Tolerance = Precision::PConfusion();
//modified by NIZNHY-PKV Thu Apr 4 10:38:23 2002 f
//GeomAdaptor_Surface TheSurface (Surface,Umin,Usup,Vmin,Vsup);
//myExtPS = Extrema_ExtPS (P, TheSurface, Tol, Tol);
myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
//myExtPS = Extrema_ExtPS();
myExtPS.SetAlgo(theProjAlgo);
myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
myExtPS.Perform(P);
//XXX myExtPS = Extrema_ExtPS (P, myGeomAdaptor, Tol, Tol);
//modified by NIZNHY-PKV Thu Apr 4 10:38:30 2002 t
Init ();
}
@@ -187,19 +162,11 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Standard_Real Tolerance,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Tolerance)
{
//modified by NIZNHY-PKV Thu Apr 4 10:39:10 2002 f
//GeomAdaptor_Surface TheSurface (Surface,Umin,Usup,Vmin,Vsup);
//myExtPS = Extrema_ExtPS (P, TheSurface, Tolerance, Tolerance);
myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
//myExtPS = Extrema_ExtPS();
myExtPS.SetAlgo(theProjAlgo);
myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
myExtPS.Perform(P);
//XXX myExtPS = Extrema_ExtPS (P, myGeomAdaptor, Tolerance, Tolerance);
//modified by NIZNHY-PKV Thu Apr 4 10:39:14 2002 t
Init ();
}
//=======================================================================
@@ -210,20 +177,11 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Umin,
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Vsup)
{
Standard_Real Tolerance = Precision::PConfusion();
//modified by NIZNHY-PKV Thu Apr 4 10:41:50 2002 f
//GeomAdaptor_Surface TheSurface (Surface,Umin,Usup,Vmin,Vsup);
myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
//modified by NIZNHY-PKV Thu Apr 4 10:42:29 2002 t
//myExtPS = Extrema_ExtPS();
//modified by NIZNHY-PKV Thu Apr 4 10:42:32 2002 f
//myExtPS.Initialize(TheSurface, Umin, Usup, Vmin, Vsup, Tol, Tol);
myExtPS.SetAlgo(theProjAlgo);
myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
//modified by NIZNHY-PKV Thu Apr 4 10:42:39 2002 t
myIsDone = Standard_False;
}
//=======================================================================
@@ -235,19 +193,10 @@ GeomAPI_ProjectPointOnSurf::GeomAPI_ProjectPointOnSurf()
const Standard_Real Usup,
const Standard_Real Vmin,
const Standard_Real Vsup,
const Standard_Real Tolerance,
const Extrema_ExtAlgo theProjAlgo)
const Standard_Real Tolerance)
{
//modified by NIZNHY-PKV Thu Apr 4 10:43:00 2002 f
//GeomAdaptor_Surface TheSurface (Surface,Umin,Usup,Vmin,Vsup);
myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
//modified by NIZNHY-PKV Thu Apr 4 10:43:16 2002 t
//myExtPS = Extrema_ExtPS();
//modified by NIZNHY-PKV Thu Apr 4 10:43:18 2002 f
//myExtPS.Initialize(TheSurface, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
myExtPS.SetAlgo(theProjAlgo);
myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
//modified by NIZNHY-PKV Thu Apr 4 10:43:26 2002 t
myIsDone = Standard_False;
}
//=======================================================================

View File

@@ -25,7 +25,6 @@
#include <Standard_Integer.hxx>
#include <Extrema_ExtPS.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Standard_Real.hxx>
class Standard_OutOfRange;
@@ -51,45 +50,38 @@ public:
//! Create the projection of a point <P> on a surface
//! <Surface>
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface);
//! Create the projection of a point <P> on a surface
//! <Surface>
//! Create the projection of a point <P> on a surface
//! <Surface>. The solution are computed in the domain
//! [Umin,Usup] [Vmin,Vsup] of the surface.
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Tolerance, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Tolerance);
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance);
//! Init the projection of a point <P> on a surface
//! <Surface>
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT GeomAPI_ProjectPointOnSurf(const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Tolerance, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Tolerance);
//! Init the projection of a point <P> on a surface
//! <Surface>. The solution are computed in the domain
//! [Umin,Usup] [Vmin,Vsup] of the surface.
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance);
//! Init the projection for many points on a surface
//! <Surface>. The solutions will be computed in the domain
//! [Umin,Usup] [Vmin,Vsup] of the surface.
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Init (const gp_Pnt& P, const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup);
Standard_EXPORT void Init (const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
Standard_EXPORT void Init (const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Standard_Real Tolerance);
Standard_EXPORT void Init (const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup, const Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Grad);
//! Sets the Extrema search algorithm - Grad or Tree. <br>
//! By default the Extrema is initialized with Grad algorithm.
void SetExtremaAlgo(const Extrema_ExtAlgo theAlgo)
{
myExtPS.SetAlgo(theAlgo);
}
Standard_EXPORT void Init (const Handle(Geom_Surface)& Surface, const Standard_Real Umin, const Standard_Real Usup, const Standard_Real Vmin, const Standard_Real Vsup);
//! Sets the Extrema search flag - MIN or MAX or MINMAX.<br>
//! By default the Extrema is set to search the MinMax solutions.

View File

@@ -1112,9 +1112,8 @@ void GeomInt_IntSS::BuildPCurves (Standard_Real f,
const gp_Pnt aP3d1 = C->Value(f);
const gp_Pnt aP3d2 = C->Value(l);
anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
anExtr.Initialize(anAS, umin, umax, vmin, vmax,
Precision::Confusion(), Precision::Confusion());
Precision::Confusion(), Precision::Confusion());
anExtr.Perform(aP3d1);
if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))

View File

@@ -89,9 +89,9 @@ static void showProjSolution(Draw_Interpretor& di,
static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
{
if ( n < 5)
if ( n != 5 && n != 7)
{
Message::SendFail() << " Use proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]";
Message::SendFail() << " Use proj curve/surf x y z [{u v}]";
return 1;
}
@@ -99,10 +99,6 @@ static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const ch
Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
Handle(Geom_Surface) GS;
Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad;
if (n == 6 && a[5][0] == 't')
aProjAlgo = Extrema_ExtAlgo_Tree;
if (GC.IsNull())
{
@@ -111,12 +107,12 @@ static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const ch
if (GS.IsNull())
return 1;
if (n <= 6)
if (n == 5)
{
Standard_Real U1, U2, V1, V2;
GS->Bounds(U1,U2,V1,V2);
GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo);
GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2);
if (!proj.IsDone())
{
di << "projection failed.";
@@ -753,7 +749,7 @@ void GeometryTest::APICommands(Draw_Interpretor& theCommands)
done = Standard_True;
theCommands.Add("proj", "proj curve/surf x y z [{extrema algo: g(grad)/t(tree)}|{u v}]\n"
theCommands.Add("proj", "proj curve/surf x y z [{u v}]\n"
"\t\tOptional parameters are relevant to surf only.\n"
"\t\tIf initial {u v} are given then local extrema is called",__FILE__, proj);

View File

@@ -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);
gp_Pnt2d pnt;
// Perform search on the whole parametric space using preinitialized extrema.
theData.myGlobExtPS.Perform (p, uInfLi, uSupLi, vInfLi, vSupLi);
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() {}

View File

@@ -198,14 +198,13 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,
Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,
const Handle(Geom_Surface)& S,
gp_Pnt2d& UV,Standard_Real& dist,
const Extrema_ExtFlag anExtFlag,
const Extrema_ExtAlgo anExtAlgo)
const Extrema_ExtFlag anExtFlag)
{
Standard_Real UMin, UMax, VMin, VMax;
GeomAPI_ProjectPointOnSurf PonS;
//
S->Bounds(UMin, UMax, VMin, VMax);
PonS.Init(S, UMin, UMax, VMin, VMax, anExtAlgo);
PonS.Init(S, UMin, UMax, VMin, VMax);
Extrema_ExtPS& anExtPS = const_cast<Extrema_ExtPS&>(PonS.Extrema());
anExtPS.SetFlag(anExtFlag);
//
@@ -279,11 +278,10 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const
// ----------------------------------------------------------------------
Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,
gp_Pnt2d& UV,Standard_Real& dist,
const Extrema_ExtFlag anExtFlag,
const Extrema_ExtAlgo anExtAlgo)
const Extrema_ExtFlag anExtFlag)
{
dist = 1.;
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist, anExtFlag, anExtAlgo);
Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist, anExtFlag);
return ok;
}

View File

@@ -27,7 +27,6 @@
#include <Extrema_ExtPC.hxx>
#include <Extrema_ExtPC2d.hxx>
#include <Extrema_ExtFlag.hxx>
#include <Extrema_ExtAlgo.hxx>
// ----------------------------------------------------------------------
// project point <P> on geometries (curve <C>,surface <S>)
@@ -42,8 +41,7 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const Stand
Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const BRepAdaptor_Curve2d& BAC2D,const Standard_Real pmin,const Standard_Real pmax,Standard_Real& param,Standard_Real& dist);
Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P,const BRepAdaptor_Curve2d& BAC2D,Standard_Real& param,Standard_Real& dist);
Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P,const Handle(Geom_Surface)& S,gp_Pnt2d& UV,Standard_Real& dist,
const Extrema_ExtFlag anExtFlag=Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo anExtAlgo=Extrema_ExtAlgo_Grad);
const Extrema_ExtFlag anExtFlag=Extrema_ExtFlag_MINMAX);
// ----------------------------------------------------------------------
// project point <P> on topologies (edge <E>,face <F>)
@@ -52,7 +50,6 @@ Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const Standar
Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const TopoDS_Edge& E,Standard_Real& param,Standard_Real& dist);
Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const TopoDS_Face& F,gp_Pnt2d& UV,Standard_Real& dist);
Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,gp_Pnt2d& UV,Standard_Real& dist,
const Extrema_ExtFlag anExtFlag=Extrema_ExtFlag_MINMAX,
const Extrema_ExtAlgo anExtAlgo=Extrema_ExtAlgo_Grad);
const Extrema_ExtFlag anExtFlag=Extrema_ExtFlag_MINMAX);
#endif

View File

@@ -7,31 +7,23 @@ puts ""
#############################################
restore [locate_data_file OCC26356-f.brep] b1
restore [locate_data_file OCC26356-w.brep] b2
explode b2 v
point p1 31350.009765625 7100 -2.17374844144233e-013
set bug_info_1 [projponf b1 p1 -min -g]
set bug_info_1 [string trim [string range $bug_info_1 [expr {[string first "=" $bug_info_1] + 1}] [expr {[string length $bug_info_1] - 1}]]]
set bug_info_1 [string trim [string range $bug_info_1 0 [expr {[string first " " $bug_info_1] - 1}]]]
set bug_info_2 [projponf b1 p1 -minmax -g]
set bug_info_2 [string trim [string range $bug_info_2 [expr {[string first "=" $bug_info_2] + 1}] [expr {[string length $bug_info_2] - 1}]]]
set bug_info_2 [string trim [string range $bug_info_2 0 [expr {[string first " " $bug_info_2] - 1}]]]
regexp {proj dist = ([0-9+-.eE]*)} [projponf b1 p1 -min] full dist1_min
regexp {proj dist = ([0-9+-.eE]*)} [projponf b1 p1 -minmax] full dist1_minmax
point p2 29200.099609375 7100 -2.17374753743702e-013
set bug_info_3 [projponf b1 p2 -min -g]
set bug_info_3 [string trim [string range $bug_info_3 [expr {[string first "=" $bug_info_3] + 1}] [expr {[string length $bug_info_3] - 1}]]]
set bug_info_3 [string trim [string range $bug_info_3 0 [expr {[string first " " $bug_info_3] - 1}]]]
set bug_info_4 [projponf b1 p2 -minmax -g]
set bug_info_4 [string trim [string range $bug_info_4 [expr {[string first "=" $bug_info_4] + 1}] [expr {[string length $bug_info_4] - 1}]]]
set bug_info_4 [string trim [string range $bug_info_4 0 [expr {[string first " " $bug_info_4] - 1}]]]
if {$bug_info_1 != $bug_info_2} {
puts "ERROR: OCC26356 is reproduced."
puts "For point #1: distance min is: ${bug_info_1}, distance minmax is: ${bug_info_2}."
regexp {proj dist = ([0-9+-.eE]*)} [projponf b1 p2 -min] full dist2_min
regexp {proj dist = ([0-9+-.eE]*)} [projponf b1 p2 -minmax] full dist2_minmax
if {[expr abs ($dist1_min - $dist1_minmax)] > 1.e-10} {
puts "ERROR: different extrema results in different modes"
puts "For point #1: distance min is: ${dist1_min}, distance minmax is: ${dist1_minmax}."
}
if {$bug_info_3 != $bug_info_4} {
puts "ERROR: OCC26356 is reproduced."
puts "For point #2: distance min is: ${bug_info_3}, distance minmax is: ${bug_info_4}."
if {[expr abs ($dist2_min - $dist2_minmax)] > 1.e-10} {
puts "ERROR: different extrema results in different modes"
puts "For point #2: distance min is: ${dist2_min}, distance minmax is: ${dist2_minmax}."
}

View File

@@ -18,7 +18,7 @@ point p_1 100 86.6025403784439 2.25000977226544
vertex v_1 100 86.6025403784439 2.25000977226544
set GOOD_DIST_1 2.0175535360778957e-14
set log_1 [projponf f p_1 -min -t]
set log_1 [projponf f p_1 -min]
regexp {proj dist = ([-0-9.+eE]+)} ${log_1} full distmax_1
if { [expr abs(${distmax_1} - ${GOOD_DIST_1})] > ${CMP_TOL} } {
puts "Error: Wrong distanse (# 1)"
@@ -39,7 +39,7 @@ point p_2 100 86.6025403784439 8.2500100656622
vertex v_2 100 86.6025403784439 8.2500100656622
set GOOD_DIST_2 9.9491842071163076e-14
set log_2 [projponf f p_2 -min -t]
set log_2 [projponf f p_2 -min]
regexp {proj dist = ([-0-9.+eE]+)} ${log_2} full distmax_2
if { [expr abs(${distmax_2} - ${GOOD_DIST_2})] > ${CMP_TOL} } {
puts "Error: Wrong distanse (# 2)"
@@ -60,7 +60,7 @@ point p_3 100 86.602540378443891 11.249990478996615
vertex v_3 100 86.602540378443891 11.249990478996615
set GOOD_DIST_3 2.8421709430404007e-14
set log_3 [projponf f p_3 -min -t]
set log_3 [projponf f p_3 -min]
regexp {proj dist = ([-0-9.+eE]+)} ${log_3} full distmax_3
if { [expr abs(${distmax_3} - ${GOOD_DIST_3})] > ${CMP_TOL} } {
puts "Error: Wrong distanse (# 3)"

View File

@@ -15,20 +15,10 @@ point p 934.419505115097 1387.10553740067 8.42056376938594e-014
set GOOD_DIST 1.0481408664017105e-12
set CMP_TOL 5.0e-12
# 1
set log_t [projponf f p -t]
regexp {proj dist = ([-0-9.+eE]+)} ${log_t} full distmax_t
if { [expr abs(${distmax_t} - ${GOOD_DIST})] > ${CMP_TOL} } {
puts "Error: Wrong intersection point (t-option)"
set log_t [projponf f p -min]
regexp {proj dist = ([-0-9.+eE]+)} ${log_t} full distmax
if { [expr abs(${distmax} - ${GOOD_DIST})] > ${CMP_TOL} } {
puts "Error: Wrong intersection point"
} else {
puts "OK: Good intersection point (t-option)"
}
# 2
set log_g [projponf f p -g]
regexp {proj dist = ([-0-9.+eE]+)} ${log_g} full distmax_g
if { [expr abs(${distmax_g} - ${GOOD_DIST})] > ${CMP_TOL} } {
puts "Error: Wrong intersection point (g-option)"
} else {
puts "OK: Good intersection point (g-option)"
puts "OK: Good intersection point"
}

View File

@@ -15,7 +15,7 @@ explode s f
copy s_1 f
point p 0.753071156928785 4.98580193823337 0
set proj_fp [projponf f p -t]
set proj_fp [projponf f p]
regexp {proj dist = ([-0-9.+eE]+)} ${proj_fp} full dist
regexp {uvproj = ([-0-9.+eE]+) ([-0-9.+eE]+)} ${proj_fp} full uproj vproj
regexp {pproj = ([-0-9.+eE]+) ([-0-9.+eE]+) ([-0-9.+eE]+)} ${proj_fp} full proj1 proj2

View File

@@ -11,8 +11,6 @@ set BugNumber OCC22826
restore [locate_data_file bug22610_f1.brep] a
mksurface s1 a
proj s1 1500 1500 500 g
renamevar ext_2 res
proj s1 1500 1500 500 t
proj s1 1500 1500 500
checklength res -l -equal ext_1
checklength ext_1 -l 6.8749734766305481

View File

@@ -12,6 +12,6 @@ point p 3.5527136788005e-015 100 100
dchrono h restart
projponf f p -min -t
projponf f p -min
dchrono h stop counter projponf