Warning, /include/opencascade/IntStart_SearchInside.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 #ifndef OCCT_DEBUG
0016 #define No_Standard_RangeError
0017 #define No_Standard_OutOfRange
0018 #endif
0019
0020
0021
0022 #include <math_FunctionSetRoot.hxx>
0023 #include <Precision.hxx>
0024 #include <gp_Pnt2d.hxx>
0025
0026 #include <TopAbs_State.hxx>
0027
0028 IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
0029 {}
0030
0031 IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func,
0032 const ThePSurface& PS,
0033 const Handle(TheTopolTool)& T,
0034 const Standard_Real Epsilon) {
0035
0036 Perform(Func,PS,T,Epsilon);
0037 }
0038
0039
0040 //=======================================================================
0041 //function : Perform
0042 //purpose : Search all inside points
0043 //=======================================================================
0044
0045 void IntStart_SearchInside::Perform (TheFunction& Func,
0046 const ThePSurface& PS,
0047 const Handle(TheTopolTool)& T,
0048 const Standard_Real Epsilon) {
0049
0050 done = Standard_False;
0051 list.Clear();
0052 Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2];
0053 math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2);
0054 gp_Pnt psol;
0055 Standard_Boolean testpnt;
0056 Standard_Integer i,j,nbpt;
0057 TopAbs_State situ;
0058 Standard_Real umin,umax,vmin,vmax;
0059 Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS);
0060 Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS);
0061 Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS);
0062 Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS);
0063
0064 Standard_Integer NbsampleU= T->NbSamplesU();
0065 Standard_Integer NbsampleV= T->NbSamplesV();
0066 Standard_Integer Nbsample = T->NbSamples();
0067
0068 Standard_Real du = Bsup(1)-Binf(1);
0069 Standard_Real dv = Bsup(2)-Binf(2);
0070 du/=(Standard_Real)NbsampleU*0.5;
0071 dv/=(Standard_Real)NbsampleV*0.5;
0072
0073 Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
0074 Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
0075 Standard_Real Maxtoler1toler2 = toler1;
0076 if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2;
0077
0078 //-- lbr le 15 mai 97
0079 //-- on interdit aux points d'etre trop prets des restrictions
0080 Maxtoler1toler2*=1000;
0081 if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001;
0082 if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001;
0083
0084
0085 Func.Set(PS);
0086 Standard_Real Tol = Func.Tolerance();
0087
0088 math_FunctionSetRoot Rsnld(Func,toler);
0089
0090 //-- lbr le 15 mai 97
0091 umin+=du*0.01;
0092 vmin+=dv*0.01;
0093 umax-=du*0.01;
0094 vmax-=dv*0.01;
0095
0096 //-- lbr le 30 octobre 97 :
0097 //-- Si une surface vient tangenter 2 edges proche d un coin
0098 //-- il faut faire attention qu un point de depart soit trouve au
0099 //-- voisinage du coin. Car ds le cas contraire, le cheminement ne
0100 //-- pourra pas passer au travers des frontieres :
0101 //--
0102 //-- typiquement I est un cylindre (conge)
0103 //--
0104 //-- PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP
0105 //-- P I I
0106 //-- P I I
0107 //-- P I
0108 //-- P # il faut trouver un point ici
0109 //-- P I
0110 //-- P I
0111 //-- PI
0112 //-- * I
0113 //-- PI I
0114 //-- P I I I I I I I I
0115 //--
0116
0117
0118 for (i=1; i <= Nbsample+12; i++) {
0119 gp_Pnt2d s2d;
0120 gp_Pnt s3d;
0121 Standard_Boolean nepastester=Standard_False;
0122 if(i<=Nbsample) {
0123 T->SamplePoint(i,s2d,s3d);
0124 UVap(1)=s2d.X(); UVap(2)=s2d.Y();
0125
0126 Standard_Real u1,v1,u2,v2;
0127 u1 = Binf(1) = Max(umin,UVap(1)-du);
0128 v1 = Binf(2) = Max(vmin,UVap(2)-dv);
0129 u2 = Bsup(1) = Min(umax,UVap(1)+du);
0130 v2 = Bsup(2) = Min(vmax,UVap(2)+dv);
0131
0132
0133 //-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2));
0134 gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1);
0135 gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2);
0136 Standard_Real aValf[1];
0137 math_Vector Valf(aValf,1,1);
0138 Func.Value(UVap,Valf);
0139 Standard_Real rvalf = Valf(1);
0140 Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2);
0141 if(rvalf*rvalf > 3.0*DistPP) {
0142 nepastester=Standard_True;
0143 }
0144 }
0145 else {
0146 if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
0147 else if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
0148 else if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
0149 else if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
0150
0151 else if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); }
0152 else if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); }
0153 else if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); }
0154 else if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); }
0155
0156 else if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); }
0157 else if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005); }
0158 else if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); }
0159 else { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005); }
0160
0161 UVap(1)=s2d.X(); UVap(2)=s2d.Y();
0162
0163 Binf(1) = Max(umin,UVap(1)-du);
0164 Binf(2) = Max(vmin,UVap(2)-dv);
0165 Bsup(1) = Min(umax,UVap(1)+du);
0166 Bsup(2) = Min(vmax,UVap(2)+dv);
0167 }
0168
0169
0170 if(nepastester==Standard_False) {
0171 Rsnld.Perform(Func,UVap,Binf,Bsup);
0172 if (Rsnld.IsDone()) {
0173 if (Abs(Func.Root()) <= Tol) {
0174 if (!Func.IsTangent()) {
0175 psol = Func.Point();
0176 Rsnld.Root(UVap);
0177 // On regarde si le point trouve est bien un nouveau point.
0178 j = 1;
0179 nbpt = list.Length();
0180 testpnt = (j <= nbpt);
0181
0182 while (testpnt) {
0183 const IntSurf_InteriorPoint& IPj = list(j);
0184 const gp_Pnt& Pj = IPj.Value();
0185 if ( (Abs(Pj.X()-psol.X()) <= Epsilon)
0186 && (Abs(Pj.Y()-psol.Y()) <= Epsilon)
0187 && (Abs(Pj.Z()-psol.Z()) <= Epsilon)
0188 && (Abs(UVap(1)-IPj.UParameter()) <= toler1)
0189 && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) {
0190 testpnt = Standard_False;
0191 }
0192 else {
0193 j = j+1;
0194 testpnt = (j <= nbpt);
0195 }
0196 }
0197 if (j > nbpt) {
0198 // situ = TheSITool::Classify(PS,UVap(1),UVap(2));
0199 situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
0200 Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic
0201 if (situ == TopAbs_IN) {
0202 list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
0203 Func.Direction3d(),
0204 Func.Direction2d()));
0205 }
0206 }
0207 }
0208 }
0209 }
0210 }
0211 }
0212 //-- 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());
0213 done = Standard_True;
0214 }
0215
0216
0217 //=======================================================================
0218 //function : Perform
0219 //purpose : Test the given inside point
0220 //=======================================================================
0221
0222 void IntStart_SearchInside::Perform (TheFunction& Func,
0223 const ThePSurface& PS,
0224 const Standard_Real UStart,
0225 const Standard_Real VStart)
0226 {
0227 done = Standard_False;
0228 list.Clear();
0229 math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
0230
0231 Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
0232 Binf(2) = ThePSurfaceTool::FirstVParameter(PS);
0233 Bsup(1) = ThePSurfaceTool::LastUParameter(PS);
0234 Bsup(2) = ThePSurfaceTool::LastVParameter(PS);
0235
0236 toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion());
0237 toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion());
0238
0239 if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) &&
0240 VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) {
0241
0242 Func.Set(PS);
0243 math_Vector UVap(1,2);
0244 UVap(1)=UStart; UVap(2)=VStart;
0245
0246 math_FunctionSetRoot Rsnld(Func,toler);
0247 Rsnld.Perform(Func,UVap,Binf,Bsup);
0248 if (Rsnld.IsDone()) {
0249 Standard_Real tol = Func.Tolerance();
0250 Standard_Real valf = Func.Root();
0251 if (Abs(valf) <= tol && !Func.IsTangent()) {
0252 const gp_Pnt& psol = Func.Point();
0253 Rsnld.Root(UVap);
0254 IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2),
0255 Func.Direction3d(),Func.Direction2d());
0256 list.Append(intp);
0257 }
0258 }
0259 }
0260
0261 done = Standard_True;
0262 }