| 1 | |
| 2 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 |
| 3 | |
| 4 | #include <Precision.hxx> |
| 5 | #include <IntSurf_Quadric.hxx> |
| 6 | |
| 7 | static |
| 8 | void FindVertex (const TheArc&, |
| 9 | const Handle(TheTopolTool)&, |
| 10 | TheFunction&, |
| 11 | IntStart_SequenceOfPathPoint&, |
| 12 | const Standard_Real); |
| 13 | |
| 14 | |
| 15 | static |
| 16 | void BoundedArc (const TheArc&, |
| 17 | const Handle(TheTopolTool)&, |
| 18 | const Standard_Real, |
| 19 | const Standard_Real, |
| 20 | TheFunction&, |
| 21 | IntStart_SequenceOfPathPoint&, |
| 22 | IntStart_SequenceOfSegment&, |
| 23 | const Standard_Real, |
| 24 | const Standard_Real, |
| 25 | Standard_Boolean&); |
| 26 | |
| 27 | |
| 28 | static |
| 29 | void InfiniteArc (const TheArc&, |
| 30 | const Handle(TheTopolTool)&, |
| 31 | const Standard_Real, |
| 32 | const Standard_Real, |
| 33 | TheFunction&, |
| 34 | IntStart_SequenceOfPathPoint&, |
| 35 | IntStart_SequenceOfSegment&, |
| 36 | const Standard_Real, |
| 37 | const Standard_Real, |
| 38 | Standard_Boolean&); |
| 39 | |
| 40 | |
| 41 | static |
| 42 | void PointProcess (const gp_Pnt&, |
| 43 | const Standard_Real, |
| 44 | const TheArc&, |
| 45 | const Handle(TheTopolTool)&, |
| 46 | IntStart_SequenceOfPathPoint&, |
| 47 | const Standard_Real, |
| 48 | Standard_Integer&); |
| 49 | |
| 50 | |
| 51 | static |
| 52 | Standard_Integer TreatLC (const TheArc& A, |
| 53 | const Handle(TheTopolTool)& aDomain, |
| 54 | const IntSurf_Quadric& aQuadric, |
| 55 | const Standard_Real TolBoundary, |
| 56 | IntStart_SequenceOfPathPoint& pnt); |
| 57 | |
| 58 | |
| 59 | //======================================================================= |
| 60 | //function : FindVertex |
| 61 | //purpose : |
| 62 | //======================================================================= |
| 63 | void FindVertex (const TheArc& A, |
| 64 | const Handle(TheTopolTool)& Domain, |
| 65 | TheFunction& Func, |
| 66 | IntStart_SequenceOfPathPoint& pnt, |
| 67 | const Standard_Real Toler) |
| 68 | { |
| 69 | |
| 70 | // Recherche des vertex de l arc de restriction A solutions. On stocke les |
| 71 | // vertex solutions dans la liste pnt. |
| 72 | |
| 73 | |
| 74 | TheVertex vtx; |
| 75 | //gp_Pnt point; |
| 76 | Standard_Real param,valf; |
| 77 | Standard_Integer itemp; |
| 78 | |
| 79 | // Domain.InitVertexIterator(A); |
| 80 | Domain->Initialize(A); |
| 81 | Domain->InitVertexIterator(); |
| 82 | while (Domain->MoreVertex()) { |
| 83 | vtx = Domain->Vertex(); |
| 84 | param = TheSOBTool::Parameter(vtx,A); |
| 85 | |
| 86 | // Evaluer la fonction et regarder par rapport a la tolerance |
| 87 | // du vertex. Si la distance <= tolerance alors ajouter le vertex a |
| 88 | // la liste des points solutions |
| 89 | // L arc est suppose deja charge dans la fonction. |
| 90 | |
| 91 | Func.Value(param,valf); |
| 92 | if (Abs(valf) <= Toler) { |
| 93 | itemp = Func.GetStateNumber(); |
| 94 | pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, |
| 95 | vtx,A,param)); |
| 96 | // on rajoute la solution |
| 97 | } |
| 98 | Domain->NextVertex(); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | |
| 103 | //======================================================================= |
| 104 | //function : BoundedArc |
| 105 | //purpose : |
| 106 | //======================================================================= |
| 107 | void BoundedArc (const TheArc& A, |
| 108 | const Handle(TheTopolTool)& Domain, |
| 109 | const Standard_Real Pdeb, |
| 110 | const Standard_Real Pfin, |
| 111 | TheFunction& Func, |
| 112 | IntStart_SequenceOfPathPoint& pnt, |
| 113 | IntStart_SequenceOfSegment& seg, |
| 114 | const Standard_Real TolBoundary, |
| 115 | const Standard_Real TolTangency, |
| 116 | Standard_Boolean& Arcsol) |
| 117 | { |
| 118 | |
| 119 | // Recherche des points solutions et des bouts d arc solution sur un arc donne. |
| 120 | // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour |
| 121 | // des arcs ayant un point debut et un point de fin (intervalle ferme de |
| 122 | // parametrage). |
| 123 | |
| 124 | |
| 125 | Standard_Integer i,Nbi,Nbp; |
| 126 | |
| 127 | gp_Pnt ptdeb,ptfin; |
| 128 | Standard_Real pardeb,parfin; |
| 129 | Standard_Integer ideb,ifin,range,ranged,rangef; |
| 130 | |
| 131 | |
| 132 | // Creer l echantillonage (math_FunctionSample ou classe heritant) |
| 133 | // Appel a math_FunctionAllRoots |
| 134 | |
| 135 | Standard_Real EpsX = TheArcTool::Resolution(A,Precision::Confusion()); |
| 136 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 137 | //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement ) |
| 138 | //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 ) |
| 139 | //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une |
| 140 | //@@@ ligne de cheminement |
| 141 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 142 | EpsX = 0.0000000001; |
| 143 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 144 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 145 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 146 | |
| 147 | // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); |
| 148 | Standard_Integer NbEchant = Func.NbSamples(); |
| 149 | |
| 150 | //-- Modif 24 Aout 93 ----------------------------- |
| 151 | Standard_Real nTolTangency = TolTangency; |
| 152 | if((Pfin - Pdeb) < (TolTangency*10.0)) { |
| 153 | nTolTangency=(Pfin-Pdeb)*0.1; |
| 154 | } |
| 155 | if(EpsX>(nTolTangency+nTolTangency)) { |
| 156 | EpsX = nTolTangency * 0.1; |
| 157 | } |
| 158 | //-------------------------------------------------- |
| 159 | //-- Plante avec un edge avec 2 Samples |
| 160 | //-- dont les extremites son solutions (f=0) |
| 161 | //-- et ou la derivee est nulle |
| 162 | //-- Exemple : un segment diametre d une sphere |
| 163 | //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95 |
| 164 | //-------------------------------------------------- |
| 165 | Standard_Real para=0,dist,maxdist; |
| 166 | /* if(NbEchant<20) NbEchant = 20; //-- lbr le 22 Avril 96 |
| 167 | //-- Toujours des pbs |
| 168 | */ |
| 169 | if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 |
| 170 | //-- Toujours des pbs |
| 171 | |
| 172 | |
| 173 | //-------------------------------------------------------------- REJECTIONS le 15 oct 98 |
| 174 | Standard_Boolean Rejection=Standard_True; |
| 175 | Standard_Real maxdr,maxr,minr,ur,dur; |
| 176 | minr=RealLast(); |
| 177 | maxr=-minr; |
| 178 | maxdr=-minr; |
| 179 | dur=(Pfin-Pdeb)*0.2; |
| 180 | for(i=1,ur=Pdeb;i<=6;i++) { |
| 181 | Standard_Real F,D; |
| 182 | if(Func.Values(ur,F,D)) { |
| 183 | Standard_Real lminr,lmaxr; |
| 184 | if(D<0.0) D=-D; |
| 185 | D*=dur+dur; |
| 186 | if(D>maxdr) maxdr=D; |
| 187 | lminr=F-D; |
| 188 | lmaxr=F+D; |
| 189 | if(lminr<minr) minr=lminr; |
| 190 | if(lmaxr>maxr) maxr=lmaxr; |
| 191 | if(minr<0.0 && maxr>0.0) { |
| 192 | Rejection=Standard_False; |
| 193 | continue; |
| 194 | } |
| 195 | } |
| 196 | ur+=dur; |
| 197 | } |
| 198 | dur=0.001+maxdr+(maxr-minr)*0.1; |
| 199 | minr-=dur; |
| 200 | maxr+=dur; |
| 201 | if(minr<0.0 && maxr>0.0) { |
| 202 | Rejection=Standard_False; |
| 203 | } |
| 204 | |
| 205 | Arcsol=Standard_False; |
| 206 | |
| 207 | if(Rejection==Standard_False) { |
| 208 | math_FunctionSample Echant(Pdeb,Pfin,NbEchant); |
| 209 | |
| 210 | Standard_Boolean aelargir=Standard_True; |
| 211 | //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f |
| 212 | // |
| 213 | //maxdist = 100.0*TolBoundary; |
| 214 | maxdist = TolBoundary+TolTangency; |
| 215 | // |
| 216 | //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t |
| 217 | for(i=1; i<=NbEchant && aelargir;i++) { |
| 218 | Standard_Real u = Echant.GetParameter(i); |
| 219 | if(Func.Value(u,dist)) { |
| 220 | if(dist>maxdist || -dist>maxdist) { |
| 221 | aelargir=Standard_False; |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | if(aelargir && maxdist<0.01) { |
| 226 | #ifdef DEB |
| 227 | //-- cout<<"\n Tolerance elargie a "<<maxdist<<" dans IntStart_SearchOnBoundaries_1.gxx"<<endl; |
| 228 | #endif |
| 229 | } |
| 230 | else { |
| 231 | maxdist = TolBoundary; |
| 232 | } |
| 233 | |
| 234 | math_FunctionAllRoots Sol(Func,Echant,EpsX,maxdist,maxdist); //-- TolBoundary,nTolTangency); |
| 235 | |
| 236 | if (!Sol.IsDone()) {Standard_Failure::Raise();} |
| 237 | |
| 238 | Nbp=Sol.NbPoints(); |
| 239 | |
| 240 | //-- detection du cas ou la fonction est quasi tangente et que les |
| 241 | //-- zeros sont quasi confondus. |
| 242 | //-- Dans ce cas on prend le point "milieu" |
| 243 | //-- On suppose que les solutions sont triees. |
| 244 | |
| 245 | Standard_Real *TabSol=NULL; |
| 246 | if(Nbp) { |
| 247 | TabSol = new Standard_Real [Nbp+2]; |
| 248 | for(i=1;i<=Nbp;i++) { |
| 249 | TabSol[i]=Sol.GetPoint(i); |
| 250 | } |
| 251 | Standard_Boolean ok; |
| 252 | do { |
| 253 | ok=Standard_True; |
| 254 | for(i=1;i<Nbp;i++) { |
| 255 | if(TabSol[i]>TabSol[i+1]) { |
| 256 | ok=Standard_False; |
| 257 | para=TabSol[i]; TabSol[i]=TabSol[i+1]; TabSol[i+1]=para; |
| 258 | } |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | while(ok==Standard_False); |
| 263 | //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f |
| 264 | ////////////////////////////////////////////////////////// |
| 265 | // The treatment of the situation when line(arc) that is |
| 266 | // tangent to cylinder(domain). |
| 267 | // We should have only one solution i.e Nbp=1. Ok? |
| 268 | // But we have 2,3,.. solutions. That is wrong ersult. |
| 269 | // The TreatLC(...) function is dedicated to solve the pb. |
| 270 | // PKV Fri Mar 23 12:17:29 2001 |
| 271 | Standard_Integer ip; |
| 272 | const IntSurf_Quadric& aQuadric=Func.Quadric(); |
| 273 | |
| 274 | ip=TreatLC (A, Domain, aQuadric, TolBoundary, pnt); |
| 275 | if (ip) { |
| 276 | ////////////////////////////////////////////////////////// |
| 277 | //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t |
| 278 | // |
| 279 | // Using of old usual way proposed by Laurent |
| 280 | // |
| 281 | for(i=1;i<Nbp;i++) { |
| 282 | Standard_Real parap1=TabSol[i+1]; |
| 283 | para=TabSol[i]; |
| 284 | Standard_Real param=(para+parap1)*0.5; |
| 285 | Standard_Real ym; |
| 286 | if(Func.Value(param,ym)) { |
| 287 | if(Abs(ym)<maxdist) { |
| 288 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 Begin |
| 289 | // Consider this interval as tangent one. Treat it to find |
| 290 | // parameter with the lowest function value. |
| 291 | |
| 292 | // Compute the number of nodes. |
| 293 | Standard_Real aTol = TolBoundary*1000.0; |
| 294 | if(aTol > 0.001) |
| 295 | aTol = 0.001; |
| 296 | |
| 297 | // fix floating point exception 569, chl-922-e9 |
| 298 | parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9); |
| 299 | para = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9); |
| 300 | |
| 301 | Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol)); |
| 302 | |
| 303 | Standard_Real aVal = RealLast(); |
| 304 | //Standard_Integer aNbNodes = 23; |
| 305 | Standard_Real aDelta = (parap1 - para)/(aNbNodes + 1.); |
| 306 | Standard_Integer ii; |
| 307 | Standard_Real aCurPar; |
| 308 | Standard_Real aCurVal; |
| 309 | |
| 310 | for (ii = 0; ii <= aNbNodes + 1; ii++) { |
| 311 | aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1; |
| 312 | |
| 313 | if (Func.Value(aCurPar, aCurVal)) { |
| 314 | //if (aCurVal < aVal) { |
| 315 | if (Abs(aCurVal) < aVal) { |
| 316 | //aVal = aCurVal; |
| 317 | aVal = Abs(aCurVal); |
| 318 | param = aCurPar; |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 End |
| 323 | TabSol[i]=Pdeb-1; |
| 324 | TabSol[i+1]=param; |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | for (i=1; i<=Nbp; i++) { |
| 330 | para=TabSol[i]; |
| 331 | if((para-Pdeb)<EpsX || (Pfin-para)<EpsX) { |
| 332 | } |
| 333 | else { |
| 334 | if(Func.Value(para,dist)) { |
| 335 | //modified by jgv 5.07.01 for the bug buc60927 |
| 336 | Standard_Integer anIndx; |
| 337 | Standard_Real aParam; |
| 338 | if (Abs(dist) < maxdist) |
| 339 | { |
| 340 | aParam = Sol.GetPoint(i); |
| 341 | if (Abs(aParam-Pdeb)<=Precision::PConfusion() || Abs(aParam-Pfin)<=Precision::PConfusion()) |
| 342 | anIndx = Sol.GetPointState(i); |
| 343 | else |
| 344 | { |
| 345 | anIndx = Func.GetStateNumber(); //take the middle point |
| 346 | aParam = para; |
| 347 | } |
| 348 | } |
| 349 | else |
| 350 | { |
| 351 | anIndx = Sol.GetPointState(i); |
| 352 | aParam = Sol.GetPoint(i); |
| 353 | } |
| 354 | const gp_Pnt& aPnt = Func.Valpoint(anIndx); |
| 355 | ////////////////////////////////////////////// |
| 356 | |
| 357 | PointProcess(aPnt, aParam, A, Domain, pnt, TolBoundary, range); |
| 358 | } |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | if(TabSol) { |
| 363 | delete [] TabSol; |
| 364 | } |
| 365 | }// end ofif (ip) |
| 366 | } // end of if(Nbp) |
| 367 | |
| 368 | // Pour chaque intervalle trouve faire |
| 369 | // Traiter les extremites comme des points |
| 370 | // Ajouter intervalle dans la liste des segments |
| 371 | |
| 372 | Nbi=Sol.NbIntervals(); |
| 373 | |
| 374 | |
| 375 | if(Nbp) { |
| 376 | //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0 0 <- Nbi "<<Nbi<<endl; |
| 377 | Nbi=0; |
| 378 | } |
| 379 | |
| 380 | //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : Nbi : "<<Nbi<<endl; |
| 381 | |
| 382 | for (i=1; i<=Nbi; i++) { |
| 383 | IntStart_TheSegment newseg; |
| 384 | newseg.SetValue(A); |
| 385 | // Recuperer point debut et fin, et leur parametre. |
| 386 | Sol.GetInterval(i,pardeb,parfin); |
| 387 | Sol.GetIntervalState(i,ideb,ifin); |
| 388 | |
| 389 | |
| 390 | //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl; |
| 391 | |
| 392 | ptdeb=Func.Valpoint(ideb); |
| 393 | ptfin=Func.Valpoint(ifin); |
| 394 | |
| 395 | PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged); |
| 396 | newseg.SetLimitPoint(pnt.Value(ranged),Standard_True); |
| 397 | PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef); |
| 398 | newseg.SetLimitPoint(pnt.Value(rangef),Standard_False); |
| 399 | seg.Append(newseg); |
| 400 | } |
| 401 | |
| 402 | if (Nbi==1) { |
| 403 | if (pardeb == Pdeb && parfin == Pfin) { |
| 404 | Arcsol=Standard_True; |
| 405 | } |
| 406 | } |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | //======================================================================= |
| 411 | //function : ComputeBoundsfromInfinite |
| 412 | //purpose : |
| 413 | //======================================================================= |
| 414 | //-- PROVISOIRE - TEMPORAIRE - PAS BON - NYI - A FAIRE |
| 415 | //-- provisoire - temporaire - pas bon - nyi - a faire |
| 416 | void ComputeBoundsfromInfinite(TheFunction& Func, |
| 417 | Standard_Real& PDeb, |
| 418 | Standard_Real& PFin, |
| 419 | Standard_Integer& NbEchant) |
| 420 | { |
| 421 | |
| 422 | //-- On cherche des parametres de debut et de fin de l arc (courbe 2d) |
| 423 | //-- infini, de facon a intersecter la quadrique avec une portion d arc |
| 424 | //-- finie. |
| 425 | |
| 426 | //-- La quadrique est un plan, un cylindre, un cone ou une sphere. |
| 427 | |
| 428 | //-- Idee : On prend un point quelconque sur l'arc et on fait croitre les |
| 429 | //-- bornes vers des valeurs ou la fonction distance signee a des chances |
| 430 | //-- de s annuler. |
| 431 | |
| 432 | //-- ATTENTION : Les calculs ci-dessous fournissent une estimation tres |
| 433 | //-- grossiere des parametres . |
| 434 | //-- Cela evite les raises et permet a des cas de Boites |
| 435 | //-- inifinies de marcher. Il faudra reprendre ce code |
| 436 | //-- avec des intersections Courbe Surface. |
| 437 | |
| 438 | NbEchant = 10; |
| 439 | |
| 440 | Standard_Real U0 = 0.0; |
| 441 | //Standard_Real U1; |
| 442 | Standard_Real dU = 0.001; |
| 443 | Standard_Real Dist0,Dist1;//Grad0,Grad1; |
| 444 | //Standard_Real D1OnArc; |
| 445 | Func.Value(U0 , Dist0); |
| 446 | Func.Value(U0+dU, Dist1); |
| 447 | Standard_Real dDist = Dist1 - Dist0; |
| 448 | if(dDist) { |
| 449 | U0 -= dU*Dist0 / dDist; |
| 450 | PDeb = PFin = U0; |
| 451 | Standard_Real Umin = U0 - 1e5; |
| 452 | Func.Value(Umin , Dist0); |
| 453 | Func.Value(Umin+dU, Dist1); |
| 454 | dDist = Dist1-Dist0; |
| 455 | if(dDist) { |
| 456 | Umin -= dU*Dist0 / dDist; |
| 457 | } |
| 458 | else { |
| 459 | Umin-=10.0; |
| 460 | } |
| 461 | Standard_Real Umax = U0 + 1e8; |
| 462 | Func.Value(Umax , Dist0); |
| 463 | Func.Value(Umax+dU, Dist1); |
| 464 | dDist = Dist1-Dist0; |
| 465 | if(dDist) { |
| 466 | Umax -= dU*Dist0 / dDist; |
| 467 | } |
| 468 | else { |
| 469 | Umax+=10.0; |
| 470 | } |
| 471 | if(Umin>U0) { Umin=U0-10.0; } |
| 472 | if(Umax<U0) { Umax=U0+10.0; } |
| 473 | |
| 474 | PFin = Umax; |
| 475 | PDeb = Umin; |
| 476 | } |
| 477 | else { |
| 478 | //-- Possibilite de Arc totalement inclu ds Quad |
| 479 | PDeb = 1e10; |
| 480 | PFin = -1e10; |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | //======================================================================= |
| 485 | //function : InfiniteArc |
| 486 | //purpose : |
| 487 | //======================================================================= |
| 488 | void InfiniteArc (const TheArc& A, |
| 489 | const Handle(TheTopolTool)& Domain, |
| 490 | const Standard_Real Pdeb, |
| 491 | const Standard_Real Pfin, |
| 492 | TheFunction& Func, |
| 493 | IntStart_SequenceOfPathPoint& pnt, |
| 494 | IntStart_SequenceOfSegment& seg, |
| 495 | const Standard_Real TolBoundary, |
| 496 | const Standard_Real TolTangency, |
| 497 | Standard_Boolean& Arcsol) |
| 498 | { |
| 499 | |
| 500 | // Recherche des points solutions et des bouts d arc solution sur un arc donne. |
| 501 | // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour |
| 502 | // des arcs ayant un point debut et un point de fin (intervalle ferme de |
| 503 | // parametrage). |
| 504 | |
| 505 | |
| 506 | Standard_Integer i,Nbi,Nbp; |
| 507 | |
| 508 | gp_Pnt ptdeb,ptfin; |
| 509 | Standard_Real pardeb,parfin; |
| 510 | Standard_Integer ideb,ifin,range,ranged,rangef; |
| 511 | |
| 512 | |
| 513 | // Creer l echantillonage (math_FunctionSample ou classe heritant) |
| 514 | // Appel a math_FunctionAllRoots |
| 515 | |
| 516 | Standard_Real EpsX = TheArcTool::Resolution(A,Precision::Confusion()); |
| 517 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 518 | //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement ) |
| 519 | //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 ) |
| 520 | //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une |
| 521 | //@@@ ligne de cheminement |
| 522 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 523 | EpsX = 0.0000000001; |
| 524 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 525 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 526 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| 527 | |
| 528 | // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); |
| 529 | Standard_Integer NbEchant = Func.NbSamples(); |
| 530 | |
| 531 | //-- Modif 24 Aout 93 ----------------------------- |
| 532 | Standard_Real nTolTangency = TolTangency; |
| 533 | if((Pfin - Pdeb) < (TolTangency*10.0)) { |
| 534 | nTolTangency=(Pfin-Pdeb)*0.1; |
| 535 | } |
| 536 | if(EpsX>(nTolTangency+nTolTangency)) { |
| 537 | EpsX = nTolTangency * 0.1; |
| 538 | } |
| 539 | //-------------------------------------------------- |
| 540 | //-- Plante avec un edge avec 2 Samples |
| 541 | //-- dont les extremites sont solutions (f=0) |
| 542 | //-- et ou la derivee est nulle |
| 543 | //-- Exemple : un segment diametre d une sphere |
| 544 | if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95 |
| 545 | //-------------------------------------------------- |
| 546 | |
| 547 | Standard_Real PDeb = Pdeb; |
| 548 | Standard_Real PFin = Pfin; |
| 549 | |
| 550 | ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant); |
| 551 | |
| 552 | math_FunctionSample Echant(PDeb,PFin,NbEchant); |
| 553 | math_FunctionAllRoots Sol(Func,Echant,EpsX,TolBoundary,nTolTangency); |
| 554 | |
| 555 | if (!Sol.IsDone()) {Standard_Failure::Raise();} |
| 556 | |
| 557 | Nbp=Sol.NbPoints(); |
| 558 | for (i=1; i<=Nbp; i++) { |
| 559 | Standard_Real para = Sol.GetPoint(i); |
| 560 | Standard_Real dist; |
| 561 | if(Func.Value(para,dist)) { |
| 562 | //--if(Abs(dist)>nTolTangency) { |
| 563 | //--cout<<" Point sur restriction a dist="<<dist<<endl; |
| 564 | //--} |
| 565 | PointProcess(Func.Valpoint(Sol.GetPointState(i)),Sol.GetPoint(i), |
| 566 | A,Domain,pnt,TolBoundary,range); |
| 567 | } |
| 568 | //--else { |
| 569 | //-- cout<<" Point Rejete dans IntStart_SearchOnBoundaries_1.gxx "<<endl; |
| 570 | //--} |
| 571 | } |
| 572 | |
| 573 | // Pour chaque intervalle trouve faire |
| 574 | // Traiter les extremites comme des points |
| 575 | // Ajouter intervalle dans la liste des segments |
| 576 | |
| 577 | Nbi=Sol.NbIntervals(); |
| 578 | |
| 579 | for (i=1; i<=Nbi; i++) { |
| 580 | IntStart_TheSegment newseg; |
| 581 | newseg.SetValue(A); |
| 582 | // Recuperer point debut et fin, et leur parametre. |
| 583 | Sol.GetInterval(i,pardeb,parfin); |
| 584 | Sol.GetIntervalState(i,ideb,ifin); |
| 585 | ptdeb=Func.Valpoint(ideb); |
| 586 | ptfin=Func.Valpoint(ifin); |
| 587 | |
| 588 | PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged); |
| 589 | newseg.SetLimitPoint(pnt.Value(ranged),Standard_True); |
| 590 | PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef); |
| 591 | newseg.SetLimitPoint(pnt.Value(rangef),Standard_False); |
| 592 | seg.Append(newseg); |
| 593 | } |
| 594 | |
| 595 | |
| 596 | Arcsol=Standard_False; |
| 597 | if (Nbi==1) { |
| 598 | if (pardeb == Pdeb && parfin == Pfin) { |
| 599 | Arcsol=Standard_True; |
| 600 | } |
| 601 | } |
| 602 | } |
| 603 | //======================================================================= |
| 604 | //function : PointProcess |
| 605 | //purpose : |
| 606 | //======================================================================= |
| 607 | void PointProcess (const gp_Pnt& Pt, |
| 608 | const Standard_Real Para, |
| 609 | const TheArc& A, |
| 610 | const Handle(TheTopolTool)& Domain, |
| 611 | IntStart_SequenceOfPathPoint& pnt, |
| 612 | const Standard_Real Tol, |
| 613 | Standard_Integer& Range) |
| 614 | { |
| 615 | |
| 616 | // Regarder si un point solution est confondu avec un vertex. |
| 617 | // Si confondu, on doit retrouver ce vertex dans la liste des points de |
| 618 | // depart. On renvoie alors le rang de ce point dans la liste pnt. |
| 619 | // Sinon, on ajoute le point dans la liste. |
| 620 | |
| 621 | |
| 622 | Standard_Integer k; |
| 623 | Standard_Boolean found,goon; |
| 624 | Standard_Real dist,toler; |
| 625 | |
| 626 | Standard_Integer Nbsol = pnt.Length(); |
| 627 | TheVertex vtx; |
| 628 | IntStart_ThePathPoint ptsol; |
| 629 | |
| 630 | // Domain.InitVertexIterator(A); |
| 631 | Domain->Initialize(A); |
| 632 | Domain->InitVertexIterator(); |
| 633 | found = Standard_False; |
| 634 | goon = Domain->MoreVertex(); |
| 635 | while (goon) { |
| 636 | vtx = Domain->Vertex(); |
| 637 | dist= Abs(Para-TheSOBTool::Parameter(vtx,A)); |
| 638 | toler = TheSOBTool::Tolerance(vtx,A); |
| 639 | #ifdef DEB |
| 640 | if(toler>0.1) { |
| 641 | cout<<"IntStart_SearchOnBoundaries_1.gxx : ** WARNING ** Tol Vertex="<<toler<<endl; |
| 642 | cout<<" Ou Edge degenere Ou Kro pointu"<<endl; |
| 643 | if(toler>10000) toler=1e-7; |
| 644 | } |
| 645 | #endif |
| 646 | |
| 647 | if (dist <= toler) { |
| 648 | // Localiser le vertex dans la liste des solutions |
| 649 | k=1; |
| 650 | found = (k>Nbsol); |
| 651 | while (!found) { |
| 652 | ptsol = pnt.Value(k); |
| 653 | if (!ptsol.IsNew()) { |
| 654 | //jag 940608 if (ptsol.Vertex() == vtx && |
| 655 | //jag 940608 ptsol.Arc() == A) { |
| 656 | if (Domain->Identical(ptsol.Vertex(),vtx) && |
| 657 | ptsol.Arc() == A && |
| 658 | Abs(ptsol.Parameter()-Para) <= toler) { |
| 659 | found=Standard_True; |
| 660 | } |
| 661 | else { |
| 662 | k=k+1; |
| 663 | found=(k>Nbsol); |
| 664 | } |
| 665 | } |
| 666 | else { |
| 667 | k=k+1; |
| 668 | found=(k>Nbsol); |
| 669 | } |
| 670 | } |
| 671 | if (k<=Nbsol) { // on a retrouve le vertex |
| 672 | Range = k; |
| 673 | } |
| 674 | else { // au cas ou... |
| 675 | ptsol.SetValue(Pt,Tol,vtx,A,Para); |
| 676 | pnt.Append(ptsol); |
| 677 | Range = pnt.Length(); |
| 678 | } |
| 679 | found = Standard_True; |
| 680 | goon = Standard_False; |
| 681 | } |
| 682 | else { |
| 683 | Domain->NextVertex(); |
| 684 | goon = Domain->MoreVertex(); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | if (!found) { // on n est pas tombe sur un vertex |
| 689 | Standard_Real TOL=Tol; |
| 690 | TOL*=1000.0; |
| 691 | if(TOL>0.001) TOL=0.001; |
| 692 | |
| 693 | ptsol.SetValue(Pt,TOL,A,Para); |
| 694 | pnt.Append(ptsol); |
| 695 | Range = pnt.Length(); |
| 696 | } |
| 697 | } |
| 698 | |
| 699 | //modified by NIZNHY-PKV Fri Mar 23 10:53:15 2001 |
| 700 | #include <TopoDS_Edge.hxx> |
| 701 | #include <Geom_Curve.hxx> |
| 702 | #include <BRepAdaptor_Curve.hxx> |
| 703 | #include <Adaptor3d_HSurface.hxx> |
| 704 | #include <GeomAbs_SurfaceType.hxx> |
| 705 | #include <BRep_Tool.hxx> |
| 706 | #include <Geom_Line.hxx> |
| 707 | #include <gp_Lin.hxx> |
| 708 | #include <gp_Vec.hxx> |
| 709 | #include <gp_Dir.hxx> |
| 710 | #include <gp_Cylinder.hxx> |
| 711 | #include <gp_Ax1.hxx> |
| 712 | #include <gp_Lin.hxx> |
| 713 | |
| 714 | #include <GeomAdaptor_Curve.hxx> |
| 715 | #include <Precision.hxx> |
| 716 | #include <Extrema_ExtCC.hxx> |
| 717 | #include <Extrema_POnCurv.hxx> |
| 718 | |
| 719 | //======================================================================= |
| 720 | //function : TreatLC |
| 721 | //purpose : |
| 722 | //======================================================================= |
| 723 | Standard_Integer TreatLC (const TheArc& A, |
| 724 | const Handle(TheTopolTool)& aDomain, |
| 725 | const IntSurf_Quadric& aQuadric, |
| 726 | const Standard_Real TolBoundary, |
| 727 | IntStart_SequenceOfPathPoint& pnt) |
| 728 | { |
| 729 | Standard_Integer anExitCode=1, aNbExt; |
| 730 | |
| 731 | Standard_Address anEAddress=aDomain->Edge(); |
| 732 | if (anEAddress==NULL) { |
| 733 | return anExitCode; |
| 734 | } |
| 735 | |
| 736 | TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; |
| 737 | |
| 738 | if (BRep_Tool::Degenerated(*anE)) { |
| 739 | return anExitCode; |
| 740 | } |
| 741 | |
| 742 | GeomAbs_CurveType aTypeE; |
| 743 | BRepAdaptor_Curve aBAC(*anE); |
| 744 | aTypeE=aBAC.GetType(); |
| 745 | |
| 746 | if (aTypeE!=GeomAbs_Line) { |
| 747 | return anExitCode; |
| 748 | } |
| 749 | |
| 750 | GeomAbs_SurfaceType aTypeS; |
| 751 | aTypeS=aQuadric.TypeQuadric(); |
| 752 | |
| 753 | if (aTypeS!=GeomAbs_Cylinder) { |
| 754 | return anExitCode; |
| 755 | } |
| 756 | |
| 757 | Standard_Real f, l, U1f, U1l, U2f, U2l, U1, UEgde, TOL, aDist, aR, aRRel, Tol; |
| 758 | Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l); |
| 759 | |
| 760 | gp_Cylinder aCyl=aQuadric.Cylinder(); |
| 761 | const gp_Ax1& anAx1=aCyl.Axis(); |
| 762 | gp_Lin aLin(anAx1); |
| 763 | Handle(Geom_Line) aCAxis=new Geom_Line (aLin); |
| 764 | aR=aCyl.Radius(); |
| 765 | |
| 766 | U1f = aCAxis->FirstParameter(); |
| 767 | U1l = aCAxis->LastParameter(); |
| 768 | |
| 769 | U2f = aCEdge->FirstParameter(); |
| 770 | U2l = aCEdge->LastParameter(); |
| 771 | |
| 772 | |
| 773 | GeomAdaptor_Curve C1, C2; |
| 774 | |
| 775 | C1.Load(aCAxis); |
| 776 | C2.Load(aCEdge); |
| 777 | |
| 778 | Tol = Precision::PConfusion(); |
| 779 | |
| 780 | Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol); |
| 781 | |
| 782 | aNbExt=anExtCC.NbExt(); |
| 783 | if (aNbExt!=1) { |
| 784 | return anExitCode; |
| 785 | } |
| 786 | |
| 787 | gp_Pnt P1,PEdge; |
| 788 | Extrema_POnCurv PC1, PC2; |
| 789 | |
| 790 | anExtCC.Points(1, PC1, PC2); |
| 791 | |
| 792 | P1 =PC1.Value(); |
| 793 | PEdge=PC2.Value(); |
| 794 | |
| 795 | U1=PC1.Parameter(); |
| 796 | UEgde=PC2.Parameter(); |
| 797 | |
| 798 | aDist=PEdge.Distance(P1); |
| 799 | aRRel=fabs(aDist-aR)/aR; |
| 800 | if (aRRel > TolBoundary) { |
| 801 | return anExitCode; |
| 802 | } |
| 803 | |
| 804 | if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) { |
| 805 | return anExitCode; |
| 806 | } |
| 807 | // |
| 808 | // Do not wonder ! |
| 809 | // It was done as into PointProcess(...) function |
| 810 | //printf("TreatLC()=> tangent line is found\n"); |
| 811 | TOL=1000.*TolBoundary; |
| 812 | if(TOL>0.001) TOL=0.001; |
| 813 | |
| 814 | IntStart_ThePathPoint ptsol; |
| 815 | ptsol.SetValue(PEdge, TOL, A, UEgde); |
| 816 | pnt.Append(ptsol); |
| 817 | |
| 818 | anExitCode=0; |
| 819 | return anExitCode; |
| 820 | |
| 821 | } |