1// Copyright (c) 1995-1999 Matra Datavision 2// Copyright (c) 1999-2014 OPEN CASCADE SAS 3// 4// This file is part of Open CASCADE Technology software library. 5// 6// This library is free software; you can redistribute it and/or modify it under 7// the terms of the GNU Lesser General Public License version 2.1 as published 8// by the Free Software Foundation, with special exception defined in the file 9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 10// distribution for complete text of the license and disclaimer of any warranty. 11// 12// Alternatively, this file may be used under the terms of Open CASCADE 13// commercial license or contractual agreement. 14 15#ifndef OCCT_DEBUG 16#define No_Standard_RangeError 17#define No_Standard_OutOfRange 18#endif 19 20 21 22#include <math_FunctionSetRoot.hxx> 23#include <Precision.hxx> 24#include <gp_Pnt2d.hxx> 25 26#include <TopAbs_State.hxx> 27 28IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False) 29{} 30 31IntStart_SearchInside::IntStart_SearchInside (TheFunction& Func, 32 const ThePSurface& PS, 33 const Handle(TheTopolTool)& T, 34 const Standard_Real Epsilon) { 35 36 Perform(Func,PS,T,Epsilon); 37} 38 39 40//======================================================================= 41//function : Perform 42//purpose : Search all inside points 43//======================================================================= 44 45void IntStart_SearchInside::Perform (TheFunction& Func, 46 const ThePSurface& PS, 47 const Handle(TheTopolTool)& T, 48 const Standard_Real Epsilon) { 49 50 done = Standard_False; 51 list.Clear(); 52 Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2]; 53 math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2); 54 gp_Pnt psol; 55 Standard_Boolean testpnt; 56 Standard_Integer i,j,nbpt; 57 TopAbs_State situ; 58 Standard_Real umin,umax,vmin,vmax; 59 Binf(1) = umin = ThePSurfaceTool::FirstUParameter(PS); 60 Binf(2) = vmin = ThePSurfaceTool::FirstVParameter(PS); 61 Bsup(1) = umax = ThePSurfaceTool::LastUParameter(PS); 62 Bsup(2) = vmax = ThePSurfaceTool::LastVParameter(PS); 63 64 Standard_Integer NbsampleU= T->NbSamplesU(); 65 Standard_Integer NbsampleV= T->NbSamplesV(); 66 Standard_Integer Nbsample = T->NbSamples(); 67 68 Standard_Real du = Bsup(1)-Binf(1); 69 Standard_Real dv = Bsup(2)-Binf(2); 70 du/=(Standard_Real)NbsampleU*0.5; 71 dv/=(Standard_Real)NbsampleV*0.5; 72 73 Standard_Real toler1 = toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion()); 74 Standard_Real toler2 = toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion()); 75 Standard_Real Maxtoler1toler2 = toler1; 76 if(toler2>Maxtoler1toler2) Maxtoler1toler2 = toler2; 77 78 //-- lbr le 15 mai 97 79 //-- on interdit aux points d'etre trop prets des restrictions 80 Maxtoler1toler2*=1000; 81 if(Maxtoler1toler2>du*0.001) Maxtoler1toler2=du*0.001; 82 if(Maxtoler1toler2>dv*0.001) Maxtoler1toler2=dv*0.001; 83 84 85 Func.Set(PS); 86 Standard_Real Tol = Func.Tolerance(); 87 88 math_FunctionSetRoot Rsnld(Func,toler); 89 90 Standard_Integer REJET_OK=0; 91 Standard_Integer REJET_KO=0; 92 93 //-- lbr le 15 mai 97 94 umin+=du*0.01; 95 vmin+=dv*0.01; 96 umax-=du*0.01; 97 vmax-=dv*0.01; 98 99 //-- lbr le 30 octobre 97 : 100 //-- Si une surface vient tangenter 2 edges proche d un coin 101 //-- il faut faire attention qu un point de depart soit trouve au 102 //-- voisinage du coin. Car ds le cas contraire, le cheminement ne 103 //-- pourra pas passer au travers des frontieres : 104 //-- 105 //-- typiquement I est un cylindre (conge) 106 //-- 107 //-- PPPPPPPPPPPPPPPPPPPP*PPPPPPPPPPPPPPPP 108 //-- P I I 109 //-- P I I 110 //-- P I 111 //-- P # il faut trouver un point ici 112 //-- P I 113 //-- P I 114 //-- PI 115 //-- * I 116 //-- PI I 117 //-- P I I I I I I I I 118 //-- 119 120 121 for (i=1; i <= Nbsample+12; i++) { 122 gp_Pnt2d s2d; 123 gp_Pnt s3d; 124 Standard_Boolean nepastester=Standard_False; 125 if(i<=Nbsample) { 126 T->SamplePoint(i,s2d,s3d); 127 UVap(1)=s2d.X(); UVap(2)=s2d.Y(); 128 129 Standard_Real u1,v1,u2,v2; 130 u1 = Binf(1) = Max(umin,UVap(1)-du); 131 v1 = Binf(2) = Max(vmin,UVap(2)-dv); 132 u2 = Bsup(1) = Min(umax,UVap(1)+du); 133 v2 = Bsup(2) = Min(vmax,UVap(2)+dv); 134 135 136 //-- gp_Pnt Pmilieu = ThePSurfaceTool::Value(PS,0.5*(u1+u2),0.5*(v1+v2)); 137 gp_Pnt Pextrm1 = ThePSurfaceTool::Value(PS,u1,v1); 138 gp_Pnt Pextrm2 = ThePSurfaceTool::Value(PS,u2,v2); 139 Standard_Real aValf[1]; 140 math_Vector Valf(aValf,1,1); 141 Func.Value(UVap,Valf); 142 Standard_Real rvalf = Valf(1); 143 Standard_Real DistPP = Pextrm1.SquareDistance(Pextrm2); 144 if(rvalf*rvalf > 3.0*DistPP) { 145 REJET_OK++; 146 nepastester=Standard_True; 147 } 148 } 149 else { 150 if(i==Nbsample+1) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); } 151 else if(i==Nbsample+2) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); } 152 else if(i==Nbsample+3) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); } 153 else if(i==Nbsample+4) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); } 154 155 else if(i==Nbsample+5) { s2d.SetCoord(umin+du*0.02,vmin+dv*0.02); } 156 else if(i==Nbsample+6) { s2d.SetCoord(umax-du*0.02,vmin+dv*0.02); } 157 else if(i==Nbsample+7) { s2d.SetCoord(umin+du*0.02,vmax-dv*0.02); } 158 else if(i==Nbsample+8) { s2d.SetCoord(umax-du*0.02,vmax-dv*0.02); } 159 160 else if(i==Nbsample+9) { s2d.SetCoord(umin+du*0.005,vmin+dv*0.005); } 161 else if(i==Nbsample+10){ s2d.SetCoord(umax-du*0.005,vmin+dv*0.005); } 162 else if(i==Nbsample+11){ s2d.SetCoord(umin+du*0.005,vmax-dv*0.005); } 163 else { s2d.SetCoord(umax-du*0.005,vmax-dv*0.005); } 164 165 UVap(1)=s2d.X(); UVap(2)=s2d.Y(); 166 167 Binf(1) = Max(umin,UVap(1)-du); 168 Binf(2) = Max(vmin,UVap(2)-dv); 169 Bsup(1) = Min(umax,UVap(1)+du); 170 Bsup(2) = Min(vmax,UVap(2)+dv); 171 } 172 173 174 if(nepastester==Standard_False) { 175 REJET_KO++; 176 Rsnld.Perform(Func,UVap,Binf,Bsup); 177 if (Rsnld.IsDone()) { 178 if (Abs(Func.Root()) <= Tol) { 179 if (!Func.IsTangent()) { 180 psol = Func.Point(); 181 Rsnld.Root(UVap); 182 // On regarde si le point trouve est bien un nouveau point. 183 j = 1; 184 nbpt = list.Length(); 185 testpnt = (j <= nbpt); 186 187 while (testpnt) { 188 const IntSurf_InteriorPoint& IPj = list(j); 189 const gp_Pnt& Pj = IPj.Value(); 190 if ( (Abs(Pj.X()-psol.X()) <= Epsilon) 191 && (Abs(Pj.Y()-psol.Y()) <= Epsilon) 192 && (Abs(Pj.Z()-psol.Z()) <= Epsilon) 193 && (Abs(UVap(1)-IPj.UParameter()) <= toler1) 194 && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) { 195 testpnt = Standard_False; 196 } 197 else { 198 j = j+1; 199 testpnt = (j <= nbpt); 200 } 201 } 202 if (j > nbpt) { 203 // situ = TheSITool::Classify(PS,UVap(1),UVap(2)); 204 situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)), 205 Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic 206 if (situ == TopAbs_IN) { 207 list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2), 208 Func.Direction3d(), 209 Func.Direction2d())); 210 } 211 } 212 } 213 } 214 } 215 } 216 } 217 //-- 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()); 218 done = Standard_True; 219} 220 221 222//======================================================================= 223//function : Perform 224//purpose : Test the given inside point 225//======================================================================= 226 227void IntStart_SearchInside::Perform (TheFunction& Func, 228 const ThePSurface& PS, 229 const Standard_Real UStart, 230 const Standard_Real VStart) 231{ 232 done = Standard_False; 233 list.Clear(); 234 math_Vector Binf(1,2), Bsup(1,2), toler(1,2); 235 236 Binf(1) = ThePSurfaceTool::FirstUParameter(PS); 237 Binf(2) = ThePSurfaceTool::FirstVParameter(PS); 238 Bsup(1) = ThePSurfaceTool::LastUParameter(PS); 239 Bsup(2) = ThePSurfaceTool::LastVParameter(PS); 240 241 toler(1) = ThePSurfaceTool::UResolution(PS,Precision::Confusion()); 242 toler(2) = ThePSurfaceTool::VResolution(PS,Precision::Confusion()); 243 244 if (UStart-Binf(1) > -toler(1) && UStart-Bsup(1) < toler(1) && 245 VStart-Binf(2) > -toler(2) && VStart-Bsup(2) < toler(2)) { 246 247 Func.Set(PS); 248 math_Vector UVap(1,2); 249 UVap(1)=UStart; UVap(2)=VStart; 250 251 math_FunctionSetRoot Rsnld(Func,toler); 252 Rsnld.Perform(Func,UVap,Binf,Bsup); 253 if (Rsnld.IsDone()) { 254 Standard_Real tol = Func.Tolerance(); 255 Standard_Real valf = Func.Root(); 256 if (Abs(valf) <= tol && !Func.IsTangent()) { 257 const gp_Pnt& psol = Func.Point(); 258 Rsnld.Root(UVap); 259 IntSurf_InteriorPoint intp (psol,UVap(1),UVap(2), 260 Func.Direction3d(),Func.Direction2d()); 261 list.Append(intp); 262 } 263 } 264 } 265 266 done = Standard_True; 267} 268