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