0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / GeomInt / GeomInt_IntSS_1.cxx
CommitLineData
b311480e 1// Created on: 1995-01-27
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
4e14c88f 17#include <algorithm>
18#include <GeomInt_IntSS.hxx>
7fd59977 19
20#include <Adaptor3d_TopolTool.hxx>
42cf5bc1 21#include <Approx_CurveOnSurface.hxx>
42cf5bc1 22#include <ElSLib.hxx>
23#include <Extrema_ExtPS.hxx>
42cf5bc1 24#include <Geom2dAdaptor.hxx>
25#include <Geom2dAdaptor_Curve.hxx>
26#include <Geom2dInt_GInter.hxx>
4e14c88f 27#include <Geom2d_Line.hxx>
28#include <Geom2d_TrimmedCurve.hxx>
42cf5bc1 29#include <GeomAdaptor.hxx>
30#include <GeomAdaptor_HSurface.hxx>
31#include <GeomInt.hxx>
4e14c88f 32#include <GeomInt_LineTool.hxx>
42cf5bc1 33#include <GeomInt_WLApprox.hxx>
7fd59977 34#include <GeomLib_Check2dBSplineCurve.hxx>
42cf5bc1 35#include <GeomLib_CheckBSplineCurve.hxx>
7fd59977 36#include <GeomProjLib.hxx>
4e14c88f 37#include <Geom_BSplineCurve.hxx>
38#include <Geom_Circle.hxx>
39#include <Geom_Ellipse.hxx>
40#include <Geom_Hyperbola.hxx>
41#include <Geom_Line.hxx>
42#include <Geom_Parabola.hxx>
43#include <Geom_TrimmedCurve.hxx>
42cf5bc1 44#include <IntPatch_GLine.hxx>
d4b867e6 45#include <IntPatch_RLine.hxx>
42cf5bc1 46#include <IntPatch_WLine.hxx>
7a91ad6e 47#include <IntRes2d_IntersectionSegment.hxx>
4e14c88f 48#include <IntSurf_Quadric.hxx>
e2e0498b 49#include <Precision.hxx>
7fd59977 50
51//=======================================================================
4e14c88f 52//function : AdjustUPeriodic
7fd59977 53//purpose :
54//=======================================================================
4e14c88f 55 static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
7fd59977 56{
4e14c88f 57 if (aC2D.IsNull() || !aS->IsUPeriodic())
58 return;
7fd59977 59 //
4e14c88f 60 const Standard_Real aEps=Precision::PConfusion();//1.e-9
61 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
62 //
63 Standard_Real umin,umax,vmin,vmax;
64 aS->Bounds(umin,umax,vmin,vmax);
65 const Standard_Real aPeriod = aS->UPeriod();
66
67 const Standard_Real aT1=aC2D->FirstParameter();
68 const Standard_Real aT2=aC2D->LastParameter();
69 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
70 const gp_Pnt2d aPx=aC2D->Value(aTx);
71 //
72 Standard_Real aUx=aPx.X();
73 if (fabs(aUx)<aEpsilon)
74 aUx=0.;
75 if (fabs(aUx-aPeriod)<aEpsilon)
76 aUx=aPeriod;
77 //
78 Standard_Real dU=0.;
79 while(aUx <(umin-aEps)) {
80 aUx+=aPeriod;
81 dU+=aPeriod;
82 }
83 while(aUx>(umax+aEps)) {
84 aUx-=aPeriod;
85 dU-=aPeriod;
86 }
87 //
88 if (dU!=0.) {
89 gp_Vec2d aV2D(dU, 0.);
90 aC2D->Translate(aV2D);
91 }
7fd59977 92}
4e14c88f 93
94 //=======================================================================
95//function : GetQuadric
7fd59977 96//purpose :
97//=======================================================================
4e14c88f 98 static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
7fd59977 99{
4e14c88f 100 switch (HS1->Surface().GetType())
101 {
102 case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break;
103 case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
104 case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break;
105 case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break;
106 case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break;
9775fa61 107 default: throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
7fd59977 108 }
109}
4e14c88f 110
111//=======================================================================
112//function : Parameters
113//purpose :
114//=======================================================================
115 static void Parameters( const Handle(GeomAdaptor_HSurface)& HS1,
116 const Handle(GeomAdaptor_HSurface)& HS2,
117 const gp_Pnt& Ptref,
118 Standard_Real& U1,
119 Standard_Real& V1,
120 Standard_Real& U2,
121 Standard_Real& V2)
122{
123 IntSurf_Quadric quad1,quad2;
124 //
125 GetQuadric(HS1, quad1);
126 GetQuadric(HS2, quad2);
127 //
128 quad1.Parameters(Ptref,U1,V1);
129 quad2.Parameters(Ptref,U2,V2);
130}
131
7fd59977 132//=======================================================================
4e14c88f 133//function : ParametersOfNearestPointOnSurface
7fd59977 134//purpose :
135//=======================================================================
4e14c88f 136static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
137 Standard_Real& theU,
138 Standard_Real& theV)
7fd59977 139{
4e14c88f 140 if(!theExtr.IsDone() || !theExtr.NbExt())
141 return Standard_False;
142
143 Standard_Integer anIndex = 1;
144 Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
145 for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
146 {
147 Standard_Real aSQD = theExtr.SquareDistance(i);
148 if (aSQD < aMinSQDist)
149 {
150 aMinSQDist = aSQD;
151 anIndex = i;
152 }
153 }
154
155 theExtr.Point(anIndex).Parameter(theU, theV);
156
157 return Standard_True;
7fd59977 158}
4e14c88f 159
7fd59977 160//=======================================================================
4e14c88f 161//function : GetSegmentBoundary
7fd59977 162//purpose :
163//=======================================================================
4e14c88f 164static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
165 const Handle(Geom2d_Curve)& theCurve,
166 GeomInt_VectorOfReal& theArrayOfParameters)
7fd59977 167{
4e14c88f 168 Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
169
170 if(theSegm.HasFirstPoint())
171 {
172 const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
173 aU1 = anIPF.ParamOnFirst();
174 }
175
176 if(theSegm.HasLastPoint())
177 {
178 const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
179 aU2 = anIPL.ParamOnFirst();
180 }
181
182 theArrayOfParameters.Append(aU1);
183 theArrayOfParameters.Append(aU2);
7fd59977 184}
4e14c88f 185
7fd59977 186//=======================================================================
4e14c88f 187//function : IntersectCurveAndBoundary
7fd59977 188//purpose :
189//=======================================================================
4e14c88f 190static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
191 const Handle(Geom2d_Curve)* const theArrBounds,
192 const Standard_Integer theNumberOfCurves,
193 const Standard_Real theTol,
194 GeomInt_VectorOfReal& theArrayOfParameters)
7fd59977 195{
4e14c88f 196 if(theC2d.IsNull())
197 return;
198
199 Geom2dAdaptor_Curve anAC1(theC2d);
200 for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
201 {
202 if(theArrBounds[aCurID].IsNull())
203 continue;
204
205 Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
206 Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
207
208 if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
209 continue;
210
211 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
212 {
213 const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
214 theArrayOfParameters.Append(aParam);
215 }
216
217 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
218 {
219 GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
220 }
221 }
7fd59977 222}
7fd59977 223
b55bd023 224//=======================================================================
225//function : isDegenerated
226//purpose : Check if theAHC2d corresponds to a degenerated edge.
227//=======================================================================
228static Standard_Boolean isDegenerated(const Handle(GeomAdaptor_HSurface)& theGAHS,
229 const Handle(Adaptor2d_HCurve2d)& theAHC2d,
230 const Standard_Real theFirstPar,
231 const Standard_Real theLastPar)
232{
233 const Standard_Real aSqTol = Precision::Confusion()*Precision::Confusion();
234 gp_Pnt2d aP2d;
235 gp_Pnt aP1, aP2;
236
237 theAHC2d->D0(theFirstPar, aP2d);
238 theGAHS->D0(aP2d.X(), aP2d.Y(), aP1);
239
240 theAHC2d->D0(theLastPar, aP2d);
241 theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
242
243 if(aP1.SquareDistance(aP2) > aSqTol)
244 return Standard_False;
245
246 theAHC2d->D0(0.5*(theFirstPar+theLastPar), aP2d);
247 theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
248
249 if(aP1.SquareDistance(aP2) > aSqTol)
250 return Standard_False;
251
252 return Standard_True;
253}
254
7fd59977 255//=======================================================================
256//function : MakeCurve
257//purpose :
258//=======================================================================
d4b867e6 259void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
4e14c88f 260 const Handle(Adaptor3d_TopolTool) & dom1,
261 const Handle(Adaptor3d_TopolTool) & dom2,
262 const Standard_Real Tol,
263 const Standard_Boolean Approx,
264 const Standard_Boolean ApproxS1,
265 const Standard_Boolean ApproxS2)
7fd59977 266
267{
268 Standard_Boolean myApprox1, myApprox2, myApprox;
269 Standard_Real Tolpc, myTolApprox;
270 IntPatch_IType typl;
271 Handle(Geom2d_BSplineCurve) H1;
272 Handle(Geom_Surface) aS1, aS2;
273 //
274 Tolpc = Tol;
275 myApprox=Approx;
276 myApprox1=ApproxS1;
277 myApprox2=ApproxS2;
278 myTolApprox=0.0000001;
279 //
280 aS1=myHS1->ChangeSurface().Surface();
281 aS2=myHS2->ChangeSurface().Surface();
282 //
283 Handle(IntPatch_Line) L = myIntersector.Line(Index);
284 typl = L->ArcType();
285 //
286 if(typl==IntPatch_Walking) {
4e14c88f 287 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
288 if(aWLine.IsNull()) {
7fd59977 289 return;
290 }
4e14c88f 291 L = aWLine;
7fd59977 292 }
293 //
294 // Line Constructor
295 myLConstruct.Perform(L);
296 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
297 return;
298 }
299 // Do the Curve
300 Standard_Boolean ok;
301 Standard_Integer i, j, aNbParts;
302 Standard_Real fprm, lprm;
303 Handle(Geom_Curve) newc;
304
305 switch (typl) {
e618b526 306 //########################################
307 // Line, Parabola, Hyperbola
308 //########################################
7fd59977 309 case IntPatch_Lin:
310 case IntPatch_Parabola:
311 case IntPatch_Hyperbola: {
312 if (typl == IntPatch_Lin) {
313 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
314 }
315 else if (typl == IntPatch_Parabola) {
316 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
317 }
318 else if (typl == IntPatch_Hyperbola) {
319 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
320 }
321 //
322 aNbParts=myLConstruct.NbParts();
323 for (i=1; i<=aNbParts; i++) {
324 myLConstruct.Part(i, fprm, lprm);
e618b526 325
7fd59977 326 if (!Precision::IsNegativeInfinite(fprm) &&
e618b526 327 !Precision::IsPositiveInfinite(lprm)) {
328 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
329 sline.Append(aCT3D);
330 //
331 if(myApprox1) {
332 Handle (Geom2d_Curve) C2d;
333 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
334 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
335 myTolReached2d=Tolpc;
336 }
337 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
338 }
339 else {
340 slineS1.Append(H1);
341 }
342 //
343 if(myApprox2) {
344 Handle (Geom2d_Curve) C2d;
345 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
346 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
347 myTolReached2d=Tolpc;
348 }
349 //
350 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
351 }
352 else {
353 slineS2.Append(H1);
354 }
7fd59977 355 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
356
357 else {
7c4e9501 358 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
359 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
360 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
361 typS1 == GeomAbs_OffsetSurface ||
362 typS1 == GeomAbs_SurfaceOfRevolution ||
363 typS2 == GeomAbs_SurfaceOfExtrusion ||
364 typS2 == GeomAbs_OffsetSurface ||
365 typS2 == GeomAbs_SurfaceOfRevolution) {
366 sline.Append(newc);
367 slineS1.Append(H1);
368 slineS2.Append(H1);
369 continue;
370 }
371 Standard_Boolean bFNIt, bLPIt;
372 Standard_Real aTestPrm, dT=100.;
373 Standard_Real u1, v1, u2, v2, TolX;
374 //
375 bFNIt=Precision::IsNegativeInfinite(fprm);
376 bLPIt=Precision::IsPositiveInfinite(lprm);
377
378 aTestPrm=0.;
379
380 if (bFNIt && !bLPIt) {
381 aTestPrm=lprm-dT;
382 }
383 else if (!bFNIt && bLPIt) {
384 aTestPrm=fprm+dT;
385 }
386 //
387 gp_Pnt ptref(newc->Value(aTestPrm));
388 //
389 TolX = Precision::Confusion();
390 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
391 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
392 if(ok) {
393 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
394 }
395 if (ok) {
396 sline.Append(newc);
397 slineS1.Append(H1);
398 slineS2.Append(H1);
399 }
7fd59977 400 }
401 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
e618b526 402 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
403 break;
7fd59977 404
e618b526 405 //########################################
406 // Circle and Ellipse
407 //########################################
7fd59977 408 case IntPatch_Circle:
409 case IntPatch_Ellipse: {
410
411 if (typl == IntPatch_Circle) {
412 newc = new Geom_Circle
e618b526 413 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
7fd59977 414 }
415 else {
416 newc = new Geom_Ellipse
e618b526 417 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
7fd59977 418 }
419 //
96a95605 420 Standard_Real aPeriod, aRealEpsilon;
7fd59977 421 //
422 aRealEpsilon=RealEpsilon();
c6541a0c 423 aPeriod=M_PI+M_PI;
7fd59977 424 //
425 aNbParts=myLConstruct.NbParts();
426 //
427 for (i=1; i<=aNbParts; i++) {
428 myLConstruct.Part(i, fprm, lprm);
429 //
430 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
e618b526 431 //==============================================
432 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
433 //
434 sline.Append(aTC3D);
435 //
436 fprm=aTC3D->FirstParameter();
437 lprm=aTC3D->LastParameter ();
438 ////
439 if(myApprox1) {
440 Handle (Geom2d_Curve) C2d;
441 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
442 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
443 myTolReached2d=Tolpc;
444 }
445 slineS1.Append(C2d);
446 }
447 else { ////
448 slineS1.Append(H1);
449 }
450 //
451 if(myApprox2) {
452 Handle (Geom2d_Curve) C2d;
453 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
454 if(Tolpc>myTolReached2d || myTolReached2d==0) {
455 myTolReached2d=Tolpc;
456 }
457 slineS2.Append(C2d);
458 }
459 else {
460 slineS2.Append(H1);
461 }
462 //==============================================
c6541a0c 463 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
7fd59977 464 //
465 else {// on regarde si on garde
e618b526 466 //
467 if (aNbParts==1) {
468 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
469 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
470 //
471 sline.Append(aTC3D);
472 fprm=aTC3D->FirstParameter();
473 lprm=aTC3D->LastParameter ();
474
475 if(myApprox1) {
476 Handle (Geom2d_Curve) C2d;
477 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
478 if(Tolpc>myTolReached2d || myTolReached2d==0) {
479 myTolReached2d=Tolpc;
480 }
481 slineS1.Append(C2d);
482 }
483 else { ////
484 slineS1.Append(H1);
485 }
486
487 if(myApprox2) {
488 Handle (Geom2d_Curve) C2d;
489 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
490 if(Tolpc>myTolReached2d || myTolReached2d==0) {
491 myTolReached2d=Tolpc;
492 }
493 slineS2.Append(C2d);
494 }
495 else {
496 slineS2.Append(H1);
497 }
498 break;
499 }
500 }
501 //
502 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
503 //
504 aTwoPIdiv17=2.*M_PI/17.;
505 //
506 for (j=0; j<=17; j++) {
507 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
508 TolX = Precision::Confusion();
509
510 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
511 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
512 if(ok) {
513 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
514 }
515 if (ok) {
516 sline.Append(newc);
517 //==============================================
518 if(myApprox1) {
519 Handle (Geom2d_Curve) C2d;
520 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
521 if(Tolpc>myTolReached2d || myTolReached2d==0) {
522 myTolReached2d=Tolpc;
523 }
524 slineS1.Append(C2d);
525 }
526 else {
527 slineS1.Append(H1);
528 }
529
530 if(myApprox2) {
531 Handle (Geom2d_Curve) C2d;
532 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
533 if(Tolpc>myTolReached2d || myTolReached2d==0) {
534 myTolReached2d=Tolpc;
535 }
536 slineS2.Append(C2d);
537 }
538 else {
539 slineS2.Append(H1);
540 }
541 break;
542 }// end of if (ok) {
543 }// end of for (Standard_Integer j=0; j<=17; j++)
7fd59977 544 }// end of else { on regarde si on garde
545 }// for (i=1; i<=myLConstruct.NbParts(); i++)
e618b526 546 }// IntPatch_Circle: IntPatch_Ellipse
547 break;
548
549 //########################################
550 // Analytic
551 //########################################
e2e0498b 552 case IntPatch_Analytic:
553 //This case was processed earlier (in IntPatch_Intersection)
e618b526 554
e618b526 555 break;
556
4e14c88f 557 //########################################
558 // Walking
559 //########################################
7fd59977 560 case IntPatch_Walking:{
561 Handle(IntPatch_WLine) WL =
562 Handle(IntPatch_WLine)::DownCast(L);
4e14c88f 563
77dbd1f1 564#ifdef GEOMINT_INTSS_DEBUG
565 WL->Dump(0);
4e14c88f 566#endif
567
7fd59977 568 //
569 Standard_Integer ifprm, ilprm;
570 //
571 if (!myApprox) {
572 aNbParts=myLConstruct.NbParts();
573 for (i=1; i<=aNbParts; i++) {
e618b526 574 myLConstruct.Part(i, fprm, lprm);
575 ifprm=(Standard_Integer)fprm;
576 ilprm=(Standard_Integer)lprm;
577 //
578 Handle(Geom2d_BSplineCurve) aH1, aH2;
579
580 if(myApprox1) {
581 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
582 }
583 if(myApprox2) {
584 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
585 }
586 //
587 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
588 //
589 sline.Append(aBSp);
590 slineS1.Append(aH1);
591 slineS2.Append(aH2);
7fd59977 592 }
593 }
594 //
595 else {
596 Standard_Boolean bIsDecomposited;
597 Standard_Integer nbiter, aNbSeqOfL;
598 GeomInt_WLApprox theapp3d;
599 IntPatch_SequenceOfLine aSeqOfL;
600 Standard_Real tol2d, aTolSS;
601 //
602 tol2d = myTolApprox;
603 aTolSS=2.e-7;
4e14c88f 604 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2);
7fd59977 605 //
606 bIsDecomposited =
4e14c88f 607 GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
7fd59977 608 //
609 aNbParts=myLConstruct.NbParts();
610 aNbSeqOfL=aSeqOfL.Length();
611 //
612 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
613 //
614 for(i = 1; i <= nbiter; i++) {
e618b526 615 if(bIsDecomposited) {
616 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
617 ifprm = 1;
618 ilprm = WL->NbPnts();
619 }
620 else {
621 myLConstruct.Part(i, fprm, lprm);
622 ifprm = (Standard_Integer)fprm;
623 ilprm = (Standard_Integer)lprm;
624 }
625 //-- lbr :
626 //-- Si une des surfaces est un plan , on approxime en 2d
627 //-- sur cette surface et on remonte les points 2d en 3d.
628 GeomAbs_SurfaceType typs1, typs2;
629 typs1 = myHS1->Surface().GetType();
630 typs2 = myHS2->Surface().GetType();
631 //
632 if(typs1 == GeomAbs_Plane) {
633 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
634 Standard_True, myApprox2,
635 ifprm, ilprm);
636 }
637 else if(typs2 == GeomAbs_Plane) {
638 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
639 myApprox1,Standard_True,
640 ifprm, ilprm);
641 }
642 else {
643 //
644 if (myHS1 != myHS2){
645 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
646 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
647
4e14c88f 648 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
e618b526 649 //Standard_Boolean bUseSurfaces;
650 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
651 //if (bUseSurfaces) {
652 //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
653 //}
654 }
655 }
656 //
657 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
658 myApprox1,myApprox2,
659 ifprm, ilprm);
660 }
661
662 if (!theapp3d.IsDone()) {
663 //
664 Handle(Geom2d_BSplineCurve) aH1, aH2;
665 //
666 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
667 if(myApprox1) {
668 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
669 }
670 if(myApprox2) {
671 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
672 }
673 //
674 sline.Append(aBSp);
675 slineS1.Append(aH1);
676 slineS2.Append(aH2);
677 }//if (!theapp3d.IsDone())
678
679 else {
680 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
681 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
682 myTolReached2d = theapp3d.TolReached2d();
683 }
684 }
685 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
686 myTolReached3d = myTolReached2d;
687 }
688 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
689 myTolReached3d = theapp3d.TolReached3d();
690 }
691
692 Standard_Integer aNbMultiCurves, nbpoles;
693 //
694 aNbMultiCurves=theapp3d.NbMultiCurves();
695 for (j=1; j<=aNbMultiCurves; j++) {
696 if(typs1 == GeomAbs_Plane) {
697 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
698 nbpoles = mbspc.NbPoles();
699
700 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
701 TColgp_Array1OfPnt tpoles(1,nbpoles);
702
703 mbspc.Curve(1,tpoles2d);
704 const gp_Pln& Pln = myHS1->Surface().Plane();
705 //
706 Standard_Integer ik;
707 for(ik = 1; ik<= nbpoles; ik++) {
708 tpoles.SetValue(ik,
709 ElSLib::Value(tpoles2d.Value(ik).X(),
710 tpoles2d.Value(ik).Y(),
711 Pln));
712 }
713 //
714 Handle(Geom_BSplineCurve) BS =
715 new Geom_BSplineCurve(tpoles,
716 mbspc.Knots(),
717 mbspc.Multiplicities(),
718 mbspc.Degree());
719 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
720 Check.FixTangent(Standard_True, Standard_True);
721 //
722 sline.Append(BS);
723 //
724 if(myApprox1) {
725 Handle(Geom2d_BSplineCurve) BS1 =
726 new Geom2d_BSplineCurve(tpoles2d,
727 mbspc.Knots(),
728 mbspc.Multiplicities(),
729 mbspc.Degree());
730 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
731 Check1.FixTangent(Standard_True,Standard_True);
732 //
733 AdjustUPeriodic (aS1, BS1);
734 //
735 slineS1.Append(BS1);
736 }
737 else {
738 slineS1.Append(H1);
739 }
740
741 if(myApprox2) {
742 mbspc.Curve(2, tpoles2d);
743
744 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
745 mbspc.Knots(),
746 mbspc.Multiplicities(),
747 mbspc.Degree());
748 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
749 newCheck.FixTangent(Standard_True,Standard_True);
750 //
751 AdjustUPeriodic (aS2, BS2);
752 //
753 slineS2.Append(BS2);
754 }
755 else {
756 slineS2.Append(H1);
757 }
758 }//if(typs1 == GeomAbs_Plane)
759 //
760 else if(typs2 == GeomAbs_Plane) {
761 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
762 nbpoles = mbspc.NbPoles();
763
764 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
765 TColgp_Array1OfPnt tpoles(1,nbpoles);
766 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
767 const gp_Pln& Pln = myHS2->Surface().Plane();
768 //
769 Standard_Integer ik;
770 for(ik = 1; ik<= nbpoles; ik++) {
771 tpoles.SetValue(ik,
772 ElSLib::Value(tpoles2d.Value(ik).X(),
773 tpoles2d.Value(ik).Y(),
774 Pln));
775
776 }
777 //
778 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
779 mbspc.Knots(),
780 mbspc.Multiplicities(),
781 mbspc.Degree());
782 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
783 Check.FixTangent(Standard_True,Standard_True);
784 //
785 sline.Append(BS);
786 //
787 if(myApprox2) {
788 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
789 mbspc.Knots(),
790 mbspc.Multiplicities(),
791 mbspc.Degree());
792 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
793 Check1.FixTangent(Standard_True,Standard_True);
794 //
795 //
796 AdjustUPeriodic (aS2, BS1);
797 //
798 slineS2.Append(BS1);
799 }
800 else {
801 slineS2.Append(H1);
802 }
803
804 if(myApprox1) {
805 mbspc.Curve(1,tpoles2d);
806 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
807 mbspc.Knots(),
808 mbspc.Multiplicities(),
809 mbspc.Degree());
810 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
811 Check2.FixTangent(Standard_True,Standard_True);
812 //
813 //
814 AdjustUPeriodic (aS1, BS2);
815 //
816 slineS1.Append(BS2);
817 }
818 else {
819 slineS1.Append(H1);
820 }
821 } // else if(typs2 == GeomAbs_Plane)
822 //
823 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
824 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
825 nbpoles = mbspc.NbPoles();
826 TColgp_Array1OfPnt tpoles(1,nbpoles);
827 mbspc.Curve(1,tpoles);
828 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
829 mbspc.Knots(),
830 mbspc.Multiplicities(),
831 mbspc.Degree());
832 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
833 Check.FixTangent(Standard_True,Standard_True);
834 //
835 //Check IsClosed()
836 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
837 BS->EndPoint().XYZ().SquareModulus());
838 Standard_Real eps = Epsilon(aDist);
94f71cad 839 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
e618b526 840 {
94f71cad 841 // Avoid creating B-splines containing two coincident poles only
842 if (mbspc.Degree() == 1 && nbpoles == 2)
843 continue;
844
845 if (!BS->IsClosed() && !BS->IsPeriodic())
846 {
847 //force Closed()
848 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
849 BS->SetPole(1, aPm);
850 BS->SetPole(BS->NbPoles(), aPm);
851 }
e618b526 852 }
853 sline.Append(BS);
854
855 if(myApprox1) {
856 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
857 mbspc.Curve(2,tpoles2d);
858 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
859 mbspc.Knots(),
860 mbspc.Multiplicities(),
861 mbspc.Degree());
862 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
863 newCheck.FixTangent(Standard_True,Standard_True);
864 //
865 AdjustUPeriodic (aS1, BS1);
866 //
867 slineS1.Append(BS1);
868 }
869 else {
870 slineS1.Append(H1);
871 }
872 if(myApprox2) {
873 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
874 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
875 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
876 mbspc.Knots(),
877 mbspc.Multiplicities(),
878 mbspc.Degree());
879 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
880 newCheck.FixTangent(Standard_True,Standard_True);
881 //
882 AdjustUPeriodic (aS2, BS2);
883 //
884 slineS2.Append(BS2);
885 }
886 else {
887 slineS2.Append(H1);
888 }
889 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
890 }// for (j=1; j<=aNbMultiCurves; j++
7c4e9501 891 }
7fd59977 892 }
893 }
894 }
e618b526 895 break;
896
7fd59977 897 case IntPatch_Restriction:
e618b526 898 {
d4b867e6 899 Handle(IntPatch_RLine) RL =
900 Handle(IntPatch_RLine)::DownCast(L);
901 Handle(Geom_Curve) aC3d;
902 Handle(Geom2d_Curve) aC2d1, aC2d2;
903 Standard_Real aTolReached;
904 TreatRLine(RL, myHS1, myHS2, aC3d,
905 aC2d1, aC2d2, aTolReached);
906
907 if(aC3d.IsNull())
908 break;
909
910 Bnd_Box2d aBox1, aBox2;
911
912 const Standard_Real aU1f = myHS1->FirstUParameter(),
913 aV1f = myHS1->FirstVParameter(),
914 aU1l = myHS1->LastUParameter(),
915 aV1l = myHS1->LastVParameter();
916 const Standard_Real aU2f = myHS2->FirstUParameter(),
917 aV2f = myHS2->FirstVParameter(),
918 aU2l = myHS2->LastUParameter(),
919 aV2l = myHS2->LastVParameter();
920
921 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
922 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
923 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
924 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
925
926 GeomInt_VectorOfReal anArrayOfParameters;
927
928 //We consider here that the intersection line is same-parameter-line
929 anArrayOfParameters.Append(aC3d->FirstParameter());
930 anArrayOfParameters.Append(aC3d->LastParameter());
931
932 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
933
934 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
935
936 //Trim RLine found.
937 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
e618b526 938 {
d4b867e6 939 const Standard_Real aParF = anArrayOfParameters(anInd),
940 aParL = anArrayOfParameters(anInd+1);
941
942 if((aParL - aParF) <= Precision::PConfusion())
943 continue;
944
945 const Standard_Real aPar = 0.5*(aParF + aParL);
946 gp_Pnt2d aPt;
947
948 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
949 if(!aC2d1.IsNull())
950 {
951 aC2d1->D0(aPar, aPt);
952
953 if(aBox1.IsOut(aPt))
954 continue;
955
956 if(myApprox1)
957 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
958 }
959
960 if(!aC2d2.IsNull())
961 {
962 aC2d2->D0(aPar, aPt);
963
964 if(aBox2.IsOut(aPt))
965 continue;
966
967 if(myApprox2)
968 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
969 }
970
971 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
972
973 sline.Append(aCurv3d);
974 slineS1.Append(aCurv2d1);
975 slineS2.Append(aCurv2d2);
e618b526 976 }
977 }
7fd59977 978 break;
7fd59977 979 }
980}
4e14c88f 981
7fd59977 982//=======================================================================
4e14c88f 983//function : TreatRLine
984//purpose : Approx of Restriction line
7fd59977 985//=======================================================================
4e14c88f 986void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
987 const Handle(GeomAdaptor_HSurface)& theHS1,
988 const Handle(GeomAdaptor_HSurface)& theHS2,
989 Handle(Geom_Curve)& theC3d,
990 Handle(Geom2d_Curve)& theC2d1,
991 Handle(Geom2d_Curve)& theC2d2,
992 Standard_Real& theTolReached)
7fd59977 993{
4e14c88f 994 Handle(GeomAdaptor_HSurface) aGAHS;
995 Handle(Adaptor2d_HCurve2d) anAHC2d;
996 Standard_Real tf, tl;
997 gp_Lin2d aL;
998 // It is assumed that 2d curve is 2d line (rectangular surface domain)
999 if(theRL->IsArcOnS1())
1000 {
1001 aGAHS = theHS1;
1002 anAHC2d = theRL->ArcOnS1();
1003 theRL->ParamOnS1(tf, tl);
1004 theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
1005 tf = Max(tf, theC2d1->FirstParameter());
1006 tl = Min(tl, theC2d1->LastParameter());
1007 theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl);
7fd59977 1008 }
4e14c88f 1009 else if (theRL->IsArcOnS2())
7fd59977 1010 {
4e14c88f 1011 aGAHS = theHS2;
1012 anAHC2d = theRL->ArcOnS2();
1013 theRL->ParamOnS2(tf, tl);
1014 theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
1015 tf = Max(tf, theC2d2->FirstParameter());
1016 tl = Min(tl, theC2d2->LastParameter());
1017 theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl);
d4b867e6 1018 }
1019 else
1020 {
1021 return;
1022 }
b55bd023 1023
1024 //Restriction line can correspond to a degenerated edge.
1025 //In this case we return null-curve.
1026 if(isDegenerated(aGAHS, anAHC2d, tf, tl))
1027 return;
1028
d4b867e6 1029 //
1030 //To provide sameparameter it is necessary to get 3d curve as
1031 //approximation of curve on surface.
1032 Standard_Integer aMaxDeg = 8;
1033 Standard_Integer aMaxSeg = 1000;
f04de133 1034 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion());
1035 anApp.Perform(aMaxSeg, aMaxDeg, GeomAbs_C1, Standard_True, Standard_False);
d4b867e6 1036 if(!anApp.HasResult())
1037 return;
1038
1039 theC3d = anApp.Curve3d();
1040 theTolReached = anApp.MaxError3d();
1041 Standard_Real aTol = Precision::Confusion();
1042 if(theRL->IsArcOnS1())
1043 {
1044 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
1045 BuildPCurves (tf, tl, aTol,
1046 aS, theC3d, theC2d2);
1047 }
1048 if(theRL->IsArcOnS2())
1049 {
1050 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
1051 BuildPCurves (tf, tl, aTol,
1052 aS, theC3d, theC2d1);
1053 }
1054 theTolReached = Max(theTolReached, aTol);
1055}
1056
1057//=======================================================================
1058//function : BuildPCurves
7fd59977 1059//purpose :
1060//=======================================================================
d4b867e6 1061void GeomInt_IntSS::BuildPCurves (Standard_Real f,
1062 Standard_Real l,
1063 Standard_Real& Tol,
1064 const Handle (Geom_Surface)& S,
1065 const Handle (Geom_Curve)& C,
1066 Handle (Geom2d_Curve)& C2d)
7fd59977 1067{
d4b867e6 1068 if (!C2d.IsNull()) {
1069 return;
1070 }
1071 //
1072 Standard_Real umin,umax,vmin,vmax;
1073 //
1074 S->Bounds(umin, umax, vmin, vmax);
1075 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
1076 if((l - f) > 2.e-09) {
1077 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
d4b867e6 1078 if (C2d.IsNull()) {
1079 // proj. a circle that goes through the pole on a sphere to the sphere
1080 Tol += Precision::Confusion();
1081 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
1082 }
8f8398f6 1083 const Handle(Standard_Type)& aType = C2d->DynamicType();
1084 if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve))
1085 {
1086 //Check first, last knots to avoid problems with trimming
1087 //First, last knots can differ from f, l because of numerical error
1088 //of projection and approximation
1089 //The same checking as in Geom2d_TrimmedCurve
1090 if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
1091 (l - C2d->LastParameter() > Precision::PConfusion()))
1092 {
1093 Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1094 TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
1095 aBspl->Knots(aKnots);
1096 BSplCLib::Reparametrize(f, l, aKnots);
1097 aBspl->SetKnots(aKnots);
1098 }
1099 }
d4b867e6 1100 }
1101 else {
7a91ad6e 1102 if((l - f) > Epsilon(Abs(f)))
1103 {
1104 //The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
1105 //On this small range C2d can be considered as segment
1106 //of line.
1107
1108 Standard_Real aU=0., aV=0.;
1109 GeomAdaptor_Surface anAS;
1110 anAS.Load(S);
1111 Extrema_ExtPS anExtr;
1112 const gp_Pnt aP3d1 = C->Value(f);
1113 const gp_Pnt aP3d2 = C->Value(l);
1114
1115 anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
1116 anExtr.Initialize(anAS, umin, umax, vmin, vmax,
1117 Precision::Confusion(), Precision::Confusion());
1118 anExtr.Perform(aP3d1);
1119
1120 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1121 {
1122 const gp_Pnt2d aP2d1(aU, aV);
1123
1124 anExtr.Perform(aP3d2);
1125
1126 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1127 {
1128 const gp_Pnt2d aP2d2(aU, aV);
1129
1130 if(aP2d1.Distance(aP2d2) > gp::Resolution())
1131 {
1132 TColgp_Array1OfPnt2d poles(1,2);
1133 TColStd_Array1OfReal knots(1,2);
1134 TColStd_Array1OfInteger mults(1,2);
1135 poles(1) = aP2d1;
1136 poles(2) = aP2d2;
1137 knots(1) = f;
1138 knots(2) = l;
1139 mults(1) = mults(2) = 2;
1140
1141 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
1142
1143 //Check same parameter in middle point .begin
1144 const gp_Pnt PMid(C->Value(0.5*(f+l)));
1145 const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
1146 const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
1147 const Standard_Real aDist = PMid.Distance(aPC);
1148 Tol = Max(aDist, Tol);
1149 //Check same parameter in middle point .end
d4b867e6 1150 }
d4b867e6 1151 }
1152 }
1153 }
1154 }
7fd59977 1155 //
d4b867e6 1156 if (S->IsUPeriodic() && !C2d.IsNull()) {
1157 // Recadre dans le domaine UV de la face
1158 Standard_Real aTm, U0, aEps, period, du, U0x;
1159 Standard_Boolean bAdjust;
1160 //
1161 aEps = Precision::PConfusion();
1162 period = S->UPeriod();
1163 //
1164 aTm = .5*(f + l);
1165 gp_Pnt2d pm = C2d->Value(aTm);
1166 U0 = pm.X();
1167 //
1168 bAdjust =
1169 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
1170 if (bAdjust) {
1171 gp_Vec2d T1(du, 0.);
1172 C2d->Translate(T1);
1173 }
1174 }
1175}
1176
1177//=======================================================================
1178//function : TrimILineOnSurfBoundaries
1179//purpose : This function finds intersection points of given curves with
1180// surface boundaries and fills theArrayOfParameters by parameters
1181// along the given curves corresponding of these points.
1182//=======================================================================
1183void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
1184 const Handle(Geom2d_Curve)& theC2d2,
1185 const Bnd_Box2d& theBound1,
1186 const Bnd_Box2d& theBound2,
1187 GeomInt_VectorOfReal& theArrayOfParameters)
1188{
1189 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
1190 // [2]:V=Vfirst, [3]:V=Vlast
1191 const Standard_Integer aNumberOfCurves = 4;
1192 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
1193 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
1194
1195 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
1196 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
1197
1198 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
1199 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
1200
1201 Standard_Real aDelta = aV1l-aV1f;
1202 if(Abs(aDelta) > RealSmall())
1203 {
1204 if(!Precision::IsInfinite(aU1f))
1205 {
1206 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
1207
1208 if(!Precision::IsInfinite(aDelta))
1209 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
1210 }
1211
1212 if(!Precision::IsInfinite(aU1l))
1213 {
1214 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
1215 if(!Precision::IsInfinite(aDelta))
1216 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
1217 }
1218 }
1219
1220 aDelta = aU1l-aU1f;
1221 if(Abs(aDelta) > RealSmall())
1222 {
1223 if(!Precision::IsInfinite(aV1f))
1224 {
1225 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
1226 if(!Precision::IsInfinite(aDelta))
1227 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
1228 }
1229
1230 if(!Precision::IsInfinite(aV1l))
1231 {
1232 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
1233 if(!Precision::IsInfinite(aDelta))
1234 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
1235 }
1236 }
1237
1238 aDelta = aV2l-aV2f;
1239 if(Abs(aDelta) > RealSmall())
1240 {
1241 if(!Precision::IsInfinite(aU2f))
1242 {
1243 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
1244 if(!Precision::IsInfinite(aDelta))
1245 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
1246 }
1247
1248 if(!Precision::IsInfinite(aU2l))
1249 {
1250 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
1251 if(!Precision::IsInfinite(aDelta))
1252 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
1253 }
1254 }
1255
1256 aDelta = aU2l-aU2f;
1257 if(Abs(aDelta) > RealSmall())
1258 {
1259 if(!Precision::IsInfinite(aV2f))
1260 {
1261 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
1262 if(!Precision::IsInfinite(aDelta))
1263 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
1264 }
1265
1266 if(!Precision::IsInfinite(aV2l))
1267 {
1268 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
1269 if(!Precision::IsInfinite(aDelta))
1270 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
1271 }
1272 }
1273
7a91ad6e 1274 const Standard_Real anIntTol = 10.0*Precision::Confusion();
d4b867e6 1275
7a91ad6e 1276 IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
1277 aNumberOfCurves, anIntTol, theArrayOfParameters);
d4b867e6 1278
7a91ad6e 1279 IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
1280 aNumberOfCurves, anIntTol, theArrayOfParameters);
d4b867e6 1281
1282 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());
7fd59977 1283}
4e14c88f 1284
1285//=======================================================================
1286//function : MakeBSpline
1287//purpose :
1288//=======================================================================
1289Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline (const Handle(IntPatch_WLine)& WL,
1290 const Standard_Integer ideb,
1291 const Standard_Integer ifin)
1292{
1293 const Standard_Integer nbpnt = ifin-ideb+1;
1294 TColgp_Array1OfPnt poles(1,nbpnt);
1295 TColStd_Array1OfReal knots(1,nbpnt);
1296 TColStd_Array1OfInteger mults(1,nbpnt);
1297 Standard_Integer i = 1, ipidebm1 = ideb;
1298 for(; i<=nbpnt; ipidebm1++, i++)
1299 {
1300 poles(i) = WL->Point(ipidebm1).Value();
1301 mults(i) = 1;
1302 knots(i) = i-1;
1303 }
1304 mults(1) = mults(nbpnt) = 2;
1305 return new Geom_BSplineCurve(poles,knots,mults,1);
1306}
1307
1308//=======================================================================
1309//function : MakeBSpline2d
1310//purpose :
1311//=======================================================================
1312Handle(Geom2d_BSplineCurve) GeomInt_IntSS::
1313 MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1314 const Standard_Integer ideb,
1315 const Standard_Integer ifin,
1316 const Standard_Boolean onFirst)
1317{
1318 const Standard_Integer nbpnt = ifin-ideb+1;
1319 TColgp_Array1OfPnt2d poles(1,nbpnt);
1320 TColStd_Array1OfReal knots(1,nbpnt);
1321 TColStd_Array1OfInteger mults(1,nbpnt);
1322 Standard_Integer i = 1, ipidebm1 = ideb;
1323 for(; i <= nbpnt; ipidebm1++, i++)
1324 {
1325 Standard_Real U, V;
1326 if(onFirst)
1327 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1328 else
1329 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1330 poles(i).SetCoord(U, V);
1331 mults(i) = 1;
1332 knots(i) = i-1;
1333 }
1334
1335 mults(1) = mults(nbpnt) = 2;
1336 return new Geom2d_BSplineCurve(poles,knots,mults,1);
1337}