1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

OCC22610 The algorithm GeomAPI_ProjectPointOnSurf produces wrong results

This commit is contained in:
JGV 2011-07-26 17:25:28 +00:00 committed by bugmaster
parent ba9cc08b88
commit 38f33510d6
5 changed files with 189 additions and 63 deletions

View File

@ -419,71 +419,82 @@ void Extrema_GenExtPS::FindSolution(const gp_Pnt& P, const math_Vector& UV, cons
if (myF.HasDegIso())
aNbMaxIter = 150;
gp_Pnt PStart = myS->Value(UV(1), UV(2));
Standard_Real DistStart = P.SquareDistance(PStart);
Standard_Real DistSol = DistStart;
math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup, aNbMaxIter);
if(S.IsDone()) {
root = S.Root();
myF.Value(root, errors);
if(f == Extrema_ExtFlag_MIN)
Standard_Boolean ToResolveOnSubgrid = Standard_False;
if (f == Extrema_ExtFlag_MIN)
{
if(S.IsDone())
{
if(Abs(errors(1)) > eps || Abs(errors(2)) > eps) {
root = S.Root();
myF.Value(root, errors);
gp_Pnt PSol = myS->Value(root(1), root(2));
DistSol = P.SquareDistance(PSol);
if(Abs(errors(1)) > eps || Abs(errors(2)) > eps || DistStart < DistSol)
//try to improve solution on subgrid of sample points
gp_Pnt PSol = myS->Value(root(1), root(2));
Standard_Real DistSol = P.SquareDistance(PSol);
Standard_Real u1 = Max(UV(1) - PasU, myumin), u2 = Min(UV(1) + PasU, myusup);
Standard_Real v1 = Max(UV(2) - PasV, myvmin), v2 = Min(UV(2) + PasV, myvsup);
if(u2 - u1 < 2.*PasU) {
if(Abs(u1 - myumin) < 1.e-9) {
u2 = u1 + 2.*PasU;
u2 = Min(u2, myusup);
}
if(Abs(u2 - myusup) < 1.e-9) {
u1 = u2 - 2.*PasU;
u1 = Max(u1, myumin);
}
}
if(v2 - v1 < 2.*PasV) {
if(Abs(v1 - myvmin) < 1.e-9) {
v2 = v1 + 2.*PasV;
v2 = Min(v2, myvsup);
}
if(Abs(v2 - myvsup) < 1.e-9) {
v1 = v2 - 2.*PasV;
v1 = Max(v1, myvmin);
}
}
Standard_Real du = (u2 - u1)/(nbsubsample-1);
Standard_Real dv = (v2 - v1)/(nbsubsample-1);
Standard_Real u, v;
Standard_Real dist;
Standard_Boolean NewSolution = Standard_False;
Standard_Integer Nu, Nv;
for (Nu = 1, u = u1; Nu < nbsubsample; Nu++, u += du) {
for (Nv = 1, v = v1; Nv < nbsubsample; Nv++, v += dv) {
gp_Pnt Puv = myS->Value(u, v);
dist = P.SquareDistance(Puv);
if(dist < DistSol) {
UV(1) = u;
UV(2) = v;
NewSolution = Standard_True;
DistSol = dist;
}
}
}
if(NewSolution) {
//try to precise
math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup, aNbMaxIter);
}
}
ToResolveOnSubgrid = Standard_True;
}
}
else
ToResolveOnSubgrid = Standard_True;
if (ToResolveOnSubgrid)
{
Standard_Real u1 = Max(UV(1) - PasU, myumin), u2 = Min(UV(1) + PasU, myusup);
Standard_Real v1 = Max(UV(2) - PasV, myvmin), v2 = Min(UV(2) + PasV, myvsup);
if(u2 - u1 < 2.*PasU) {
if(Abs(u1 - myumin) < 1.e-9) {
u2 = u1 + 2.*PasU;
u2 = Min(u2, myusup);
}
if(Abs(u2 - myusup) < 1.e-9) {
u1 = u2 - 2.*PasU;
u1 = Max(u1, myumin);
}
}
if(v2 - v1 < 2.*PasV) {
if(Abs(v1 - myvmin) < 1.e-9) {
v2 = v1 + 2.*PasV;
v2 = Min(v2, myvsup);
}
if(Abs(v2 - myvsup) < 1.e-9) {
v1 = v2 - 2.*PasV;
v1 = Max(v1, myvmin);
}
}
Standard_Real du = (u2 - u1)/(nbsubsample-1);
Standard_Real dv = (v2 - v1)/(nbsubsample-1);
Standard_Real u, v;
Standard_Real dist;
Standard_Boolean NewSolution = Standard_False;
Standard_Integer Nu, Nv;
for (Nu = 1, u = u1; Nu < nbsubsample; Nu++, u += du) {
for (Nv = 1, v = v1; Nv < nbsubsample; Nv++, v += dv) {
gp_Pnt Puv = myS->Value(u, v);
dist = P.SquareDistance(Puv);
if(dist < DistSol) {
UV(1) = u;
UV(2) = v;
NewSolution = Standard_True;
DistSol = dist;
}
}
}
if(NewSolution) {
//try to precise
math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup, aNbMaxIter);
}
} //end of if (ToResolveOnSubgrid)
} //end of if (f == Extrema_ExtFlag_MIN)
myDone = Standard_True;
}

