1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-06 10:36:12 +03:00
occt/src/IntStart/IntStart_SearchInside.gxx
abv 0797d9d30a 0025418: Debug output to be limited to OCC development environment
Macros ending on "DEB" are replaced by OCCT_DEBUG across OCCT code; new macros described in documentation.
Macros starting with DEB are changed to start with "OCCT_DEBUG_".
Some code cleaned.
2014-11-05 16:55:24 +03:00

268 lines
8.9 KiB
Plaintext

// Copyright (c) 1995-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 OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#endif
#include <math_FunctionSetRoot.hxx>
#include <Precision.hxx>
#include <gp_Pnt2d.hxx>
#include <TopAbs_State.hxx>
IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
{}
IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func,
const ThePSurface& PS,
const Handle(TheTopolTool)& T,
const Standard_Real Epsilon) {
Perform(Func,PS,T,Epsilon);
}
//=======================================================================
//function : Perform
//purpose : Search all inside points
//=======================================================================
void IntStart_SearchInside::Perform (TheFunction& Func,
const ThePSurface& PS,
const Handle(TheTopolTool)& T,
const Standard_Real Epsilon) {
done = Standard_False;
list.Clear();
Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2];
math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2);
gp_Pnt psol;
Standard_Boolean testpnt;
Standard_Integer i,j,nbpt;
TopAbs_State situ;
Standard_Real umin,umax,vmin,vmax;
Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS);
Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS);
Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS);
Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS);
Standard_Integer NbsampleU= T->NbSamplesU();
Standard_Integer NbsampleV= T->NbSamplesV();
Standard_Integer Nbsample = T->NbSamples();
Standard_Real du = Bsup(1)-Binf(1);
Standard_Real dv = Bsup(2)-Binf(2);
du/=(Standard_Real)NbsampleU*0.5;
dv/=(Standard_Real)NbsampleV*0.5;
Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
Standard_Real Maxtoler1toler2 = toler1;
if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2;
//-- lbr le 15 mai 97
//-- on interdit aux points d'etre trop prets des restrictions
Maxtoler1toler2*=1000;
if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001;
if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001;
Func.Set(PS);
Standard_Real Tol = Func.Tolerance();
math_FunctionSetRoot Rsnld(Func,toler);
Standard_Integer REJET_OK=0;
Standard_Integer REJET_KO=0;
//-- lbr le 15 mai 97
umin+=du*0.01;
vmin+=dv*0.01;
umax-=du*0.01;
vmax-=dv*0.01;
//-- lbr le 30 octobre 97 :
//-- Si une surface vient tangenter 2 edges proche d un coin
//-- il faut faire attention qu un point de depart soit trouve au
//-- voisinage du coin. Car ds le cas contraire, le cheminement ne
//-- pourra pas passer au travers des frontieres :
//--
//-- typiquement I est un cylindre (conge)
//--
//-- PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP
//-- P I I
//-- P I I
//-- P I
//-- P # il faut trouver un point ici
//-- P I
//-- P I
//-- PI
//-- * I
//-- PI I
//-- P I I I I I I I I
//--
for (i=1; i <= Nbsample+12; i++) {
gp_Pnt2d s2d;
gp_Pnt s3d;
Standard_Boolean nepastester=Standard_False;
if(i<=Nbsample) {
T->SamplePoint(i,s2d,s3d);
UVap(1)=s2d.X(); UVap(2)=s2d.Y();
Standard_Real u1,v1,u2,v2;
u1 = Binf(1) = Max(umin,UVap(1)-du);
v1 = Binf(2) = Max(vmin,UVap(2)-dv);
u2 = Bsup(1) = Min(umax,UVap(1)+du);
v2 = Bsup(2) = Min(vmax,UVap(2)+dv);
//-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2));
gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1);
gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2);
Standard_Real aValf[1];
math_Vector Valf(aValf,1,1);
Func.Value(UVap,Valf);
Standard_Real rvalf = Valf(1);
Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2);
if(rvalf*rvalf > 3.0*DistPP) {
REJET_OK++;
nepastester=Standard_True;
}
}
else {
if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
else if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
else if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
else if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
else if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
else if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
else if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
else if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
else if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); }
else if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005); }
else if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); }
else { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005); }
UVap(1)=s2d.X(); UVap(2)=s2d.Y();
Binf(1) = Max(umin,UVap(1)-du);
Binf(2) = Max(vmin,UVap(2)-dv);
Bsup(1) = Min(umax,UVap(1)+du);
Bsup(2) = Min(vmax,UVap(2)+dv);
}
if(nepastester==Standard_False) {
REJET_KO++;
Rsnld.Perform(Func,UVap,Binf,Bsup);
if (Rsnld.IsDone()) {
if (Abs(Func.Root()) <= Tol) {
if (!Func.IsTangent()) {
psol = Func.Point();
Rsnld.Root(UVap);
// On regarde si le point trouve est bien un nouveau point.
j = 1;
nbpt = list.Length();
testpnt = (j <= nbpt);
while (testpnt) {
const IntSurf_InteriorPoint& IPj = list(j);
const gp_Pnt& Pj = IPj.Value();
if ( (Abs(Pj.X()-psol.X()) <= Epsilon)
&& (Abs(Pj.Y()-psol.Y()) <= Epsilon)
&& (Abs(Pj.Z()-psol.Z()) <= Epsilon)
&& (Abs(UVap(1)-IPj.UParameter()) <= toler1)
&& (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) {
testpnt = Standard_False;
}
else {
j = j+1;
testpnt = (j <= nbpt);
}
}
if (j > nbpt) {
// situ = TheSITool::Classify(PS,UVap(1),UVap(2));
situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic
if (situ == TopAbs_IN) {
list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
Func.Direction3d(),
Func.Direction2d()));
}
}
}
}
}
}
}
//-- printf("\n Total : %d Rejet : %d RatioPointCalc : %g nbpt =%d\n",REJET_OK+REJET_KO,REJET_OK,(double)(REJET_KO)/(double)(REJET_OK+REJET_KO),list.Length());
done = Standard_True;
}
//=======================================================================
//function : Perform
//purpose : Test the given inside point
//=======================================================================
void IntStart_SearchInside::Perform (TheFunction& Func,
const ThePSurface& PS,
const Standard_Real UStart,
const Standard_Real VStart)
{
done = Standard_False;
list.Clear();
math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
Binf(2) = ThePSurfaceTool::FirstVParameter(PS);
Bsup(1) = ThePSurfaceTool::LastUParameter(PS);
Bsup(2) = ThePSurfaceTool::LastVParameter(PS);
toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) &&
VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) {
Func.Set(PS);
math_Vector UVap(1,2);
UVap(1)=UStart; UVap(2)=VStart;
math_FunctionSetRoot Rsnld(Func,toler);
Rsnld.Perform(Func,UVap,Binf,Bsup);
if (Rsnld.IsDone()) {
Standard_Real tol = Func.Tolerance();
Standard_Real valf = Func.Root();
if (Abs(valf) <= tol && !Func.IsTangent()) {
const gp_Pnt& psol = Func.Point();
Rsnld.Root(UVap);
IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2),
Func.Direction3d(),Func.Direction2d());
list.Append(intp);
}
}
}
done = Standard_True;
}