1// Created on: 1993-04-09 2// Created by: Laurent BUCHARD 3// Copyright (c) 1993-1999 Matra Datavision 4// Copyright (c) 1999-2014 OPEN CASCADE SAS 5// 6// This file is part of Open CASCADE Technology software library. 7// 8// This library is free software; you can redistribute it and/or modify it under 9// the terms of the GNU Lesser General Public License version 2.1 as published 10// by the Free Software Foundation, with special exception defined in the file 11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 12// distribution for complete text of the license and disclaimer of any warranty. 13// 14// Alternatively, this file may be used under the terms of Open CASCADE 15// commercial license or contractual agreement. 16 17//#ifndef OCCT_DEBUG 18//#define No_Standard_RangeError 19//#define No_Standard_OutOfRange 20//#endif 21 22 23#define TOLTANGENCY 0.00000001 24#define TOLERANCE_ANGULAIRE 1.e-12//0.00000001 25#define TOLERANCE 0.00000001 26 27#define NBSAMPLESONCIRCLE 32 28#define NBSAMPLESONELLIPSE 32 29#define NBSAMPLESONPARAB 16 30#define NBSAMPLESONHYPR 32 31 32#include <ElSLib.hxx> 33#include <Intf_SectionPoint.hxx> 34#include <Intf_TangentZone.hxx> 35#include <Intf_Tool.hxx> 36#include <math_FunctionSetRoot.hxx> 37#include <IntCurveSurface_IntersectionPoint.hxx> 38#include <IntCurveSurface_IntersectionSegment.hxx> 39#include <IntAna_IntConicQuad.hxx> 40#include <IntAna_Quadric.hxx> 41#include <gp_Vec.hxx> 42#include <gp_Dir.hxx> 43#include <Precision.hxx> 44#include <IntAna_IntLinTorus.hxx> 45 46#include <GeomAbs_Shape.hxx> 47#include <GeomAbs_CurveType.hxx> 48#include <TColStd_Array1OfReal.hxx> 49#include <TColgp_Array1OfPnt.hxx> 50#include <gp_Pnt.hxx> 51#include <gp_Pln.hxx> 52#include <gp_Lin.hxx> 53#include <GProp_PEquation.hxx> 54#include <GProp_PGProps.hxx> 55#include <GProp_PrincipalProps.hxx> 56#include <Extrema_ExtElC.hxx> 57#include <Extrema_POnCurv.hxx> 58 59 60 61#include <ProjLib_Plane.hxx> 62#include <IntAna2d_AnaIntersection.hxx> 63#include <gp_Lin2d.hxx> 64#include <IntAna2d_IntPoint.hxx> 65#include <gp_Parab2d.hxx> 66#include <IntAna2d_Conic.hxx> 67#include <IntAna2d_AnaIntersection.hxx> 68#include <gp_Hypr2d.hxx> 69#include <Adaptor3d_Curve.hxx> 70#include <Adaptor3d_Surface.hxx> 71 72 73#include <TColgp_Array2OfPnt.hxx> 74#include <TColStd_HArray1OfReal.hxx> 75#include <Adaptor3d_TopolTool.hxx> 76#include <ElCLib.hxx> 77//#define ICS_DEB 78static 79 void EstLimForInfExtr(const gp_Lin& Line, 80 const TheSurface& surface, 81 const Standard_Boolean IsOffSurf, 82 const Standard_Integer nbsu, 83 const Standard_Boolean U1inf, 84 const Standard_Boolean U2inf, 85 const Standard_Boolean V1inf, 86 const Standard_Boolean V2inf, 87 Standard_Real& U1new, 88 Standard_Real& U2new, 89 Standard_Real& V1new, 90 Standard_Real& V2new, 91 Standard_Boolean& NoIntersection); 92 93static 94 void EstLimForInfRevl(const gp_Lin& Line, 95 const TheSurface& surface, 96 const Standard_Boolean U1inf, 97 const Standard_Boolean U2inf, 98 const Standard_Boolean V1inf, 99 const Standard_Boolean V2inf, 100 Standard_Real& U1new, 101 Standard_Real& U2new, 102 Standard_Real& V1new, 103 Standard_Real& V2new, 104 Standard_Boolean& NoIntersection); 105 106static 107 void EstLimForInfOffs(const gp_Lin& Line, 108 const TheSurface& surface, 109 const Standard_Integer nbsu, 110 const Standard_Boolean U1inf, 111 const Standard_Boolean U2inf, 112 const Standard_Boolean V1inf, 113 const Standard_Boolean V2inf, 114 Standard_Real& U1new, 115 Standard_Real& U2new, 116 Standard_Real& V1new, 117 Standard_Real& V2new, 118 Standard_Boolean& NoIntersection); 119 120static 121 void EstLimForInfSurf(Standard_Real& U1new, 122 Standard_Real& U2new, 123 Standard_Real& V1new, 124 Standard_Real& V2new); 125 126static 127 void SectionPointToParameters(const Intf_SectionPoint& Sp, 128 const IntCurveSurface_ThePolyhedron& Surf, 129 const IntCurveSurface_ThePolygon& Curv, 130 Standard_Real& u, 131 Standard_Real& v, 132 Standard_Real& w); 133 134static 135 void IntCurveSurface_ComputeTransitions(const TheCurve& curve, 136 const Standard_Real w, 137 IntCurveSurface_TransitionOnCurve& TransOnCurve, 138 const TheSurface& surface, 139 const Standard_Real u, 140 const Standard_Real v); 141 142static 143 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface, 144 const gp_Pnt& P, 145 Standard_Real& u, 146 Standard_Real& v); 147 148static 149 void ProjectIntersectAndEstLim(const gp_Lin& theLine, 150 const gp_Pln& thePln, 151 const ProjLib_Plane& theBasCurvProj, 152 Standard_Real& theVmin, 153 Standard_Real& theVmax, 154 Standard_Boolean& theNoIntersection); 155 156//======================================================================= 157//function : IntCurveSurface_Inter 158//purpose : 159//======================================================================= 160IntCurveSurface_Inter::IntCurveSurface_Inter() 161{ 162} 163//======================================================================= 164//function : DoSurface 165//purpose : 166//======================================================================= 167void IntCurveSurface_Inter::DoSurface(const TheSurface& surface, 168 const Standard_Real u0, 169 const Standard_Real u1, 170 const Standard_Real v0, 171 const Standard_Real v1, 172 TColgp_Array2OfPnt& pntsOnSurface, 173 Bnd_Box& boxSurface, 174 Standard_Real& gap) 175{ 176 Standard_Integer iU = 0, iV = 0; 177 Standard_Real U = 0., V = 0; 178// modified by NIZHNY-MKK Mon Oct 3 17:38:45 2005 179// Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.; 180 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.; 181 gp_Pnt aPnt; 182 183 for(iU = 0; iU < 50; iU++) { 184 185 if(iU == 0) 186 U = u0; 187 else if(iU == 49) 188 U = u1; 189 else 190 U = u0 + dU * ((Standard_Real)iU); 191 192 for(iV = 0; iV < 50; iV++) { 193 194 if(iV == 0) 195 V = v0; 196 else if(iV == 49) 197 V = v1; 198 else 199 V = v0 + dV * ((Standard_Real)iV); 200 201 TheSurfaceTool::D0(surface,U,V,aPnt); 202 boxSurface.Add(aPnt); 203 pntsOnSurface.SetValue(iU+1,iV+1,aPnt); 204 } 205 } 206 Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU); 207 Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV); 208 gap = Max(Ures,Vres); 209} 210 211//======================================================================= 212//function : DoNewBounds 213//purpose : 214//======================================================================= 215void IntCurveSurface_Inter::DoNewBounds( 216 const TheSurface& surface, 217 const Standard_Real u0, 218 const Standard_Real u1, 219 const Standard_Real v0, 220 const Standard_Real v1, 221 const TColgp_Array2OfPnt& pntsOnSurface, 222 const TColStd_Array1OfReal& X, 223 const TColStd_Array1OfReal& Y, 224 const TColStd_Array1OfReal& Z, 225 TColStd_Array1OfReal& Bounds) 226{ 227 Bounds.SetValue(1,u0); 228 Bounds.SetValue(2,u1); 229 Bounds.SetValue(3,v0); 230 Bounds.SetValue(4,v1); 231 232 Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface)); 233 Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface)); 234 Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True; 235 Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True; 236 237 Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0; 238 Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1; 239 240 for(i = 1; i <= 2; i++) { 241 for(j = 1; j <= 2; j++) { 242 for(k = 1; k <= 2; k++) { 243 gp_Pnt aPoint(X(i),Y(j),Z(k)); 244 Standard_Real DistMin = 1.e+100; 245 Standard_Integer diU = 0, diV = 0; 246 for(iU = 1; iU <= 50; iU++) { 247 for(iV = 1; iV <= 50; iV++) { 248 const gp_Pnt aP = pntsOnSurface.Value(iU,iV); 249 Standard_Real dist = aP.SquareDistance(aPoint); 250 if(dist < DistMin) { 251 DistMin = dist; 252 diU = iU; 253 diV = iV; 254 } 255 } 256 } 257 if(diU > 0 && diU < iUmin) iUmin = diU; 258 if(diU > 0 && diU > iUmax) iUmax = diU; 259 if(diV > 0 && diV < iVmin) iVmin = diV; 260 if(diV > 0 && diV > iVmax) iVmax = diV; 261 } 262 } 263 } 264 265// modified by NIZHNY-MKK Mon Oct 3 17:38:43 2005 266// Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.; 267 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.; 268 269 Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1)); 270 Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1)); 271 Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1)); 272 Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1)); 273 274 if(USmin > USmax) { 275 Standard_Real tmp = USmax; 276 USmax = USmin; 277 USmin = tmp; 278 } 279 if(VSmin > VSmax) { 280 Standard_Real tmp = VSmax; 281 VSmax = VSmin; 282 VSmin = tmp; 283 } 284 285 USmin -= 1.5*dU; 286 if(USmin < u0) USmin = u0; 287 USmax += 1.5*dU; 288 if(USmax > u1) USmax = u1; 289 VSmin -= 1.5*dV; 290 if(VSmin < v0) VSmin = v0; 291 VSmax += 1.5*dV; 292 if(VSmax > v1) VSmax = v1; 293 294 if(checkU) { 295 Bounds.SetValue(1,USmin); 296 Bounds.SetValue(2,USmax); 297 } 298 if(checkV) { 299 Bounds.SetValue(3,VSmin); 300 Bounds.SetValue(4,VSmax); 301 } 302} 303 304//======================================================================= 305//function : Perform 306//purpose : Decompose la surface si besoin est 307//======================================================================= 308void IntCurveSurface_Inter::Perform(const TheCurve& curve, 309 const TheSurface& surface) 310{ 311 ResetFields(); 312 done = Standard_True; 313 Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2); 314 Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2); 315 Standard_Real U0,U1,V0,V1; 316 317 if(NbUOnS > 1) 318 { 319 TColStd_Array1OfReal TabU(1,NbUOnS+1); 320 TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2); 321 for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) 322 { 323 U0 = TabU.Value(iu); 324 U1 = TabU.Value(iu+1); 325 if(NbVOnS > 1) 326 { 327 TColStd_Array1OfReal TabV(1,NbVOnS+1); 328 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2); 329 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) 330 { 331 // More than one interval on U and V param space. 332 V0 = TabV.Value(iv); 333 V1 = TabV.Value(iv+1); 334 Perform(curve,surface,U0,V0,U1,V1); 335 } 336 } 337 else 338 { 339 // More than one interval only on U param space. 340 V0 = TheSurfaceTool::FirstVParameter(surface); 341 V1 = TheSurfaceTool::LastVParameter(surface); 342 Perform(curve,surface,U0,V0,U1,V1); 343 } 344 } 345 } 346 else if(NbVOnS > 1) 347 { 348 // More than one interval only on V param space. 349 U0 = TheSurfaceTool::FirstUParameter(surface); 350 U1 = TheSurfaceTool::LastUParameter(surface); 351 TColStd_Array1OfReal TabV(1,NbVOnS+1); 352 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2); 353 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) 354 { 355 V0 = TabV.Value(iv); 356 V1 = TabV.Value(iv+1); 357 Perform(curve,surface,U0,V0,U1,V1); 358 } 359 } 360 else 361 { 362 // One interval on U and V param space. 363 V0 = TheSurfaceTool::FirstVParameter(surface); 364 V1 = TheSurfaceTool::LastVParameter(surface); 365 U0 = TheSurfaceTool::FirstUParameter(surface); 366 U1 = TheSurfaceTool::LastUParameter(surface); 367 368 Perform(curve,surface,U0,V0,U1,V1); 369 } 370} 371//======================================================================= 372//function : Perform 373//purpose : 374//======================================================================= 375void IntCurveSurface_Inter::Perform(const TheCurve& curve, 376 const TheSurface& surface, 377 const Standard_Real U1,const Standard_Real V1, 378 const Standard_Real U2,const Standard_Real V2) 379{ 380 // Protection from double type overflow. 381 // This may happen inside square magnitude computation based on normal, 382 // which was computed on bound parameteres (bug26525). 383 Standard_Real UU1 = U1, UU2 = U2, VV1 = V1, VV2 = V2; 384 if (U1 < -1.0e50) 385 UU1 = -1.0e50; 386 if (U2 > 1.0e50) 387 UU2 = 1.0e50; 388 if (V1 < -1.0e50) 389 VV1 = -1.0e50; 390 if (V2 > 1.0e50) 391 VV2 = 1.0e50; 392 393 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve); 394 395 switch(CurveType) { 396 case GeomAbs_Line: 397 { 398 PerformConicSurf(TheCurveTool::Line(curve),curve,surface,UU1,VV1,UU2,VV2); 399 break; 400 } 401 case GeomAbs_Circle: 402 { 403 PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,UU1,VV1,UU2,VV2); 404 break; 405 } 406 case GeomAbs_Ellipse: 407 { 408 PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,UU1,VV1,UU2,VV2); 409 break; 410 } 411 case GeomAbs_Parabola: 412 { 413 PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,UU1,VV1,UU2,VV2); 414 break; 415 } 416 case GeomAbs_Hyperbola: 417 { 418 PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,UU1,VV1,UU2,VV2); 419 break; 420 } 421 default: 422 { 423 Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2); 424 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 425 if( (SurfaceType != GeomAbs_Plane) 426 && (SurfaceType != GeomAbs_Cylinder) 427 && (SurfaceType != GeomAbs_Cone) 428 && (SurfaceType != GeomAbs_Sphere)) { 429 430 if(nbIntervalsOnCurve > 1) { 431 TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1); 432 TheCurveTool::Intervals(curve,TabW,GeomAbs_C2); 433 for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) { 434 Standard_Real u1,u2; 435 u1 = TabW.Value(i); 436 u2 = TabW.Value(i+1); 437 438 Handle(TColStd_HArray1OfReal) aPars; 439 Standard_Real defl = 0.1; 440 Standard_Integer NbMin = 10; 441 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars); 442 443// IntCurveSurface_ThePolygon polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2)); 444 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1()); 445 InternalPerform(curve,polygon,surface,UU1,VV1,UU2,VV2); 446 } 447 } 448 else { 449 Standard_Real u1,u2; 450 u1 = TheCurveTool::FirstParameter(curve); 451 u2 = TheCurveTool::LastParameter(curve); 452 453 Handle(TColStd_HArray1OfReal) aPars; 454 Standard_Real defl = 0.1; 455 Standard_Integer NbMin = 10; 456 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars); 457 458// IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2)); 459 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1()); 460 InternalPerform(curve,polygon,surface,UU1,VV1,UU2,VV2); 461 } 462 } 463 else { //-- la surface est une quadrique 464 InternalPerformCurveQuadric(curve,surface); 465 } 466 } 467 } 468} 469//======================================================================= 470//function : Perform 471//purpose : 472//======================================================================= 473void IntCurveSurface_Inter::Perform(const TheCurve& curve, 474 const IntCurveSurface_ThePolygon& polygon, 475 const TheSurface& surface) { 476 ResetFields(); 477 done = Standard_True; 478 Standard_Real u1,v1,u2,v2; 479 u1 = TheSurfaceTool::FirstUParameter(surface); 480 v1 = TheSurfaceTool::FirstVParameter(surface); 481 u2 = TheSurfaceTool::LastUParameter(surface); 482 v2 = TheSurfaceTool::LastVParameter(surface); 483 Standard_Integer nbsu,nbsv; 484 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2); 485 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2); 486 if(nbsu>40) nbsu=40; 487 if(nbsv>40) nbsv=40; 488 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2); 489 Perform(curve,polygon,surface,polyhedron); 490} 491//======================================================================= 492//function : Perform 493//purpose : 494//======================================================================= 495void IntCurveSurface_Inter::Perform(const TheCurve& curve, 496 const TheSurface& surface, 497 const IntCurveSurface_ThePolyhedron& polyhedron) { 498 ResetFields(); 499 done = Standard_True; 500 Standard_Real u1 = TheCurveTool::FirstParameter(curve); 501 Standard_Real u2 = TheCurveTool::LastParameter(curve); 502 IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2)); 503 Perform(curve,polygon,surface,polyhedron); 504} 505//======================================================================= 506//function : Perform 507//purpose : 508//======================================================================= 509void IntCurveSurface_Inter::Perform(const TheCurve& curve, 510 const IntCurveSurface_ThePolygon& polygon, 511 const TheSurface& surface, 512 const IntCurveSurface_ThePolyhedron& polyhedron) { 513 ResetFields(); 514 done = Standard_True; 515 Standard_Real u1,v1,u2,v2; 516 u1 = TheSurfaceTool::FirstUParameter(surface); 517 v1 = TheSurfaceTool::FirstVParameter(surface); 518 u2 = TheSurfaceTool::LastUParameter(surface); 519 v2 = TheSurfaceTool::LastVParameter(surface); 520 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2); 521} 522 523//======================================================================= 524//function : Perform 525//purpose : 526//======================================================================= 527void IntCurveSurface_Inter::Perform(const TheCurve& curve, 528 const IntCurveSurface_ThePolygon& polygon, 529 const TheSurface& surface, 530 const IntCurveSurface_ThePolyhedron& polyhedron, 531 Bnd_BoundSortBox& BndBSB) { 532 ResetFields(); 533 done = Standard_True; 534 Standard_Real u1,v1,u2,v2; 535 u1 = TheSurfaceTool::FirstUParameter(surface); 536 v1 = TheSurfaceTool::FirstVParameter(surface); 537 u2 = TheSurfaceTool::LastUParameter(surface); 538 v2 = TheSurfaceTool::LastVParameter(surface); 539 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB); 540} 541//======================================================================= 542//function : InternalPerform 543//purpose : C a l c u l d u p o i n t a p p r o c h e 544//== p u i s d u p o i n t E x a c t 545//======================================================================= 546void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve, 547 const IntCurveSurface_ThePolygon& polygon, 548 const TheSurface& surface, 549 const IntCurveSurface_ThePolyhedron& polyhedron, 550 const Standard_Real u0, 551 const Standard_Real v0, 552 const Standard_Real u1, 553 const Standard_Real v1, 554 Bnd_BoundSortBox& BSB) { 555 IntCurveSurface_TheInterference interference(polygon,polyhedron,BSB); 556 IntCurveSurface_TheCSFunction theicsfunction(surface,curve); 557 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY); 558 math_FunctionSetRoot rsnld(intersectionExacte.Function()); 559 560// Standard_Real u,v,w,winit; 561 Standard_Real u,v,w; 562 gp_Pnt P; 563 Standard_Real winf = polygon.InfParameter(); 564 Standard_Real wsup = polygon.SupParameter(); 565 Standard_Integer NbSectionPoints = interference.NbSectionPoints(); 566 Standard_Integer NbTangentZones = interference.NbTangentZones(); 567 568 569 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 570 571 Standard_Integer i,NbStartPoints=NbSectionPoints; 572 for(i=1; i<= NbTangentZones; i++) { 573 const Intf_TangentZone& TZ = interference.ZoneValue(i); 574 Standard_Integer nbpnts = TZ.NumberOfPoints(); 575 NbStartPoints+=nbpnts; 576 } 577 578 if(NbStartPoints) { 579 Standard_Real *TabU = new Standard_Real [NbStartPoints+1]; 580 Standard_Real *TabV = new Standard_Real [NbStartPoints+1]; 581 Standard_Real *TabW = new Standard_Real [NbStartPoints+1]; 582 Standard_Integer IndexPoint=0; 583 584 for(i=1; i<= NbSectionPoints; i++) { 585 const Intf_SectionPoint& SP = interference.PntValue(i); 586 SectionPointToParameters(SP,polyhedron,polygon,u,v,w); 587 TabU[IndexPoint]=u; 588 TabV[IndexPoint]=v; 589 TabW[IndexPoint]=w; 590 IndexPoint++; 591 } 592 for(i=1; i<= NbTangentZones; i++) { 593 const Intf_TangentZone& TZ = interference.ZoneValue(i); 594 Standard_Integer nbpnts = TZ.NumberOfPoints(); 595 for(Standard_Integer j=1; j<=nbpnts; j++) { 596 const Intf_SectionPoint& SP = TZ.GetPoint(j); 597 SectionPointToParameters(SP,polyhedron,polygon,u,v,w); 598 TabU[IndexPoint]=u; 599 TabV[IndexPoint]=v; 600 TabW[IndexPoint]=w; 601 IndexPoint++; 602 } 603 } 604 605 //-- Tri 606 Standard_Real su=0,sv=0,sw=0,ptol; 607 ptol = 10*Precision::PConfusion(); 608 609 //-- Tri suivant la variable W 610 Standard_Boolean Triok; 611 do { 612 Triok=Standard_True; 613 Standard_Integer im1; 614 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 615 if(TabW[i] < TabW[im1]) { 616 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t; 617 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t; 618 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 619 Triok=Standard_False; 620 } 621 } 622 } 623 while(Triok==Standard_False); 624 625 //-- On trie pour des meme W suivant U 626 do { 627 Triok=Standard_True; 628 Standard_Integer im1; 629 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 630// modified by NIZHNY-MKK Mon Oct 3 17:38:49 2005 631// if(Abs(TabW[i]-TabW[im1])<ptol) { 632 if((TabW[i]-TabW[im1])<ptol) { 633 TabW[i]=TabW[im1]; 634 if(TabU[i] < TabU[im1]) { 635 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t; 636 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 637 Triok=Standard_False; 638 } 639 } 640 } 641 } 642 while(Triok==Standard_False); 643 644 //-- On trie pour des meme U et W suivant V 645 do { 646 Triok=Standard_True; 647 Standard_Integer im1; 648 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 649// modified by NIZHNY-MKK Mon Oct 3 17:38:52 2005 650// if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 651 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 652 TabU[i]=TabU[im1]; 653 if(TabV[i] < TabV[im1]) { 654 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 655 Triok=Standard_False; 656 } 657 } 658 } 659 } 660 while(Triok==Standard_False); 661 662 663 for(i=0;i<NbStartPoints; i++) { 664 u=TabU[i]; v=TabV[i]; w=TabW[i]; 665 if(i==0) { 666 su=u-1; 667 } 668 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 669 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup); 670 if(intersectionExacte.IsDone()) { 671 if(!intersectionExacte.IsEmpty()) { 672 P=intersectionExacte.Point(); 673 w=intersectionExacte.ParameterOnCurve(); 674 intersectionExacte.ParameterOnSurface(u,v); 675 AppendPoint(curve,w,surface,u,v); 676 } 677 } 678 } 679 su=TabU[i]; sv=TabV[i]; sw=TabW[i]; 680 } 681 delete [] TabW; 682 delete [] TabV; 683 delete [] TabU; 684 } 685} 686 687//======================================================================= 688//function : InternalPerform 689//purpose : 690//======================================================================= 691void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve, 692 const IntCurveSurface_ThePolygon& polygon, 693 const TheSurface& surface, 694 const IntCurveSurface_ThePolyhedron& polyhedron, 695 const Standard_Real u0, 696 const Standard_Real v0, 697 const Standard_Real u1, 698 const Standard_Real v1) { 699 IntCurveSurface_TheInterference interference(polygon,polyhedron); 700 IntCurveSurface_TheCSFunction theicsfunction(surface,curve); 701 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY); 702 math_FunctionSetRoot rsnld(intersectionExacte.Function()); 703 704// Standard_Real u,v,w,winit; 705 Standard_Real u,v,w; 706 gp_Pnt P; 707 Standard_Real winf = polygon.InfParameter(); 708 Standard_Real wsup = polygon.SupParameter(); 709 Standard_Integer NbSectionPoints = interference.NbSectionPoints(); 710 Standard_Integer NbTangentZones = interference.NbTangentZones(); 711 712 713 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 714 715 Standard_Integer i,NbStartPoints=NbSectionPoints; 716 for(i=1; i<= NbTangentZones; i++) { 717 const Intf_TangentZone& TZ = interference.ZoneValue(i); 718 Standard_Integer nbpnts = TZ.NumberOfPoints(); 719 NbStartPoints+=nbpnts; 720 } 721 722 if(NbStartPoints) { 723 Standard_Real *TabU = new Standard_Real [NbStartPoints+1]; 724 Standard_Real *TabV = new Standard_Real [NbStartPoints+1]; 725 Standard_Real *TabW = new Standard_Real [NbStartPoints+1]; 726 Standard_Integer IndexPoint=0; 727 728 for(i=1; i<= NbSectionPoints; i++) { 729 const Intf_SectionPoint& SP = interference.PntValue(i); 730 SectionPointToParameters(SP,polyhedron,polygon,u,v,w); 731 TabU[IndexPoint]=u; 732 TabV[IndexPoint]=v; 733 TabW[IndexPoint]=w; 734 IndexPoint++; 735 } 736 for(i=1; i<= NbTangentZones; i++) { 737 const Intf_TangentZone& TZ = interference.ZoneValue(i); 738 Standard_Integer nbpnts = TZ.NumberOfPoints(); 739 for(Standard_Integer j=1; j<=nbpnts; j++) { 740 const Intf_SectionPoint& SP = TZ.GetPoint(j); 741 SectionPointToParameters(SP,polyhedron,polygon,u,v,w); 742 TabU[IndexPoint]=u; 743 TabV[IndexPoint]=v; 744 TabW[IndexPoint]=w; 745 IndexPoint++; 746 } 747 } 748 749 //-- Tri 750 Standard_Real su=0,sv=0,sw=0,ptol; 751 ptol = 10*Precision::PConfusion(); 752 753 //-- Tri suivant la variable W 754 Standard_Boolean Triok; 755 do { 756 Triok=Standard_True; 757 Standard_Integer im1; 758 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 759 if(TabW[i] < TabW[im1]) { 760 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t; 761 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t; 762 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 763 Triok=Standard_False; 764 } 765 } 766 } 767 while(Triok==Standard_False); 768 769 //-- On trie pour des meme W suivant U 770 do { 771 Triok=Standard_True; 772 Standard_Integer im1; 773 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 774// modified by NIZHNY-MKK Mon Oct 3 17:38:56 2005 775// if(Abs(TabW[i]-TabW[im1])<ptol) { 776 if((TabW[i]-TabW[im1])<ptol) { 777 TabW[i]=TabW[im1]; 778 if(TabU[i] < TabU[im1]) { 779 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t; 780 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 781 Triok=Standard_False; 782 } 783 } 784 } 785 } 786 while(Triok==Standard_False); 787 788 //-- On trie pour des meme U et W suivant V 789 do { 790 Triok=Standard_True; 791 Standard_Integer im1; 792 for(i=1,im1=0;i<NbStartPoints;im1++,i++) { 793// modified by NIZHNY-MKK Mon Oct 3 17:38:58 2005 794// if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 795 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 796 TabU[i]=TabU[im1]; 797 if(TabV[i] < TabV[im1]) { 798 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t; 799 Triok=Standard_False; 800 } 801 } 802 } 803 } 804 while(Triok==Standard_False); 805 806 807 for(i=0;i<NbStartPoints; i++) { 808 u=TabU[i]; v=TabV[i]; w=TabW[i]; 809 if(i==0) { 810 su=u-1; 811 } 812 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 813 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup); 814 if(intersectionExacte.IsDone()) { 815 if(!intersectionExacte.IsEmpty()) { 816 P=intersectionExacte.Point(); 817 w=intersectionExacte.ParameterOnCurve(); 818 intersectionExacte.ParameterOnSurface(u,v); 819 AppendPoint(curve,w,surface,u,v); 820 } 821 } 822 } 823 su=TabU[i]; sv=TabV[i]; sw=TabW[i]; 824 } 825 delete [] TabW; 826 delete [] TabV; 827 delete [] TabU; 828 } 829} 830//======================================================================= 831//function : InternalPerformCurveQuadric 832//purpose : 833//======================================================================= 834void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve& curve, 835 const TheSurface& surface) { 836 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve); 837 if(QuadCurv.IsDone()) { 838 Standard_Integer NbRoots = QuadCurv.NbRoots(); 839 Standard_Real u,v,w; 840 for(Standard_Integer i = 1; i<= NbRoots; i++) { 841 w = QuadCurv.Root(i); 842 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v); 843 AppendPoint(curve,w,surface,u,v); 844 } 845 //-- Intervals non traites ............................................. 846 } 847} 848 849//======================================================================= 850//function : InternalPerform 851//purpose : 852//======================================================================= 853void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve, 854 const IntCurveSurface_ThePolygon& polygon, 855 const TheSurface& surface, 856 const Standard_Real U1, 857 const Standard_Real V1, 858 const Standard_Real U2, 859 const Standard_Real V2) { 860 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 861 if( (SurfaceType != GeomAbs_Plane) 862 && (SurfaceType != GeomAbs_Cylinder) 863 && (SurfaceType != GeomAbs_Cone) 864 && (SurfaceType != GeomAbs_Sphere) ) { 865 if(SurfaceType != GeomAbs_BSplineSurface) { 866 Standard_Integer nbsu,nbsv; 867 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2); 868 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2); 869 if(nbsu>40) nbsu=40; 870 if(nbsv>40) nbsv=40; 871 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2); 872 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 873 } 874 else { 875 Handle(Adaptor3d_Surface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9); 876 aS = aS->VTrim(V1, V2, 1.e-9); 877 Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS); 878 Standard_Real defl = 0.1; 879 aTopTool->SamplePnts(defl, 10, 10); 880 881 Standard_Integer nbpu = aTopTool->NbSamplesU(); 882 Standard_Integer nbpv = aTopTool->NbSamplesV(); 883 TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv); 884 aTopTool->UParameters(Upars); 885 aTopTool->VParameters(Vpars); 886 887 IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars); 888 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 889 } 890 } 891 else { 892 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve); 893 if(QuadCurv.IsDone()) { 894 Standard_Integer NbRoots = QuadCurv.NbRoots(); 895 Standard_Real u,v,w; 896 for(Standard_Integer i = 1; i<= NbRoots; i++) { 897 w = QuadCurv.Root(i); 898 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v); 899 AppendPoint(curve,w,surface,u,v); 900 } 901 //-- Intervalles non traites ............................................. 902 } 903 } //-- Fin : la Surface est une quadrique 904} 905//======================================================================= 906//function : PerformConicSurf 907//purpose : 908//======================================================================= 909void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin& Line, 910 const TheCurve& curve, 911 const TheSurface& surface, 912 const Standard_Real U1, 913 const Standard_Real V1, 914 const Standard_Real U2, 915 const Standard_Real V2) { 916 917 918 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 919 Standard_Boolean isAnaProcessed = Standard_True; 920 switch(SurfaceType) { 921 case GeomAbs_Plane: 922 { 923 IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE); 924 AppendIntAna(curve,surface,LinPlane); 925 break; 926 } 927 case GeomAbs_Cylinder: 928 { 929 IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface)); 930 AppendIntAna(curve,surface,LinCylinder); 931 break; 932 } 933 case GeomAbs_Sphere: 934 { 935 IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface)); 936 AppendIntAna(curve,surface,LinSphere); 937 break; 938 } 939 case GeomAbs_Torus: 940 { 941 IntAna_IntLinTorus intlintorus(Line, TheSurfaceTool::Torus(surface)); 942 if (intlintorus.IsDone()) { 943 Standard_Integer nbp = intlintorus.NbPoints(); 944 Standard_Real fi, theta, w; 945 for (Standard_Integer i = 1; i <= nbp; i++) { 946 const gp_Pnt aDebPnt(intlintorus.Value(i)); 947 (void)aDebPnt; 948 w = intlintorus.ParamOnLine(i); 949 intlintorus.ParamOnTorus(i, fi, theta); 950 AppendPoint(curve, w, surface, fi, theta); 951 } 952 } 953 else 954 isAnaProcessed = Standard_False; 955 break; 956 } 957 case GeomAbs_Cone: 958 { 959 const Standard_Real correction = 1.E+5*Precision::Angular(); 960 gp_Cone cn = TheSurfaceTool::Cone(surface); 961 if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction) { 962 IntAna_IntConicQuad LinCone(Line, cn); 963 AppendIntAna(curve, surface, LinCone); 964 } 965 else 966 isAnaProcessed = Standard_False; 967 break; 968 } 969 default: 970 isAnaProcessed = Standard_False; 971 } 972 if (!isAnaProcessed) 973 { 974 Standard_Integer nbsu,nbsv; 975 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2); 976 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2); 977 978 Standard_Boolean U1inf = Precision::IsInfinite(U1); 979 Standard_Boolean U2inf = Precision::IsInfinite(U2); 980 Standard_Boolean V1inf = Precision::IsInfinite(V1); 981 Standard_Boolean V2inf = Precision::IsInfinite(V2); 982 983 Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2; 984 985 Standard_Boolean NoIntersection = Standard_False; 986 987 if(U1inf || U2inf || V1inf || V2inf ) { 988 989 if(SurfaceType == GeomAbs_SurfaceOfExtrusion) { 990 991 EstLimForInfExtr(Line, surface, Standard_False, nbsu, 992 U1inf, U2inf, V1inf, V2inf, 993 U1new, U2new, V1new, V2new, NoIntersection); 994 995 } 996 else if (SurfaceType == GeomAbs_SurfaceOfRevolution) { 997 998 EstLimForInfRevl(Line, surface, 999 U1inf, U2inf, V1inf, V2inf, 1000 U1new, U2new, V1new, V2new, NoIntersection); 1001 1002 } 1003 else if (SurfaceType == GeomAbs_OffsetSurface) { 1004 1005 EstLimForInfOffs(Line, surface, nbsu, 1006 U1inf, U2inf, V1inf, V2inf, 1007 U1new, U2new, V1new, V2new, NoIntersection); 1008 } 1009 else { 1010 1011 EstLimForInfSurf(U1new, U2new, V1new, V2new); 1012 } 1013 1014 } 1015 1016 1017 if(NoIntersection) return; 1018 1019 1020 // modified by NIZHNY-OFV Mon Aug 20 14:56:47 2001 (60963 begin) 1021 if(nbsu<20) nbsu=20; 1022 if(nbsv<20) nbsv=20; 1023 // modified by NIZHNY-OFV Mon Aug 20 14:57:06 2001 (60963 end) 1024 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new); 1025 Intf_Tool bndTool; 1026 Bnd_Box boxLine; 1027 bndTool.LinBox(Line,polyhedron.Bounding(),boxLine); 1028 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 1029 Standard_Real pinf = bndTool.BeginParam(nbseg); 1030 Standard_Real psup = bndTool.EndParam(nbseg); 1031 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; } 1032 IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2); 1033 InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new); 1034 } 1035 } 1036} 1037//======================================================================= 1038//function : PerformConicSurf 1039//purpose : 1040//======================================================================= 1041void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ& Circle, 1042 const TheCurve& curve, 1043 const TheSurface& surface, 1044 const Standard_Real U1, 1045 const Standard_Real V1, 1046 const Standard_Real U2, 1047 const Standard_Real V2) { 1048 1049 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 1050 switch(SurfaceType) { 1051 case GeomAbs_Plane: 1052 { 1053 IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE); 1054 AppendIntAna(curve,surface,CircPlane); 1055 break; 1056 } 1057 case GeomAbs_Cylinder: 1058 { 1059 IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface)); 1060 AppendIntAna(curve,surface,CircCylinder); 1061 break; 1062 } 1063 case GeomAbs_Cone: 1064 { 1065 IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface)); 1066 AppendIntAna(curve,surface,CircCone); 1067 break; 1068 } 1069 case GeomAbs_Sphere: 1070 { 1071 IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface)); 1072 AppendIntAna(curve,surface,CircSphere); 1073 break; 1074 } 1075 default: 1076 { 1077 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE); 1078 InternalPerform(curve,polygon,surface,U1,V1,U2,V2); 1079 } 1080 } 1081} 1082//======================================================================= 1083//function : PerformConicSurf 1084//purpose : 1085//======================================================================= 1086void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips& Ellipse, 1087 const TheCurve& curve, 1088 const TheSurface& surface, 1089 const Standard_Real U1, 1090 const Standard_Real V1, 1091 const Standard_Real U2, 1092 const Standard_Real V2) { 1093 1094 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 1095 switch(SurfaceType) { 1096 case GeomAbs_Plane: 1097 { 1098 IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE); 1099 AppendIntAna(curve,surface,EllipsePlane); 1100 break; 1101 } 1102 case GeomAbs_Cylinder: 1103 { 1104 IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface)); 1105 AppendIntAna(curve,surface,EllipseCylinder); 1106 break; 1107 } 1108 case GeomAbs_Cone: 1109 { 1110 IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface)); 1111 AppendIntAna(curve,surface,EllipseCone); 1112 break; 1113 } 1114 case GeomAbs_Sphere: 1115 { 1116 IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface)); 1117 AppendIntAna(curve,surface,EllipseSphere); 1118 break; 1119 } 1120 default: 1121 { 1122 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE); 1123 InternalPerform(curve,polygon,surface,U1,V1,U2,V2); 1124 } 1125 } 1126} 1127//======================================================================= 1128//function : PerformConicSurf 1129//purpose : 1130//======================================================================= 1131void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab& Parab, 1132 const TheCurve& curve, 1133 const TheSurface& surface, 1134 const Standard_Real U1, 1135 const Standard_Real V1, 1136 const Standard_Real U2, 1137 const Standard_Real V2) { 1138 1139 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 1140 switch(SurfaceType) { 1141 case GeomAbs_Plane: 1142 { 1143 IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE); 1144 AppendIntAna(curve,surface,ParabPlane); 1145 break; 1146 } 1147 case GeomAbs_Cylinder: 1148 { 1149 IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface)); 1150 AppendIntAna(curve,surface,ParabCylinder); 1151 break; 1152 } 1153 case GeomAbs_Cone: 1154 { 1155 IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface)); 1156 AppendIntAna(curve,surface,ParabCone); 1157 break; 1158 } 1159 case GeomAbs_Sphere: 1160 { 1161 IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface)); 1162 AppendIntAna(curve,surface,ParabSphere); 1163 break; 1164 } 1165 default: 1166 { 1167 Standard_Integer nbsu,nbsv; 1168 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2); 1169 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2); 1170 if(nbsu>40) nbsu=40; 1171 if(nbsv>40) nbsv=40; 1172 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2); 1173 Intf_Tool bndTool; 1174 Bnd_Box boxParab; 1175 bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab); 1176 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 1177 IntCurveSurface_ThePolygon polygon(curve, 1178 bndTool.BeginParam(nbseg), 1179 bndTool.EndParam(nbseg), 1180 NBSAMPLESONPARAB); 1181 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 1182 } 1183 } 1184 } 1185} 1186//======================================================================= 1187//function : PerformConicSurf 1188//purpose : 1189//======================================================================= 1190void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr& Hypr, 1191 const TheCurve& curve, 1192 const TheSurface& surface, 1193 const Standard_Real U1, 1194 const Standard_Real V1, 1195 const Standard_Real U2, 1196 const Standard_Real V2) { 1197 1198 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 1199 switch(SurfaceType) { 1200 case GeomAbs_Plane: 1201 { 1202 IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE); 1203 AppendIntAna(curve,surface,HyprPlane); 1204 break; 1205 } 1206 case GeomAbs_Cylinder: 1207 { 1208 IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface)); 1209 AppendIntAna(curve,surface,HyprCylinder); 1210 break; 1211 } 1212 case GeomAbs_Cone: 1213 { 1214 IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface)); 1215 AppendIntAna(curve,surface,HyprCone); 1216 break; 1217 } 1218 case GeomAbs_Sphere: 1219 { 1220 IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface)); 1221 AppendIntAna(curve,surface,HyprSphere); 1222 break; 1223 } 1224 default: 1225 { 1226 Standard_Integer nbsu,nbsv; 1227 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2); 1228 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2); 1229 if(nbsu>40) nbsu=40; 1230 if(nbsv>40) nbsv=40; 1231 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2); 1232 Intf_Tool bndTool; 1233 Bnd_Box boxHypr; 1234 bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr); 1235 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 1236 IntCurveSurface_ThePolygon polygon(curve, 1237 bndTool.BeginParam(nbseg), 1238 bndTool.EndParam(nbseg), 1239 NBSAMPLESONHYPR); 1240 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 1241 } 1242 } 1243 } 1244} 1245//======================================================================= 1246//function : AppendIntAna 1247//purpose : 1248//======================================================================= 1249void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve, 1250 const TheSurface& surface, 1251 const IntAna_IntConicQuad& intana_ConicQuad) { 1252 if(intana_ConicQuad.IsDone()) { 1253 if(intana_ConicQuad.IsInQuadric()) { 1254 //-- std::cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<std::endl; 1255 myIsParallel = Standard_True; 1256 } 1257 else if(intana_ConicQuad.IsParallel()) { 1258 //-- std::cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<std::endl; 1259 myIsParallel = Standard_True; 1260 } 1261 else { 1262 Standard_Integer nbp = intana_ConicQuad.NbPoints(); 1263 Standard_Real u,v,w; 1264 for(Standard_Integer i = 1; i<= nbp; i++) { 1265 gp_Pnt P(intana_ConicQuad.Point(i)); 1266 w = intana_ConicQuad.ParamOnConic(i); 1267 IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v); 1268 AppendPoint(curve,w,surface,u,v); 1269 } 1270 } 1271 } 1272 else { 1273 //-- std::cout<<" IntAna Conic Quad Not Done "<<std::endl; 1274 } 1275} 1276//======================================================================= 1277//function : AppendPoint 1278//purpose : 1279//======================================================================= 1280void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve, 1281 const Standard_Real lw, 1282 const TheSurface& surface, 1283 const Standard_Real su, 1284 const Standard_Real sv) { 1285 1286 Standard_Real W0 = TheCurveTool::FirstParameter(curve); 1287 Standard_Real W1 = TheCurveTool::LastParameter(curve); 1288 Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface); 1289 Standard_Real U1 = TheSurfaceTool::LastUParameter(surface); 1290 Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface); 1291 Standard_Real V1 = TheSurfaceTool::LastVParameter(surface); 1292 //-- Test si la courbe est periodique 1293 Standard_Real w = lw, u = su, v = sv; 1294 1295 GeomAbs_CurveType aCType = TheCurveTool::GetType(curve); 1296 1297 if(TheCurveTool::IsPeriodic(curve) 1298 || aCType == GeomAbs_Circle 1299 || aCType == GeomAbs_Ellipse) { 1300 w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve)); 1301 } 1302 1303 if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return; 1304 1305 GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface); 1306 if (TheSurfaceTool::IsUPeriodic(surface) 1307 || aSType == GeomAbs_Cylinder 1308 || aSType == GeomAbs_Cone 1309 || aSType == GeomAbs_Sphere) { 1310 u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface)); 1311 } 1312 1313 if (TheSurfaceTool::IsVPeriodic(surface)) { 1314 v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface)); 1315 } 1316 1317 if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return; 1318 if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return; 1319 1320 IntCurveSurface_TransitionOnCurve TransOnCurve; 1321 IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve, 1322 surface,u,v); 1323 gp_Pnt P(TheCurveTool::Value(curve,w)); 1324 IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve); 1325 Append(IP); //-- invoque la methode de IntCurveSurface_Intersection. 1326 1327} 1328 1329//======================================================================= 1330//function : AppendSegment 1331//purpose : 1332//======================================================================= 1333void IntCurveSurface_Inter::AppendSegment(const TheCurve& , 1334 const Standard_Real , 1335 const Standard_Real , 1336 const TheSurface& ) { 1337 //std::cout<<" !!! Not Yet Implemented 1338 //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<std::endl; 1339} 1340 1341//======================================================================= 1342//function : SectionPointToParameters 1343//purpose : P o i n t d i n t e r f e r e n c e - - > 1344// U , V e t W 1345//======================================================================= 1346void SectionPointToParameters(const Intf_SectionPoint& Sp, 1347 const IntCurveSurface_ThePolyhedron& Polyhedron, 1348 const IntCurveSurface_ThePolygon& Polygon, 1349 Standard_Real& U, 1350 Standard_Real& V, 1351 Standard_Real& W) { 1352 1353 Intf_PIType typ; 1354 Standard_Integer Adr1,Adr2; 1355 Standard_Real Param,u,v; 1356 gp_Pnt P(Sp.Pnt()); 1357 1358 Standard_Integer Pt1,Pt2,Pt3; 1359 Standard_Real u1 = 0.,v1 = 0.,param; 1360 //---------------------------------------------------------------------- 1361 //-- Calcul des parametres approches sur la surface -- 1362 //---------------------------------------------------------------------- 1363 1364 Sp.InfoSecond(typ,Adr1,Adr2,Param); 1365 switch(typ) { 1366 case Intf_VERTEX: //-- Adr1 est le numero du vertex 1367 { 1368 Polyhedron.Parameters(Adr1,u1,v1); 1369 break; 1370 } 1371 case Intf_EDGE: 1372 { 1373 Polyhedron.Parameters(Adr1,u1,v1); 1374 Polyhedron.Parameters(Adr2,u,v); 1375 u1+= Param * (u-u1); 1376 v1+= Param * (v-v1); 1377 break; 1378 } 1379 case Intf_FACE: 1380 { 1381 Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc; 1382 Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3); 1383 gp_Pnt PA(Polyhedron.Point(Pt1)); 1384 gp_Pnt PB(Polyhedron.Point(Pt2)); 1385 gp_Pnt PC(Polyhedron.Point(Pt3)); 1386 Polyhedron.Parameters(Pt1,ua,va); 1387 Polyhedron.Parameters(Pt2,ub,vb); 1388 Polyhedron.Parameters(Pt3,uc,vc); 1389 gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC))); 1390 cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale); 1391 ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale); 1392 cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale); 1393 cabc = ca + cb + cc; 1394 1395 ca/=cabc; cb/=cabc; cc/=cabc; 1396 1397 u1 = ca * ua + cb * ub + cc * uc; 1398 v1 = ca * va + cb * vb + cc * vc; 1399 break; 1400 } 1401 default: 1402 { 1403 std::cout<<" Default dans SectionPointToParameters "<<std::endl; 1404 break; 1405 } 1406 } 1407 //---------------------------------------------------------------------- 1408 //-- Calcul du point approche sur la Curve -- 1409 //---------------------------------------------------------------------- 1410 Standard_Integer SegIndex; 1411 1412 Sp.InfoFirst(typ,SegIndex,param); 1413 W = Polygon.ApproxParamOnCurve(SegIndex,param); 1414 if(param>1.0 || param<0.0) { 1415 //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron); 1416 //-- IntCurveSurface_ThePolygonTool::Dump(Polygon); 1417 } 1418 U = u1; 1419 V = v1; 1420} 1421//======================================================================= 1422//function : IntCurveSurface_ComputeTransitions 1423//purpose : 1424//======================================================================= 1425void IntCurveSurface_ComputeTransitions(const TheCurve& curve, 1426 const Standard_Real w, 1427 IntCurveSurface_TransitionOnCurve& TransOnCurve, 1428 const TheSurface& surface, 1429 const Standard_Real u, 1430 const Standard_Real v) { 1431 1432 gp_Vec NSurf,D1U,D1V;//TgCurv; 1433 gp_Pnt Psurf; 1434 Standard_Real CosDir; 1435 1436 1437 TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V); 1438 NSurf = D1U.Crossed(D1V); 1439 TheCurveTool::D1(curve,w,Psurf,D1U); 1440 Standard_Real Norm = NSurf.Magnitude(); 1441 if(Norm>TOLERANCE_ANGULAIRE && 1442 D1U.SquareMagnitude() > TOLERANCE_ANGULAIRE) { 1443 D1U.Normalize(); 1444 CosDir = NSurf.Dot(D1U); 1445 CosDir/=Norm; 1446 if( -CosDir > TOLERANCE_ANGULAIRE) { 1447 //-- --Curve---> <----Surface---- 1448 TransOnCurve = IntCurveSurface_In; 1449 } 1450 else if(CosDir > TOLERANCE_ANGULAIRE) { 1451 //-- --Curve---> ----Surface--> 1452 TransOnCurve = IntCurveSurface_Out; 1453 } 1454 else { 1455 TransOnCurve = IntCurveSurface_Tangent; 1456 } 1457 } 1458 else { 1459 TransOnCurve = IntCurveSurface_Tangent; 1460 } 1461} 1462//======================================================================= 1463//function : IntCurveSurface_ComputeParamsOnQuadric 1464//purpose : 1465//======================================================================= 1466void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface, 1467 const gp_Pnt& P, 1468 Standard_Real& u, 1469 Standard_Real& v) { 1470 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface); 1471 switch(SurfaceType) { 1472 case GeomAbs_Plane: 1473 { 1474 ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v); 1475 break; 1476 } 1477 case GeomAbs_Cylinder: 1478 { 1479 ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v); 1480 break; 1481 } 1482 case GeomAbs_Cone: 1483 { 1484 ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v); 1485 break; 1486 } 1487 case GeomAbs_Sphere: 1488 { 1489 ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v); 1490 break; 1491 } 1492 default: 1493 break; 1494 } 1495} 1496//======================================================================= 1497//function : EstLimForInfExtr 1498//purpose : Estimation of limits for infinite surfaces 1499//======================================================================= 1500void EstLimForInfExtr(const gp_Lin& Line, 1501 const TheSurface& surface, 1502 const Standard_Boolean IsOffSurf, 1503 const Standard_Integer nbsu, 1504 const Standard_Boolean U1inf, 1505 const Standard_Boolean U2inf, 1506 const Standard_Boolean V1inf, 1507 const Standard_Boolean V2inf, 1508 Standard_Real& U1new, 1509 Standard_Real& U2new, 1510 Standard_Real& V1new, 1511 Standard_Real& V2new, 1512 Standard_Boolean& NoIntersection) 1513 1514{ 1515 1516 NoIntersection = Standard_False; 1517 1518 Handle(Adaptor3d_Surface) aBasSurf; 1519 1520 if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface); 1521 1522 gp_Dir aDirOfExt; 1523 1524 if(IsOffSurf) aDirOfExt = aBasSurf->Direction(); 1525 else aDirOfExt = TheSurfaceTool::Direction(surface); 1526 1527 Standard_Real tolang = TOLERANCE_ANGULAIRE; 1528 1529 if(aDirOfExt.IsParallel(Line.Direction(), tolang)) { 1530 NoIntersection = Standard_True; 1531 return; 1532 } 1533 1534 if((V1inf || V2inf) && !(U1inf || U2inf)) { 1535 1536 Standard_Real vmin = RealLast(), vmax = -vmin; 1537 gp_Lin aL; 1538 Standard_Real step = (U2new - U1new) / nbsu; 1539 Standard_Real u = U1new, v; 1540 gp_Pnt aP; 1541 Extrema_POnCurv aP1, aP2; 1542 Standard_Integer i; 1543 1544 for(i = 0; i <= nbsu; i++) { 1545 1546 TheSurfaceTool::D0(surface, u, 0., aP); 1547 aL.SetLocation(aP); 1548 aL.SetDirection(aDirOfExt); 1549 1550 Extrema_ExtElC aExtr(aL, Line, tolang); 1551 1552 if(!aExtr.IsDone()) return; 1553 1554 if(aExtr.IsParallel()) { 1555 NoIntersection = Standard_True; 1556 return; 1557 } 1558 1559 aExtr.Points(1, aP1, aP2); 1560 v = aP1.Parameter(); 1561 vmin = Min(vmin, v); 1562 vmax = Max(vmax, v); 1563 1564 u += step; 1565 1566 } 1567 1568 vmin = vmin - Abs(vmin) - 10.; 1569 vmax = vmax + Abs(vmax) + 10.; 1570 1571 V1new = Max(V1new, vmin); 1572 V2new = Min(V2new, vmax); 1573 1574 } 1575 else if(U1inf || U2inf) { 1576 1577 Standard_Real umin = RealLast(), umax = -umin; 1578 Standard_Real u0 = Min(Max(0., U1new), U2new); 1579 Standard_Real v0 = Min(Max(0., V1new), V2new); 1580 gp_Pnt aP; 1581 TheSurfaceTool::D0(surface, u0, v0, aP); 1582 gp_Pln aRefPln(aP, aDirOfExt); 1583 1584 Handle(Adaptor3d_Curve) aBasCurv; 1585 1586 if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve(); 1587 else aBasCurv = TheSurfaceTool::BasisCurve(surface); 1588 1589 ProjLib_Plane Projector(aRefPln); 1590 1591 Projector.Project(Line); 1592 1593 if(!Projector.IsDone()) return; 1594 1595 gp_Lin2d Line2d = Projector.Line(); 1596 1597 GeomAbs_CurveType aCurvTyp = aBasCurv->GetType(); 1598 1599 if(aCurvTyp == GeomAbs_Line) { 1600 1601 Projector.Project(aBasCurv->Line()); 1602 1603 if(!Projector.IsDone()) return; 1604 1605 gp_Lin2d aL2d = Projector.Line(); 1606 1607 IntAna2d_AnaIntersection anInter(Line2d, aL2d); 1608 1609 if(!anInter.IsDone()) return; 1610 1611 if(anInter.IsEmpty() || anInter.IdenticalElements() || 1612 anInter.ParallelElements() ) { 1613 NoIntersection = Standard_True; 1614 return; 1615 } 1616 1617 const IntAna2d_IntPoint& anIntPnt = anInter.Point(1); 1618 umin = umax = anIntPnt.ParamOnSecond(); 1619 } 1620 else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) { 1621 1622 IntAna2d_Conic aCon(Line2d); 1623 IntAna2d_AnaIntersection anInter; 1624 1625 if(aCurvTyp == GeomAbs_Parabola) { 1626 Projector.Project(aBasCurv->Parabola()); 1627 if(!Projector.IsDone()) return; 1628 1629 const gp_Parab2d& aP2d = Projector.Parabola(); 1630 1631 anInter.Perform(aP2d, aCon); 1632 } 1633 else { 1634 Projector.Project(aBasCurv->Hyperbola()); 1635 if(!Projector.IsDone()) return; 1636 1637 const gp_Hypr2d& aH2d = Projector.Hyperbola(); 1638 anInter.Perform(aH2d, aCon); 1639 } 1640 1641 if(!anInter.IsDone()) return; 1642 1643 if(anInter.IsEmpty()) { 1644 NoIntersection = Standard_True; 1645 return; 1646 } 1647 1648 Standard_Integer i, nbint = anInter.NbPoints(); 1649 for(i = 1; i <= nbint; i++) { 1650 1651 const IntAna2d_IntPoint& anIntPnt = anInter.Point(i); 1652 1653 umin = Min(anIntPnt.ParamOnFirst(), umin); 1654 umax = Max(anIntPnt.ParamOnFirst(), umax); 1655 1656 } 1657 1658 } 1659 else { 1660 return; 1661 } 1662 1663 umin = umin - Abs(umin) - 10; 1664 umax = umax + Abs(umax) + 10; 1665 1666 U1new = Max(U1new, umin); 1667 U2new = Min(U2new, umax); 1668 1669 if(V1inf || V2inf) { 1670 EstLimForInfExtr(Line, surface, IsOffSurf, nbsu, 1671 Standard_False, Standard_False, V1inf, V2inf, 1672 U1new, U2new, V1new, V2new, NoIntersection); 1673 } 1674 } 1675 1676 return; 1677 1678} 1679//======================================================================= 1680//function : ProjectIntersectAndEstLim 1681//purpose : project <theLine> and it's X-axe symmetric line to <thePln> and 1682// intersect resulting curve with <theBasCurvProj>. 1683// Then estimate max and min parameters of intersection on 1684// <theBasCurvProj>. 1685// Is called from EstLimForInfRevl() 1686//======================================================================= 1687void ProjectIntersectAndEstLim(const gp_Lin& theLine, 1688 const gp_Pln& thePln, 1689 const ProjLib_Plane& theBasCurvProj, 1690 Standard_Real& theVmin, 1691 Standard_Real& theVmax, 1692 Standard_Boolean& theNoIntersection) 1693{ 1694 ProjLib_Plane aLineProj( thePln, theLine ); 1695 if (!aLineProj.IsDone()) { 1696#ifdef OCCT_DEBUG 1697 std::cout 1698 << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()" 1699 << std::endl; 1700#endif 1701 return; 1702 } 1703 gp_Lin2d aLin2d = aLineProj.Line(); 1704 1705 // make a second line X-axe symmetric to the first one 1706 gp_Pnt2d aP1 = aLin2d.Location(); 1707 gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY()); 1708 gp_Pnt2d aP1sym (aP1.X(), -aP1.Y()); 1709 gp_Pnt2d aP2sym (aP2.X(), -aP2.Y()); 1710 gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym)); 1711 1712 // intersect projections 1713 IntAna2d_Conic aCon (aLin2d); 1714 IntAna2d_Conic aConSym (aLin2dsym); 1715 IntAna2d_AnaIntersection anIntersect; 1716 IntAna2d_AnaIntersection anIntersectSym; 1717 1718 switch (theBasCurvProj.GetType()) { 1719 case GeomAbs_Line: 1720 anIntersectSym.Perform(theBasCurvProj.Line(), aConSym); 1721 anIntersect.Perform(theBasCurvProj.Line(), aCon); break; 1722 case GeomAbs_Hyperbola: 1723 anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym); 1724 anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break; 1725 case GeomAbs_Parabola: 1726 anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym); 1727 anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break; 1728 default: 1729 return; // not infinite curve 1730 } 1731 1732 // retrieve params of intersections 1733 Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0; 1734 Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0; 1735 Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym); 1736 1737 if (aNbPnt == 0) { 1738 theNoIntersection = Standard_True; 1739 return; 1740 } 1741 Standard_Real aParam; 1742 for (iPnt = 1; iPnt <= aNbPnt; iPnt++) 1743 { 1744 if (iPnt <= aNbIntPnt) { 1745 const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt); 1746 aParam = aIntPnt.ParamOnFirst(); 1747 theVmin = Min (theVmin, aParam ); 1748 theVmax = Max (theVmax, aParam ); 1749 } 1750 if (iPnt <= aNbIntPntSym) { 1751 const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt); 1752 aParam = aIntPnt.ParamOnFirst(); 1753 theVmin = Min (theVmin, aParam ); 1754 theVmax = Max (theVmax, aParam ); 1755 } 1756 } 1757 1758 return; 1759} 1760//======================================================================= 1761//function : EstLimForInfRevl 1762//purpose : Estimate V1 and V2 to pass to InternalPerform() if they are 1763// infinite for Surface of Revolution 1764// Algo: intersect projections of Line and basis curve on the 1765// plane passing through revolution axe 1766//======================================================================= 1767void EstLimForInfRevl(const gp_Lin& Line, 1768 const TheSurface& surface, 1769 const Standard_Boolean U1inf, 1770 const Standard_Boolean U2inf, 1771 const Standard_Boolean V1inf, 1772 const Standard_Boolean V2inf, 1773 Standard_Real& U1new, 1774 Standard_Real& U2new, 1775 Standard_Real& V1new, 1776 Standard_Real& V2new, 1777 Standard_Boolean& NoIntersection) 1778{ 1779 1780 NoIntersection = Standard_False; 1781 1782 if (U1inf || U2inf) { 1783 if (U1inf) 1784 U1new = Max (0., U1new); 1785 else 1786 U2new = Min (2 * M_PI, U2new); 1787 if (! V1inf && !V2inf) return; 1788 } 1789 1790 Handle(Adaptor3d_Curve) aBasisCurve = TheSurfaceTool::BasisCurve(surface); 1791 gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface); 1792 gp_Vec aXVec = aRevAx.Direction(); 1793 Standard_Real aTolAng = Precision::Angular(); 1794 1795 // make plane to project a basis curve 1796 gp_Pnt O = aRevAx.Location(); 1797 Standard_Real aU = 0.; 1798 gp_Pnt P = aBasisCurve->Value(aU); 1799 while (O.SquareDistance(P) <= Precision::PConfusion() || 1800 aXVec.IsParallel( gp_Vec(O,P), aTolAng)) { 1801 aU += 1.; 1802 P = aBasisCurve->Value(aU); 1803 if (aU > 3) 1804 // basis curve is a line coinciding with aXVec, P is any not on aXVec 1805 P = gp_Pnt(aU, aU+1, aU+2); 1806 } 1807 gp_Vec aNVec = aXVec ^ gp_Vec(O,P); 1808 gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec)); 1809 1810 // project basic curve 1811 ProjLib_Plane aBasCurvProj(aPln); 1812 switch (aBasisCurve->GetType()) { 1813 case GeomAbs_Line: 1814 aBasCurvProj.Project(aBasisCurve->Line ()); break; 1815 case GeomAbs_Hyperbola: 1816 aBasCurvProj.Project(aBasisCurve->Hyperbola()); break; 1817 case GeomAbs_Parabola: 1818 aBasCurvProj.Project(aBasisCurve->Parabola ()); break; 1819 default: 1820 return; // not infinite curve 1821 } 1822 if (!aBasCurvProj.IsDone()) { 1823#ifdef OCCT_DEBUG 1824 std::cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << std::endl; 1825#endif 1826 return; 1827 } 1828 // make plane to project Line 1829 if (aXVec.IsParallel( Line.Direction(), aTolAng)) { 1830 P = Line.Location(); 1831 while (O.SquareDistance(P) <= Precision::PConfusion()) { 1832 aU += 1.; 1833 P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec 1834 } 1835 aNVec = aXVec ^ gp_Vec(O,P); 1836 } else 1837 aNVec = aXVec.Crossed( Line.Direction() ); 1838 1839 aPln = gp_Pln (gp_Ax3 (O, aNVec ,aXVec)); 1840 1841 // make a second plane perpendicular to the first one, rotated around aXVec 1842 gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.); 1843 1844 // project Line and it's X-axe symmetric one to plane and intersect 1845 // resulting curve with projection of Basic Curev 1846 Standard_Real aVmin = RealLast(), aVmax = -aVmin; 1847 Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False; 1848 ProjectIntersectAndEstLim (Line, aPln, aBasCurvProj, aVmin, aVmax, aNoInt1); 1849 ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2); 1850 1851 if (aNoInt1 && aNoInt2) { 1852 NoIntersection = Standard_True; 1853 return; 1854 } 1855 1856 aVmin = aVmin - Abs(aVmin) - 10; 1857 aVmax = aVmax + Abs(aVmax) + 10; 1858 1859 if (V1inf) V1new = aVmin; 1860 if (V2inf) V2new = aVmax; 1861 1862 //std::cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << std::endl; 1863 1864 return; 1865} 1866 1867//======================================================================= 1868//function : EstLimForInfOffs 1869//purpose : 1870//======================================================================= 1871void EstLimForInfOffs(const gp_Lin& Line, 1872 const TheSurface& surface, 1873 const Standard_Integer nbsu, 1874 const Standard_Boolean U1inf, 1875 const Standard_Boolean U2inf, 1876 const Standard_Boolean V1inf, 1877 const Standard_Boolean V2inf, 1878 Standard_Real& U1new, 1879 Standard_Real& U2new, 1880 Standard_Real& V1new, 1881 Standard_Real& V2new, 1882 Standard_Boolean& NoIntersection) 1883{ 1884 1885 NoIntersection = Standard_False; 1886 1887 const Handle(Adaptor3d_Surface)& aBasSurf = TheSurfaceTool::BasisSurface(surface); 1888 Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface); 1889 1890 GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType(); 1891 1892 // case for plane, cylinder and cone - make equivalent surface; 1893 if(aTypeOfBasSurf == GeomAbs_Plane) { 1894 1895 gp_Pln aPln = aBasSurf->Plane(); 1896 gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection(); 1897 aT *= anOffVal; 1898 aPln.Translate(aT); 1899 IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE); 1900 1901 if(!LinPlane.IsDone()) return; 1902 1903 if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) { 1904 1905 NoIntersection = Standard_True; 1906 return; 1907 1908 } 1909 1910 Standard_Real u, v; 1911 ElSLib::Parameters(aPln, LinPlane.Point(1), u, v); 1912 U1new = Max(U1new, u - 10.); 1913 U2new = Min(U2new, u + 10.); 1914 V1new = Max(V1new, v - 10.); 1915 V2new = Min(V2new, v + 10.); 1916 1917 } 1918 else if(aTypeOfBasSurf == GeomAbs_Cylinder) { 1919 1920 gp_Cylinder aCyl = aBasSurf->Cylinder(); 1921 1922 Standard_Real aR = aCyl.Radius(); 1923 gp_Ax3 anA = aCyl.Position(); 1924 1925 if (anA.Direct()) 1926 aR += anOffVal; 1927 else 1928 aR -= anOffVal; 1929 1930 if ( aR >= TOLTANGENCY ) { 1931 aCyl.SetRadius(aR); 1932 } 1933 else if ( aR <= -TOLTANGENCY ){ 1934 anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI); 1935 aCyl.SetPosition(anA); 1936// modified by NIZHNY-MKK Mon Oct 3 17:37:54 2005 1937// aCyl.SetRadius(Abs(aR)); 1938 aCyl.SetRadius(-aR); 1939 } 1940 else { 1941 1942 NoIntersection = Standard_True; 1943 return; 1944 1945 } 1946 1947 IntAna_IntConicQuad LinCylinder(Line, aCyl); 1948 1949 if(!LinCylinder.IsDone()) return; 1950 1951 if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) { 1952 1953 NoIntersection = Standard_True; 1954 return; 1955 1956 } 1957 1958 Standard_Integer i, nbp = LinCylinder.NbPoints(); 1959 Standard_Real vmin = RealLast(), vmax = -vmin, u, v; 1960 1961 for(i = 1; i <= nbp; i++) { 1962 1963 ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v); 1964 vmin = Min(vmin, v); 1965 vmax = Max(vmax, v); 1966 1967 } 1968 1969 V1new = Max(V1new, vmin - Abs(vmin) - 10.); 1970 V2new = Min(V2new, vmax + Abs(vmax) + 10.); 1971 1972 } 1973 else if(aTypeOfBasSurf == GeomAbs_Cone) { 1974 1975 gp_Cone aCon = aBasSurf->Cone(); 1976 Standard_Real anAng = aCon.SemiAngle(); 1977 Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng); 1978 gp_Ax3 anA = aCon.Position(); 1979 if ( aR >= 0.) { 1980 1981 gp_Vec aZ( anA.Direction()); 1982 aZ *= - anOffVal * Sin(anAng); 1983 anA.Translate(aZ); 1984 aCon.SetPosition(anA); 1985 aCon.SetRadius(aR); 1986 aCon.SetSemiAngle(anAng); 1987 1988 } 1989 else { 1990 1991 return; 1992 1993 } 1994 1995 IntAna_IntConicQuad LinCone(Line, aCon); 1996 1997 if(!LinCone.IsDone()) return; 1998 1999 if(LinCone.IsParallel() || LinCone.IsInQuadric()) { 2000 2001 NoIntersection = Standard_True; 2002 return; 2003 2004 } 2005 2006 Standard_Integer i, nbp = LinCone.NbPoints(); 2007 Standard_Real vmin = RealLast(), vmax = -vmin, u, v; 2008 2009 for(i = 1; i <= nbp; i++) { 2010 2011 ElSLib::Parameters(aCon, LinCone.Point(i), u, v); 2012 vmin = Min(vmin, v); 2013 vmax = Max(vmax, v); 2014 2015 } 2016 2017 V1new = Max(V1new, vmin - Abs(vmin) - 10.); 2018 V2new = Min(V2new, vmax + Abs(vmax) + 10.); 2019 2020 } 2021 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) { 2022 2023 Standard_Real anU1 = U1new, anU2 = U2new; 2024 2025 EstLimForInfExtr(Line, surface, Standard_True, nbsu, 2026 U1inf, U2inf, V1inf, V2inf, 2027 U1new, U2new, V1new, V2new, NoIntersection); 2028 2029 if(NoIntersection) return; 2030 2031 if(U1inf || U2inf) { 2032 2033 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType(); 2034 if(aBasCurvType == GeomAbs_Line) { 2035 U1new = Max(anU1, -1.e10); 2036 U2new = Min(anU2, 1.e10); 2037 } 2038 else if(aBasCurvType == GeomAbs_Parabola) { 2039 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola(); 2040 Standard_Real aF = aPrb.Focal(); 2041 Standard_Real dU = 2.e5 * Sqrt(aF); 2042 U1new = Max(anU1, -dU); 2043 U2new = Min(anU2, dU); 2044 } 2045 else if(aBasCurvType == GeomAbs_Hyperbola) { 2046 U1new = Max(anU1, -30.); 2047 U2new = Min(anU2, 30.); 2048 } 2049 else { 2050 U1new = Max(anU1, -1.e10); 2051 U2new = Min(anU2, 1.e10); 2052 } 2053 2054 } 2055 2056 } 2057 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) { 2058 2059 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType(); 2060 if(aBasCurvType == GeomAbs_Line) { 2061 V1new = Max(V1new, -1.e10); 2062 V2new = Min(V2new, 1.e10); 2063 } 2064 else if(aBasCurvType == GeomAbs_Parabola) { 2065 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola(); 2066 Standard_Real aF = aPrb.Focal(); 2067 Standard_Real dV = 2.e5 * Sqrt(aF); 2068 V1new = Max(V1new, -dV); 2069 V2new = Min(V2new, dV); 2070 } 2071 else if(aBasCurvType == GeomAbs_Hyperbola) { 2072 V1new = Max(V1new, -30.); 2073 V2new = Min(V2new, 30.); 2074 } 2075 else { 2076 V1new = Max(V1new, -1.e10); 2077 V2new = Min(V2new, 1.e10); 2078 } 2079 2080 } 2081 else { 2082 2083 V1new = Max(V1new, -1.e10); 2084 V2new = Min(V2new, 1.e10); 2085 } 2086} 2087//======================================================================= 2088//function : EstLimForInfSurf 2089//purpose : 2090//======================================================================= 2091void EstLimForInfSurf(Standard_Real& U1new, 2092 Standard_Real& U2new, 2093 Standard_Real& V1new, 2094 Standard_Real& V2new) 2095{ 2096 U1new = Max(U1new, -1.e10); 2097 U2new = Min(U2new, 1.e10); 2098 V1new = Max(V1new, -1.e10); 2099 V2new = Min(V2new, 1.e10); 2100} 2101