View File

@ -6,5 +6,4 @@ GeometryTest_API2dCommands.cxx
GeometryTest_APICommands.cxx
GeometryTest_ContinuityCommands.cxx
GeometryTest_PolyCommands.cxx
GeometryTest_TestProjCommands.cxx

View File

@ -55,4 +55,7 @@ is
---Purpose: defines command to test the polyhedral
-- triangulations and the polygons from the Poly package.
TestProjCommands(I : in out Interpretor from Draw);
---Purpose: defines commands to test projection of geometric objects
end GeometryTest;

View File

@ -24,6 +24,7 @@ void GeometryTest::AllCommands(Draw_Interpretor& theCommands)
// GeometryTest::API2dCommands(theCommands);
GeometryTest::APICommands(theCommands);
GeometryTest::ContinuityCommands(theCommands);
GeometryTest::TestProjCommands(theCommands);
// define the TCL variable Draw_GEOMETRY
//char* com = "set Draw_GEOMETRY 1";
//theCommands.Eval(com);

View File

@ -0,0 +1,112 @@
// File: GeometryTest_TestProjCommands.cxx
// Created: 30.06.11 17:21:02
// Author: jgv@ROLEX
// Copyright: Open CASCADE 2011
#include <GeometryTest.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <DBRep.hxx>
#include <DBRep_DrawableShape.hxx>
#include <Draw_Interpretor.hxx>
#include <Draw_Appli.hxx>
#include <DrawTrSurf.hxx>
#include <Draw_Marker3D.hxx>
#include <stdio.h>
#ifdef WNT
Standard_IMPORT Draw_Viewer dout;
#endif
//=======================================================================
//function : xdistcs
//purpose :
//=======================================================================
static Standard_Integer xdistcs(Draw_Interpretor& , Standard_Integer n, const char** a)
{
if (n<5) {
cout<<" Use xdistcs c s t1 t2 nbp"<<endl;
return 0;
}
//
Standard_Boolean bRet;
Standard_Integer i, aNbP, iSize;
Standard_Real aTol, aD, aT, aT1, aT2, dT;
gp_Pnt aP;
Handle(Geom_Curve) aC;
Handle(Geom_Surface) aS;
GeomAPI_ProjectPointOnSurf aPPS;
Handle(Draw_Marker3D) aMr;
Draw_Color aColor(Draw_rouge);
//
aTol=1.e-7;
//
aC=DrawTrSurf::GetCurve(a[1]);
if (aC.IsNull()) {
cout<<a[1]<<" is null curve"<<endl;
return 0;
}
//
aS=DrawTrSurf::GetSurface(a[2]);
if (aS.IsNull()) {
cout<<a[2]<<" is null"<<endl;
return 0;
}
//
aT1=atof(a[3]);
aT2=atof(a[4]);
//
aNbP=10;
if (n>5) {
aNbP=atoi(a[5]);
}
//
iSize=3;
//
dT=(aT2-aT1)/(aNbP-1);
for (i=0; i<aNbP; ++i) {
aT=aT1+i*dT;
if (i==aNbP-1) {
aT=aT2;
}
//
aC->D0(aT, aP);
aPPS.Init(aP, aS, aTol);
bRet=aPPS.IsDone();
if (!bRet) {
cout<<" GeomAPI_ProjectPointOnSurf failed"<<endl;
return 0;
}
//
aD=aPPS.LowerDistance();
printf(" T=%lg\tD=%lg\n", aT, aD);
//
aMr=new Draw_Marker3D(aP, Draw_Plus, aColor, iSize);
dout << aMr;
}
//
return 0;
}
//=======================================================================
//function : TestProjCommands
//purpose :
//=======================================================================
void GeometryTest::TestProjCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean loaded = Standard_False;
if (loaded) return;
loaded = Standard_True;
DrawTrSurf::BasicCommands(theCommands);
const char* g;
g = "Testing of projection (geometric objects)";
theCommands.Add("xdistcs", "xdistcs c s t1 t2 nbp", __FILE__, xdistcs, g);
}