180ec90fc8f1907e901b4b0a99331fbbaa3ad7a0
[occt.git] / src / IntPatch / IntPatch_ImpPrmIntersection.cxx
1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-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 <IntPatch_ImpPrmIntersection.hxx>
18
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <ElCLib.hxx>
22 #include <IntPatch_ArcFunction.hxx>
23 #include <IntPatch_PointLine.hxx>
24 #include <IntPatch_RLine.hxx>
25 #include <IntPatch_RstInt.hxx>
26 #include <IntPatch_SpecialPoints.hxx>
27 #include <IntPatch_TheIWLineOfTheIWalking.hxx>
28 #include <IntPatch_TheIWalking.hxx>
29 #include <IntPatch_TheSurfFunction.hxx>
30 #include <IntPatch_WLine.hxx>
31 #include <IntSurf.hxx>
32 #include <IntSurf_Quadric.hxx>
33 #include <IntSurf_QuadricTool.hxx>
34 #include <IntSurf_SequenceOfPathPoint.hxx>
35 #include <TopAbs_Orientation.hxx>
36 #include <TopTrans_CurveTransition.hxx>
37 #include <math_Matrix.hxx>
38 #include <math_Vector.hxx>
39
40 #ifndef OCCT_DEBUG
41 #define No_Standard_RangeError
42 #define No_Standard_OutOfRange
43 #endif
44
45 static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
46                                         const Standard_Boolean       IsReversed,
47                                         const IntSurf_Quadric&       theQuad,
48                                         const Handle(Adaptor3d_TopolTool)& thePDomain,
49                                         const Handle(Adaptor3d_HSurface)&  theQSurf,
50                                         const Handle(Adaptor3d_HSurface)&  theOtherSurf,
51                                         const Standard_Real                theArcTol,
52                                         const Standard_Real                theTolTang,
53                                         IntPatch_SequenceOfLine&           theLines);
54 static 
55   void ComputeTangency (const IntPatch_TheSOnBounds& solrst,
56   IntSurf_SequenceOfPathPoint& seqpdep,
57   const Handle(Adaptor3d_TopolTool)& Domain,
58   IntPatch_TheSurfFunction& Func,
59   const Handle(Adaptor3d_HSurface)& PSurf,
60   TColStd_Array1OfInteger& Destination);
61 static 
62   void Recadre(const Standard_Boolean ,
63   GeomAbs_SurfaceType typeS1,
64   GeomAbs_SurfaceType typeS2,
65   IntPatch_Point&  pt,
66   const Handle(IntPatch_TheIWLineOfTheIWalking)& iwline,
67   Standard_Integer Param,
68   Standard_Real U1,
69   Standard_Real V1,
70   Standard_Real U2,
71   Standard_Real V2);
72
73 static 
74   Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
75                               const Handle(IntPatch_PointLine)& theLine,
76                               const Handle(Adaptor2d_HCurve2d)& theArc,
77                               const Standard_Boolean isTheSurface1Using,
78                               const Standard_Real theToler3D,
79                               const Standard_Real theToler2D,
80                               const Standard_Real thePeriod);
81
82 //=======================================================================
83 //function : IsSeamOrPole
84 //purpose  : 
85 //=======================================================================
86 static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQSurf,
87                                          const Handle(IntSurf_LineOn2S)& theLine,
88                                          const Standard_Boolean IsReversed,
89                                          const Standard_Integer theRefIndex,
90                                          const Standard_Real theDeltaMax)
91 {
92   if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
93     return IntPatch_SPntNone;
94
95   //Parameters on Quadric and on parametric for reference point
96   Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
97   Standard_Real aUQNext, aVQNext, aUPNext, aVPNext;
98
99   if(IsReversed)
100   {
101     theLine->Value(theRefIndex).Parameters  (aUPRef, aVPRef, aUQRef, aVQRef);
102     theLine->Value(theRefIndex+1).Parameters(aUPNext, aVPNext, aUQNext, aVQNext);
103   }
104   else
105   {
106     theLine->Value(theRefIndex).Parameters  (aUQRef, aVQRef, aUPRef, aVPRef);
107     theLine->Value(theRefIndex+1).Parameters(aUQNext, aVQNext, aUPNext, aVPNext);
108   }
109
110   const GeomAbs_SurfaceType aType = theQSurf->GetType();
111
112   const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
113
114   if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
115     return IntPatch_SPntNone;
116
117   switch(aType)
118   {
119   case GeomAbs_Cylinder:
120     return IntPatch_SPntSeamU;
121
122   case GeomAbs_Torus:
123     {
124       const Standard_Real aDeltaV = Abs(aVQRef - aVQNext);
125
126       if((aDeltaU >= theDeltaMax) && (aDeltaV >= theDeltaMax))
127         return IntPatch_SPntSeamUV;
128
129       if(aDeltaU >= theDeltaMax)
130         return IntPatch_SPntSeamU;
131
132       if(aDeltaV >= theDeltaMax)
133         return IntPatch_SPntSeamV;
134     }
135
136     break;
137   case GeomAbs_Sphere:
138   case GeomAbs_Cone:
139     return IntPatch_SPntPoleSeamU;
140   default:
141     break;
142   }
143
144   return IntPatch_SPntNone;
145 }
146
147 //=======================================================================
148 //function : IntPatch_ImpPrmIntersection
149 //purpose  : 
150 //=======================================================================
151 IntPatch_ImpPrmIntersection::IntPatch_ImpPrmIntersection ()
152   : done(Standard_False),
153   empt(Standard_False),
154   myIsStartPnt(Standard_False),
155   myUStart(0.0),
156   myVStart(0.0)
157 { }
158
159
160 //=======================================================================
161 //function : IntPatch_ImpPrmIntersection
162 //purpose  : 
163 //=======================================================================
164
165 IntPatch_ImpPrmIntersection::IntPatch_ImpPrmIntersection
166   (const Handle(Adaptor3d_HSurface)&    Surf1,
167   const Handle(Adaptor3d_TopolTool)&   D1,
168   const Handle(Adaptor3d_HSurface)&    Surf2,
169   const Handle(Adaptor3d_TopolTool)&   D2,
170   const Standard_Real    TolArc,
171   const Standard_Real    TolTang,
172   const Standard_Real    Fleche,
173   const Standard_Real    Pas)
174   : done(Standard_False),
175   empt(Standard_False),
176   myIsStartPnt(Standard_False),
177   myUStart(0.0),
178   myVStart(0.0)
179 {
180   Perform(Surf1,D1,Surf2,D2,TolArc,TolTang,Fleche,Pas);
181 }
182
183
184 //=======================================================================
185 //function : SetStartPoint
186 //purpose  : 
187 //=======================================================================
188
189 void IntPatch_ImpPrmIntersection::SetStartPoint(const Standard_Real U,
190   const Standard_Real V)
191 {
192   myIsStartPnt = Standard_True;
193   myUStart = U; myVStart = V;
194 }
195
196 //=======================================================================
197 //function : ComputeTangency
198 //purpose  : 
199 //=======================================================================
200 void ComputeTangency (const IntPatch_TheSOnBounds& solrst,
201   IntSurf_SequenceOfPathPoint& seqpdep,
202   const Handle(Adaptor3d_TopolTool)& Domain,
203   IntPatch_TheSurfFunction& Func,
204   const Handle(Adaptor3d_HSurface)& PSurf,
205   TColStd_Array1OfInteger& Destination)
206 {
207   Standard_Integer i,k, NbPoints, seqlength;
208   Standard_Real theparam,test;
209   Standard_Boolean fairpt, ispassing;
210   TopAbs_Orientation arcorien,vtxorien;
211   Handle(Adaptor2d_HCurve2d) thearc;
212   Handle(Adaptor3d_HVertex) vtx,vtxbis;
213   //Standard_Boolean ispassing;
214   IntPatch_ThePathPointOfTheSOnBounds PStart;
215   IntSurf_PathPoint PPoint;
216   gp_Vec vectg;
217   gp_Dir2d dirtg;
218   gp_Pnt ptbid;
219   gp_Vec d1u,d1v,v1,v2;
220   gp_Pnt2d p2d;
221   gp_Vec2d d2d;
222   //
223   double aX[2], aF[1], aD[1][2];
224   math_Vector X(aX, 1, 2);
225   math_Vector F(aF, 1, 1);
226   math_Matrix D(aD, 1, 1, 1, 2); 
227   //
228   seqlength = 0;
229   NbPoints = solrst.NbPoints();
230   for (i=1; i<= NbPoints; i++) {
231     if (Destination(i) == 0) {
232       PStart = solrst.Point(i);
233       thearc   = PStart.Arc();
234       theparam = PStart.Parameter();
235       arcorien = Domain->Orientation(thearc);
236       ispassing = (arcorien == TopAbs_INTERNAL || 
237         arcorien == TopAbs_EXTERNAL);
238
239       thearc->D0(theparam,p2d);
240       X(1) = p2d.X(); 
241       X(2) = p2d.Y();
242       PPoint.SetValue(PStart.Value(),X(1),X(2));
243
244       Func.Values(X,F,D);
245       if (Func.IsTangent()) {
246         PPoint.SetTangency(Standard_True);
247         Destination(i) = seqlength+1;
248         if (!PStart.IsNew()) {
249           vtx = PStart.Vertex();
250           for (k=i+1; k<=NbPoints; k++) {
251             if (Destination(k) ==0) {
252               PStart = solrst.Point(k);
253               if (!PStart.IsNew()) {
254                 vtxbis = PStart.Vertex();
255                 if (Domain->Identical(vtx,vtxbis)) {
256                   thearc   = PStart.Arc();
257                   theparam = PStart.Parameter();
258                   arcorien = Domain->Orientation(thearc);
259                   ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
260                     arcorien == TopAbs_EXTERNAL);
261
262                   thearc->D0(theparam,p2d);
263                   PPoint.AddUV(p2d.X(),p2d.Y());
264                   Destination(k) = seqlength+1;
265                 }
266               }
267             }
268           }
269         }
270         PPoint.SetPassing(ispassing);
271         seqpdep.Append(PPoint);
272         seqlength++;
273       }
274       else { // on a un point de depart potentiel
275
276         vectg = Func.Direction3d();
277         dirtg = Func.Direction2d();
278
279         PSurf->D1(X(1),X(2),ptbid,d1u,d1v);
280         thearc->D1(theparam,p2d,d2d);
281         v2.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
282         v1 = d1u.Crossed(d1v);
283
284         test = vectg.Dot(v1.Crossed(v2));
285         if (PStart.IsNew()) {
286           if ((test < 0. && arcorien == TopAbs_FORWARD) ||
287             (test > 0. && arcorien == TopAbs_REVERSED)) {
288               vectg.Reverse();
289               dirtg.Reverse();
290           }
291           PPoint.SetDirections(vectg,dirtg);
292           PPoint.SetPassing(ispassing);
293           Destination(i) = seqlength+1;
294           seqpdep.Append(PPoint);
295           seqlength++;
296         }
297         else { // traiter la transition complexe
298           gp_Dir bidnorm(1.,1.,1.);
299           Standard_Real tole = 1.e-8;
300           TopAbs_Orientation LocTrans;
301           TopTrans_CurveTransition comptrans;
302           comptrans.Reset(vectg,bidnorm,0.);
303           if (arcorien == TopAbs_FORWARD || 
304             arcorien == TopAbs_REVERSED) {
305               // pour essai
306
307               vtx = PStart.Vertex();
308               vtxorien = Domain->Orientation(vtx);
309               if (Abs(test) <= tole) {
310                 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
311               }
312               else {
313                 if (((test > 0.)&& arcorien == TopAbs_FORWARD) ||
314                   ((test < 0.)&& arcorien == TopAbs_REVERSED)){
315                     LocTrans = TopAbs_FORWARD;
316                 }
317                 else {
318                   LocTrans = TopAbs_REVERSED;
319                 }
320                 if (arcorien == TopAbs_REVERSED) {v2.Reverse();}
321               }
322
323               comptrans.Compare(tole,v2,bidnorm,0.,LocTrans,vtxorien);
324           }
325           Destination(i) = seqlength+1;
326           for (k= i+1; k<=NbPoints; k++) {
327             if (Destination(k) == 0) {
328               PStart = solrst.Point(k);
329               if (!PStart.IsNew()) {
330                 vtxbis = PStart.Vertex();
331                 if (Domain->Identical(vtx,vtxbis)) {
332                   thearc   = PStart.Arc();
333                   theparam = PStart.Parameter();
334                   arcorien = Domain->Orientation(thearc);
335
336                   PPoint.AddUV(X(1),X(2));
337
338                   thearc->D1(theparam,p2d,d2d);
339                   PPoint.AddUV(p2d.X(),p2d.Y());
340
341                   if (arcorien == TopAbs_FORWARD || 
342                     arcorien == TopAbs_REVERSED) {
343                       ispassing = Standard_False;
344                       v2.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
345
346                       test = vectg.Dot(v1.Crossed(v2));
347                       vtxorien = Domain->Orientation(PStart.Vertex());
348                       if (Abs(test) <= tole) {
349                         LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
350                       }
351                       else {
352                         if (((test > 0.)&& arcorien == TopAbs_FORWARD) ||
353                           ((test < 0.)&& arcorien == TopAbs_REVERSED)){
354                             LocTrans = TopAbs_FORWARD;
355                         }
356                         else {
357                           LocTrans = TopAbs_REVERSED;
358                         }
359                         if (arcorien == TopAbs_REVERSED) {v2.Reverse();}
360                       }
361
362                       comptrans.Compare(tole,v2,bidnorm,0.,LocTrans,vtxorien);
363                   }
364                   Destination(k) = seqlength+1;
365                 }
366               }
367             }
368           }
369           fairpt = Standard_True;
370           if (!ispassing) {
371             TopAbs_State Before = comptrans.StateBefore();
372             TopAbs_State After  = comptrans.StateAfter();
373             if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
374               fairpt = Standard_False;
375             }
376             else if (Before == TopAbs_IN) {
377               if (After == TopAbs_IN) {
378                 ispassing = Standard_True;
379               }
380               else {
381                 vectg.Reverse();
382                 dirtg.Reverse();
383               }
384             }
385             else {
386               if (After !=TopAbs_IN) {
387                 fairpt = Standard_False;
388               }
389             }
390           }
391           if (fairpt) {
392             PPoint.SetDirections(vectg,dirtg);
393             PPoint.SetPassing(ispassing);
394             seqpdep.Append(PPoint);
395             seqlength++;
396           }
397           else { // il faut remettre en "ordre" si on ne garde pas le point.
398             for (k=i; k <=NbPoints ; k++) {
399               if (Destination(k)==seqlength + 1) {
400                 Destination(k) = -Destination(k);
401               }
402             }
403           }
404         }
405       }
406     }
407   }
408 }
409 //=======================================================================
410 //function : Recadre
411 //purpose  : 
412 //=======================================================================
413 void Recadre(const Standard_Boolean ,
414   GeomAbs_SurfaceType typeS1,
415   GeomAbs_SurfaceType typeS2,
416   IntPatch_Point&  pt,
417   const Handle(IntPatch_TheIWLineOfTheIWalking)& iwline,
418   Standard_Integer Param,
419   Standard_Real U1,
420   Standard_Real V1,
421   Standard_Real U2,
422   Standard_Real V2)
423 {
424   Standard_Real U1p,V1p,U2p,V2p;
425   iwline->Line()->Value(Param).Parameters(U1p,V1p,U2p,V2p);
426   switch(typeS1)
427   {
428   case GeomAbs_Torus:
429     while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
430     while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
431     Standard_FALLTHROUGH
432   case GeomAbs_Cylinder:
433   case GeomAbs_Cone:
434   case GeomAbs_Sphere:
435     while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
436     while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
437   default:
438     break;
439   }
440   switch(typeS2)
441   { 
442   case GeomAbs_Torus:
443     while(V2<(V2p-1.5*M_PI)) V2+=M_PI+M_PI;
444     while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
445     Standard_FALLTHROUGH
446   case GeomAbs_Cylinder:
447   case GeomAbs_Cone:
448   case GeomAbs_Sphere:
449     while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
450     while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
451   default:
452     break;
453   }
454   pt.SetParameters(U1,V1,U2,V2);
455 }
456
457 //=======================================================================
458 //function : Perform
459 //purpose  : 
460 //=======================================================================
461 void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1,
462   const Handle(Adaptor3d_TopolTool)& D1,
463   const Handle(Adaptor3d_HSurface)& Surf2,
464   const Handle(Adaptor3d_TopolTool)& D2,
465   const Standard_Real TolArc,
466   const Standard_Real TolTang,
467   const Standard_Real Fleche,
468   const Standard_Real Pas)
469 {
470   Standard_Boolean reversed, procf, procl, dofirst, dolast;
471   Standard_Integer indfirst = 0, indlast = 0, ind2, NbSegm;
472   Standard_Integer NbPointIns, NbPointRst, Nblines, Nbpts, NbPointDep;
473   Standard_Real U1,V1,U2,V2,paramf,paraml,currentparam;
474
475   IntPatch_TheSegmentOfTheSOnBounds thesegm;
476   IntSurf_PathPoint PPoint;
477
478   Handle(IntPatch_RLine) rline;
479   Handle(IntPatch_WLine) wline;
480   IntPatch_ThePathPointOfTheSOnBounds PStart,PStartf,PStartl;
481   IntPatch_Point ptdeb,ptfin,ptbis;
482
483   IntPatch_IType typ;
484   IntSurf_Transition TLine,TArc;
485   IntSurf_TypeTrans trans1,trans2;
486   gp_Pnt valpt,ptbid;
487   gp_Vec tgline,tgrst,norm1,norm2,d1u,d1v;
488   gp_Dir DirNormale;
489   gp_Vec VecNormale;
490
491   gp_Pnt2d p2d;
492   gp_Vec2d d2d;
493
494   Handle(Adaptor2d_HCurve2d) currentarc;
495   GeomAbs_SurfaceType typeS1, typeS2;
496   IntSurf_Quadric Quad;
497   IntPatch_TheSurfFunction Func;
498   IntPatch_ArcFunction AFunc;
499   //
500   typeS1 = Surf1->GetType();
501   typeS2 = Surf2->GetType();
502
503   paramf =0.;
504   paraml =0.;
505   trans1 = IntSurf_Undecided;
506   trans2 = IntSurf_Undecided;
507   //
508   done = Standard_False;
509   empt = Standard_True;
510   slin.Clear();
511   spnt.Clear();
512   //
513   reversed = Standard_False;
514   switch (typeS1)
515   {
516   case GeomAbs_Plane:
517     Quad.SetValue(Surf1->Plane());
518     break;
519
520   case GeomAbs_Cylinder:
521     Quad.SetValue(Surf1->Cylinder());
522     break;
523
524   case GeomAbs_Sphere:
525     Quad.SetValue(Surf1->Sphere());
526     break;
527
528   case GeomAbs_Cone:
529     Quad.SetValue(Surf1->Cone());
530     break;
531
532   default:
533     {
534       reversed = Standard_True;
535       switch (typeS2)
536       {
537       case GeomAbs_Plane:
538         Quad.SetValue(Surf2->Plane());
539         break;
540
541       case GeomAbs_Cylinder:
542         Quad.SetValue(Surf2->Cylinder());
543         break;
544
545       case GeomAbs_Sphere:
546         Quad.SetValue(Surf2->Sphere());
547         break;
548
549       case GeomAbs_Cone:
550         Quad.SetValue(Surf2->Cone());
551         break;
552       default:
553         {
554           throw Standard_ConstructionError();
555           break;
556         }
557       } 
558     }
559     break;
560   }
561   //
562   Func.SetImplicitSurface(Quad);
563   Func.Set(IntSurf_QuadricTool::Tolerance(Quad));
564   AFunc.SetQuadric(Quad);
565   //
566   if (!reversed) {
567     Func.Set(Surf2);
568     AFunc.Set(Surf2);
569   }
570   else {
571     Func.Set(Surf1);
572     AFunc.Set(Surf1);
573   }
574   //
575   if (!reversed) {
576     solrst.Perform(AFunc,D2,TolArc,TolTang);
577   }
578   else {
579     solrst.Perform(AFunc,D1,TolArc,TolTang);
580   }
581   if (!solrst.IsDone()) {
582     return;
583   }
584   //
585   IntSurf_SequenceOfPathPoint seqpdep;
586   IntSurf_SequenceOfInteriorPoint seqpins;
587   //
588   NbPointRst = solrst.NbPoints();
589   TColStd_Array1OfInteger Destination(1,NbPointRst+1); Destination.Init(0);
590   if (NbPointRst) {
591     if (!reversed) {
592       ComputeTangency(solrst,seqpdep,D2,Func,Surf2,Destination);
593     }
594     else {
595       ComputeTangency(solrst,seqpdep,D1,Func,Surf1,Destination);
596     }
597   }
598   //
599   Standard_Boolean SearchIns = Standard_True;
600   if(Quad.TypeQuadric() == GeomAbs_Plane && solrst.NbSegments() > 0)
601   {
602     //For such kind of cases it is possible that whole surface is on one side of plane,
603     //plane only touches surface and does not cross it,
604     //so no inner points exist.
605     SearchIns = Standard_False;
606     Handle(Adaptor3d_TopolTool) T;
607     if(reversed)
608     {
609       T = D1;
610     }
611     else
612     {
613       T = D2;
614     }
615     Standard_Integer aNbSamples = 0;
616     aNbSamples = T->NbSamples();
617     gp_Pnt2d s2d;
618     gp_Pnt s3d;
619     Standard_Real aValf[1], aUVap[2];
620     math_Vector Valf(aValf,1,1), UVap(aUVap,1,2);
621     T->SamplePoint(1,s2d, s3d);
622     UVap(1)=s2d.X(); 
623     UVap(2)=s2d.Y();
624     Func.Value(UVap,Valf);
625     Standard_Real rvalf = Sign(1.,Valf(1));
626     for(Standard_Integer i = 2; i <= aNbSamples; ++i)
627     {
628       T->SamplePoint(i,s2d, s3d);
629       UVap(1)=s2d.X(); 
630       UVap(2)=s2d.Y();
631       Func.Value(UVap,Valf);
632       if(rvalf * Valf(1) < 0.)
633       {
634         SearchIns = Standard_True;
635         break;
636       }   
637     }
638   }
639   // Recherche des points interieurs
640   NbPointIns = 0;
641   if(SearchIns) {
642     if (!reversed) {
643       if (myIsStartPnt)
644         solins.Perform(Func,Surf2,myUStart,myVStart);
645       else
646         solins.Perform(Func,Surf2,D2,TolTang);
647     }
648     else {
649       if (myIsStartPnt)
650         solins.Perform(Func,Surf1,myUStart,myVStart);
651       else
652         solins.Perform(Func,Surf1,D1,TolTang);
653     }
654     NbPointIns = solins.NbPoints();
655     for (Standard_Integer i=1; i <= NbPointIns; i++) {
656       seqpins.Append(solins.Value(i));
657     }
658   }
659   //
660   NbPointDep=seqpdep.Length();
661   //
662   if (NbPointDep || NbPointIns) {
663     IntPatch_TheIWalking iwalk(TolTang,Fleche,Pas);
664     if (!reversed) {
665       iwalk.Perform(seqpdep,seqpins,Func,Surf2);
666     }
667     else {
668       iwalk.Perform(seqpdep,seqpins,Func,Surf1,Standard_True);
669     }
670     if(!iwalk.IsDone()) {
671       return;
672     }
673
674     Standard_Real Vmin, Vmax, TolV = 1.e-14;
675     if (!reversed) { //Surf1 is quadric
676       Vmin = Surf1->FirstVParameter();
677       Vmax = Surf1->LastVParameter();
678     }
679     else { //Surf2 is quadric
680       Vmin = Surf2->FirstVParameter();
681       Vmax = Surf2->LastVParameter();
682     }
683     //
684     Nblines = iwalk.NbLines();
685     for (Standard_Integer j=1; j<=Nblines; j++) {
686       const Handle(IntPatch_TheIWLineOfTheIWalking)&  iwline  = iwalk.Value(j);
687       const Handle(IntSurf_LineOn2S)&                 thelin  = iwline->Line();
688
689       Nbpts = thelin->NbPoints();
690       if(Nbpts>=2) { 
691         Standard_Integer k = 0;
692         tgline = iwline->TangentVector(k);      
693         if(k>=1 && k<=Nbpts) { } else { k=Nbpts>>1; } 
694         valpt = thelin->Value(k).Value();       
695
696         if (!reversed) {
697           thelin->Value(k).ParametersOnS2(U2,V2);
698           norm1 = Quad.Normale(valpt);
699           Surf2->D1(U2,V2,ptbid,d1u,d1v);
700           norm2 = d1u.Crossed(d1v);
701         }
702         else {
703           thelin->Value(k).ParametersOnS1(U2,V2);
704           norm2 = Quad.Normale(valpt);
705           Surf1->D1(U2,V2,ptbid,d1u,d1v);
706           norm1 = d1u.Crossed(d1v);
707         }
708         if (tgline.DotCross(norm2,norm1) > 0.) {
709           trans1 = IntSurf_Out;
710           trans2 = IntSurf_In;
711         }
712         else {
713           trans1 = IntSurf_In;
714           trans2 = IntSurf_Out;
715         }
716
717         //
718         Standard_Real AnU1,AnU2,AnV2;
719
720         GeomAbs_SurfaceType typQuad = Quad.TypeQuadric();
721         Standard_Boolean arecadr=Standard_False;
722         valpt = thelin->Value(1).Value();
723         Quad.Parameters(valpt,AnU1,V1);
724
725         if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
726         if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
727
728         if(reversed) { 
729           thelin->SetUV(1,Standard_False,AnU1,V1); //-- on va lire u2,v2
730           thelin->Value(1).ParametersOnS1(AnU2,AnV2);
731         }
732         else { 
733           thelin->SetUV(1,Standard_True,AnU1,V1);  //-- on va lire u1,v1 
734           thelin->Value(1).ParametersOnS2(AnU2,AnV2);
735         }
736
737         if(typQuad==GeomAbs_Cylinder || 
738           typQuad==GeomAbs_Cone || 
739           typQuad==GeomAbs_Sphere) { 
740             arecadr=Standard_True; 
741         } 
742         //
743         for (k=2; k<=Nbpts; ++k) {
744           valpt = thelin->Value(k).Value();
745           Quad.Parameters(valpt,U1,V1);
746           //
747           if((V1 < Vmin) && (Vmin-V1 < TolV)) {
748             V1 = Vmin;
749           }
750           if((V1 > Vmax) && (V1-Vmax < TolV)) {
751             V1 = Vmax;
752           }
753           //
754           if(arecadr) {
755             //modified by NIZNHY-PKV Fri Mar 28 15:06:01 2008f
756             Standard_Real aCf, aTwoPI;
757             //
758             aCf=0.;
759             aTwoPI=M_PI+M_PI;
760             if ((U1-AnU1) >  1.5*M_PI) { 
761               while ((U1-AnU1) > (1.5*M_PI+aCf*aTwoPI)) {
762                 aCf=aCf+1.;
763               }
764               U1=U1-aCf*aTwoPI;
765             } 
766             //
767             else {
768               while ((U1-AnU1) < (-1.5*M_PI-aCf*aTwoPI)) {
769                 aCf=aCf+1.;
770               }
771               U1=U1+aCf*aTwoPI;
772             }
773             // was:
774             //if ((U1-AnU1) >  1.5*M_PI) { 
775             //  U1-=M_PI+M_PI;
776             //}
777             //else if ((U1-AnU1) < -1.5*M_PI) { 
778             //  U1+=M_PI+M_PI; 
779             //}
780             //modified by NIZNHY-PKV Fri Mar 28 15:06:11 2008t
781           }
782           //
783           if(reversed) { 
784             thelin->SetUV(k,Standard_False,U1,V1);
785
786             thelin->Value(k).ParametersOnS1(U2,V2);
787             switch(typeS1) { 
788             case GeomAbs_Cylinder:
789             case GeomAbs_Cone:
790             case GeomAbs_Sphere:
791             case GeomAbs_Torus:
792               while(U2<(AnU2-1.5*M_PI)) U2+=M_PI+M_PI;
793               while(U2>(AnU2+1.5*M_PI)) U2-=M_PI+M_PI;
794               break;
795             default: 
796               break;
797             }
798             if(typeS2==GeomAbs_Torus) { 
799               while(V2<(AnV2-1.5*M_PI)) V2+=M_PI+M_PI;
800               while(V2>(AnV2+1.5*M_PI)) V2-=M_PI+M_PI;
801             }
802             thelin->SetUV(k,Standard_True,U2,V2);
803           }
804           else { 
805             thelin->SetUV(k,Standard_True,U1,V1);
806
807             thelin->Value(k).ParametersOnS2(U2,V2);
808             switch(typeS2) { 
809             case GeomAbs_Cylinder:
810             case GeomAbs_Cone:
811             case GeomAbs_Sphere:
812             case GeomAbs_Torus:
813               while(U2<(AnU2-1.5*M_PI)) U2+=M_PI+M_PI;
814               while(U2>(AnU2+1.5*M_PI)) U2-=M_PI+M_PI;
815               break;
816             default: 
817               break;
818             }
819             if(typeS2==GeomAbs_Torus) { 
820               while(V2<(AnV2-1.5*M_PI)) V2+=M_PI+M_PI;
821               while(V2>(AnV2+1.5*M_PI)) V2-=M_PI+M_PI;
822             }
823             thelin->SetUV(k,Standard_False,U2,V2);
824
825           }
826
827           AnU1=U1;
828           AnU2=U2;
829           AnV2=V2;
830         }
831         // <-A
832         wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
833
834 #ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG
835         wline->Dump(0);
836 #endif
837
838         if (   iwline->HasFirstPoint() 
839           && iwline->IsTangentAtBegining() == Standard_False) 
840         {
841           indfirst = iwline->FirstPointIndex();
842           PPoint = seqpdep(indfirst);
843           tgline = PPoint.Direction3d();
844           Standard_Integer themult = PPoint.Multiplicity();
845           for (Standard_Integer i=NbPointRst; i>=1; i--) {
846             if (Destination(i) == indfirst) {
847               if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
848                 Quad.Parameters(PPoint.Value(),U1,V1);
849
850                 if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
851                 if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
852
853                 PPoint.Parameters(themult,U2,V2);
854                 Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
855               }
856               else {  //-- typeS1 != Pln && Cyl && Sph && Cone
857                 Quad.Parameters(PPoint.Value(),U2,V2);
858
859                 if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
860                 if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
861
862                 PPoint.Parameters(themult,U1,V1);
863                 Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
864               }
865
866               VecNormale = d1u.Crossed(d1v);                      
867               //-- Modif du 27 Septembre 94 (Recadrage des pts U,V) 
868               ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
869               ptdeb.SetParameters(U1,V1,U2,V2);
870               ptdeb.SetParameter(1.);
871
872               Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
873
874               currentarc = solrst.Point(i).Arc();
875               currentparam = solrst.Point(i).Parameter();
876               currentarc->D1(currentparam,p2d,d2d);
877               tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
878
879               Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
880               if(squaremagnitudeVecNormale > 1e-13) { 
881                 DirNormale=VecNormale;
882                 IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
883               }
884               else { 
885                 TLine.SetValue(Standard_True,IntSurf_Undecided);
886                 TArc.SetValue(Standard_True,IntSurf_Undecided);
887               }
888
889               ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
890               if (!solrst.Point(i).IsNew()) {
891                 ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
892               }
893               wline->AddVertex(ptdeb);
894               if (themult == 0) {
895                 wline->SetFirstPoint(wline->NbVertex());
896               }
897
898               themult--;
899             }
900           }
901         }
902         else if (iwline->IsTangentAtBegining()) 
903         {
904           gp_Pnt psol = thelin->Value(1).Value();
905           thelin->Value(1).ParametersOnS1(U1,V1);
906           thelin->Value(1).ParametersOnS2(U2,V2);
907           ptdeb.SetValue(psol,TolArc,Standard_True);
908           ptdeb.SetParameters(U1,V1,U2,V2);
909           ptdeb.SetParameter(1.);
910           wline->AddVertex(ptdeb);
911           wline->SetFirstPoint(wline->NbVertex());
912         }
913         else 
914         { 
915           gp_Pnt psol = thelin->Value(1).Value();
916           thelin->Value(1).ParametersOnS1(U1,V1);
917           thelin->Value(1).ParametersOnS2(U2,V2);
918           ptdeb.SetValue(psol,TolArc,Standard_False);
919           ptdeb.SetParameters(U1,V1,U2,V2);
920           ptdeb.SetParameter(1.);
921           wline->AddVertex(ptdeb);
922           wline->SetFirstPoint(wline->NbVertex());
923         }
924
925
926         if (   iwline->HasLastPoint() 
927           && iwline->IsTangentAtEnd() == Standard_False) 
928         {
929           indlast = iwline->LastPointIndex();
930           PPoint = seqpdep(indlast);
931           tgline = PPoint.Direction3d().Reversed();
932           Standard_Integer themult = PPoint.Multiplicity();
933           for (Standard_Integer i=NbPointRst; i >=1; i--) {
934             if (Destination(i) == indlast) {
935               if (!reversed) {
936                 Quad.Parameters(PPoint.Value(),U1,V1);
937
938                 if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
939                 if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
940
941                 PPoint.Parameters(themult,U2,V2);
942                 Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
943                 VecNormale = d1u.Crossed(d1v);                    //-- @@@@
944               }
945               else {
946                 Quad.Parameters(PPoint.Value(),U2,V2);
947
948                 if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
949                 if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
950
951                 PPoint.Parameters(themult,U1,V1);
952                 Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
953                 VecNormale = d1u.Crossed(d1v);                    //-- @@@@
954               }
955
956               ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
957               ptfin.SetParameters(U1,V1,U2,V2);
958               ptfin.SetParameter(Nbpts);
959
960               Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
961
962               currentarc = solrst.Point(i).Arc();
963               currentparam = solrst.Point(i).Parameter();
964               currentarc->D1(currentparam,p2d,d2d);
965               tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
966
967
968               Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
969               if(squaremagnitudeVecNormale > 1e-13) { 
970                 DirNormale=VecNormale;
971                 IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
972               }
973               else { 
974                 TLine.SetValue(Standard_True,IntSurf_Undecided);
975                 TArc.SetValue(Standard_True,IntSurf_Undecided);
976               }
977
978
979               ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
980               if (!solrst.Point(i).IsNew()) {
981                 ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
982               }
983               wline->AddVertex(ptfin);
984               if (themult == 0) {
985                 wline->SetLastPoint(wline->NbVertex());
986               }
987
988               themult--;
989             }
990           }
991         }
992         else if (iwline->IsTangentAtEnd()) 
993         {
994           gp_Pnt psol = thelin->Value(Nbpts).Value();
995           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
996           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
997           ptfin.SetValue(psol,TolArc,Standard_True);
998           ptfin.SetParameters(U1,V1,U2,V2);
999           ptfin.SetParameter(Nbpts);
1000           wline->AddVertex(ptfin);
1001           wline->SetLastPoint(wline->NbVertex());
1002         }
1003         else 
1004         { 
1005           gp_Pnt psol = thelin->Value(Nbpts).Value();
1006           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
1007           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
1008           ptfin.SetValue(psol,TolArc,Standard_False);
1009           ptfin.SetParameters(U1,V1,U2,V2);
1010           ptfin.SetParameter(Nbpts);
1011           wline->AddVertex(ptfin);
1012           wline->SetLastPoint(wline->NbVertex());
1013         }
1014         //
1015         // Il faut traiter les points de passage.
1016         slin.Append(wline);
1017       }// if(Nbpts>=2) {
1018     }// for (j=1; j<=Nblines; j++) {
1019
1020     // ON GERE LES RACCORDS ENTRE LIGNES. ELLE NE PEUVENT SE RACCORDER
1021     // QUE SUR DES POINTS DE TANGENCE
1022
1023
1024     Nblines = slin.Length();
1025     for (Standard_Integer j=1; j<=Nblines-1; j++) {
1026       dofirst = dolast = Standard_False;
1027       const  Handle(IntPatch_Line)& slinj = slin(j);
1028       Handle(IntPatch_WLine) wlin1 (Handle(IntPatch_WLine)::DownCast (slinj));
1029       if (wlin1->HasFirstPoint()) {
1030         ptdeb = wlin1->FirstPoint(indfirst);
1031         if (ptdeb.IsTangencyPoint()) {
1032           dofirst = Standard_True;
1033         }
1034       }
1035       if (wlin1->HasLastPoint()) {
1036         ptfin = wlin1->LastPoint(indlast);
1037         if (ptfin.IsTangencyPoint()) {
1038           dolast = Standard_True;
1039         }
1040       }
1041
1042       if (dofirst || dolast) {
1043         for (Standard_Integer k=j+1; k<=Nblines;k++) {
1044           const  Handle(IntPatch_Line)& slink = slin(k);
1045           Handle(IntPatch_WLine) wlin2 (Handle(IntPatch_WLine)::DownCast (slink));
1046           if (wlin2->HasFirstPoint()) {
1047             ptbis = wlin2->FirstPoint(ind2);
1048             if (ptbis.IsTangencyPoint()) {
1049               if (dofirst ) {
1050                 if (ptdeb.Value().Distance(ptbis.Value()) <= TolArc) {
1051                   ptdeb.SetMultiple(Standard_True);
1052                   if (!ptbis.IsMultiple()) {
1053                     ptbis.SetMultiple(Standard_True);
1054                     wlin2->Replace(ind2,ptbis);
1055                   }
1056                 }
1057               }
1058               if (dolast ) {
1059                 if (ptfin.Value().Distance(ptbis.Value()) <= TolArc) {
1060                   ptfin.SetMultiple(Standard_True);
1061                   if (!ptbis.IsMultiple()) {
1062                     ptbis.SetMultiple(Standard_True);
1063                     wlin2->Replace(ind2,ptbis);
1064                   }
1065                 }
1066               }
1067             }
1068           }
1069           if (wlin2->HasLastPoint()) {
1070             ptbis = wlin2->LastPoint(ind2);
1071             if (ptbis.IsTangencyPoint()) {
1072               if (dofirst ) {
1073                 if (ptdeb.Value().Distance(ptbis.Value()) <= TolArc) {
1074                   ptdeb.SetMultiple(Standard_True);
1075                   if (!ptbis.IsMultiple()) {
1076                     ptbis.SetMultiple(Standard_True);
1077                     wlin2->Replace(ind2,ptbis);
1078                   }
1079                 }
1080               }
1081               if (dolast ) {
1082                 if (ptfin.Value().Distance(ptbis.Value()) <= TolArc) {
1083                   ptfin.SetMultiple(Standard_True);
1084                   if (!ptbis.IsMultiple()) {
1085                     ptbis.SetMultiple(Standard_True);
1086                     wlin2->Replace(ind2,ptbis);
1087                   }
1088                 }
1089               }
1090             }
1091           }
1092         }
1093         if(dofirst) 
1094           wlin1->Replace(indfirst,ptdeb);
1095         if(dolast) 
1096           wlin1->Replace(indlast,ptfin);
1097       }
1098     }
1099   }// if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1100   //
1101   // Treatment the segments
1102   NbSegm = solrst.NbSegments();
1103   if (NbSegm) {
1104     for(Standard_Integer i=1; i<=NbSegm; i++) {
1105       thesegm = solrst.Segment(i);  
1106       //Check if segment is degenerated
1107       if(thesegm.HasFirstPoint() && thesegm.HasLastPoint())
1108       {
1109         Standard_Real tol2 = Precision::Confusion();
1110         tol2 *= tol2;
1111         const gp_Pnt& aPf = thesegm.FirstPoint().Value();
1112         const gp_Pnt& aPl = thesegm.LastPoint().Value();
1113         if(aPf.SquareDistance(aPl) <= tol2)
1114         {
1115           //segment can be degenerated - check inner point
1116           paramf = thesegm.FirstPoint().Parameter();
1117           paraml = thesegm.LastPoint().Parameter();
1118           gp_Pnt2d _p2d = 
1119             thesegm.Curve()->Value(.57735 * paramf + 0.42265 * paraml);
1120           gp_Pnt aPm;
1121           if(reversed)
1122           {
1123             Surf1->D0(_p2d.X(), _p2d.Y(), aPm);
1124           }
1125           else
1126           {
1127             Surf2->D0(_p2d.X(), _p2d.Y(), aPm);
1128           }
1129           if(aPm.SquareDistance(aPf) <= tol2)
1130           {
1131             //Degenerated
1132             continue;
1133           }
1134         }
1135       }
1136
1137
1138       //----------------------------------------------------------------------      
1139       // on cree une ligne d intersection contenant uniquement le segment.
1140       // VOIR POUR LA TRANSITION DE LA LIGNE
1141       // On ajoute aussi un polygone pour le traitement des intersections
1142       // entre ligne et restrictions de la surface implicite (PutVertexOnLine)
1143       //----------------------------------------------------------------------
1144       //-- Calcul de la transition sur la rline (12 fev 97)
1145       //-- reversed a le sens de OnFirst
1146       //--
1147       dofirst = dolast  = Standard_False;
1148       procf = Standard_False;
1149       procl = Standard_False;
1150       IntSurf_Transition TLineUnk,TArcUnk;
1151
1152       IntPatch_Point _thepointAtBeg;
1153       IntPatch_Point _thepointAtEnd;
1154
1155       Standard_Boolean TransitionOK=Standard_False;
1156
1157       if(thesegm.HasFirstPoint()) { 
1158         Standard_Real _u1,_v1,_u2,_v2;
1159
1160         dofirst = Standard_True;
1161         PStartf = thesegm.FirstPoint();
1162         paramf = PStartf.Parameter();
1163
1164         gp_Pnt2d _p2d     = thesegm.Curve()->Value(paramf);
1165         Handle(Adaptor3d_HVertex) _vtx;
1166         if(PStartf.IsNew()==Standard_False) 
1167           _vtx= PStartf.Vertex();
1168         const gp_Pnt& _Pp = PStartf.Value();
1169         _thepointAtBeg.SetValue(_Pp,PStartf.Tolerance(),Standard_False);
1170         if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
1171           Quad.Parameters(_Pp,_u1,_v1);
1172           _u2=_p2d.X(); _v2=_p2d.Y();
1173         }
1174         else {  //-- typeS1 != Pln && Cyl && Sph && Cone
1175           Quad.Parameters(_Pp,_u2,_v2);
1176           _u1=_p2d.X(); _v1=_p2d.Y();
1177         }
1178         _thepointAtBeg.SetParameters(_u1,_v1,_u2,_v2);
1179         _thepointAtBeg.SetParameter(paramf);
1180         if(PStartf.IsNew()==Standard_False) 
1181           _thepointAtBeg.SetVertex(reversed,_vtx);
1182         _thepointAtBeg.SetArc(reversed,thesegm.Curve(),paramf,TLineUnk,TArcUnk);
1183
1184
1185         gp_Vec d1u1,d1v1,d1u2,d1v2; gp_Vec2d _d2d;
1186         Surf1->D1(_u1,_v1,ptbid,d1u1,d1v1);
1187         norm1 = d1u1.Crossed(d1v1);
1188         Surf2->D1(_u2,_v2,ptbid,d1u2,d1v2);
1189         norm2 = d1u2.Crossed(d1v2);
1190
1191         thesegm.Curve()->D1(paramf,_p2d,_d2d);
1192         if(reversed) { 
1193           tgline.SetLinearForm(_d2d.X(),d1u1,_d2d.Y(),d1v1);
1194         }
1195         else { 
1196           tgline.SetLinearForm(_d2d.X(),d1u2,_d2d.Y(),d1v2);
1197         }
1198         _u1=tgline.DotCross(norm2,norm1);
1199         TransitionOK=Standard_True;
1200         if (_u1 > 0.00000001) {
1201           trans1 = IntSurf_Out;
1202           trans2 = IntSurf_In;
1203         }
1204         else if(_u1 < -0.00000001) { 
1205           trans1 = IntSurf_In;
1206           trans2 = IntSurf_Out;
1207         }
1208         else { 
1209           TransitionOK=Standard_False;
1210         }
1211       }
1212       if(thesegm.HasLastPoint()) {  
1213         Standard_Real _u1,_v1,_u2,_v2;
1214
1215         dolast = Standard_True;
1216         PStartl = thesegm.LastPoint();
1217         paraml = PStartl.Parameter();
1218
1219         gp_Pnt2d _p2d = thesegm.Curve()->Value(paraml);
1220         Handle(Adaptor3d_HVertex) _vtx;
1221         if(PStartl.IsNew()==Standard_False) 
1222           _vtx = PStartl.Vertex();
1223         const gp_Pnt& _Pp = PStartl.Value();
1224         IntPatch_Point _thepoint;
1225         _thepointAtEnd.SetValue(_Pp,PStartl.Tolerance(),Standard_False);
1226         if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
1227           Quad.Parameters(_Pp,_u1,_v1);
1228           _u2=_p2d.X(); _v2=_p2d.Y();
1229         }
1230         else {  //-- typeS1 != Pln && Cyl && Sph && Cone
1231           Quad.Parameters(_Pp,_u2,_v2);
1232           _u1=_p2d.X(); _v1=_p2d.Y();
1233         }
1234         _thepointAtEnd.SetParameters(_u1,_v1,_u2,_v2);
1235         _thepointAtEnd.SetParameter(paraml);
1236         if(PStartl.IsNew()==Standard_False)
1237           _thepointAtEnd.SetVertex(reversed,_vtx);
1238         _thepointAtEnd.SetArc(reversed,thesegm.Curve(),paraml,TLineUnk,TArcUnk);
1239
1240
1241
1242         gp_Vec d1u1,d1v1,d1u2,d1v2; gp_Vec2d _d2d;
1243         Surf1->D1(_u1,_v1,ptbid,d1u1,d1v1);
1244         norm1 = d1u1.Crossed(d1v1);
1245         Surf2->D1(_u2,_v2,ptbid,d1u2,d1v2);
1246         norm2 = d1u2.Crossed(d1v2);
1247
1248         thesegm.Curve()->D1(paraml,_p2d,_d2d);
1249         if(reversed) { 
1250           tgline.SetLinearForm(_d2d.X(),d1u1,_d2d.Y(),d1v1);
1251         }
1252         else { 
1253           tgline.SetLinearForm(_d2d.X(),d1u2,_d2d.Y(),d1v2);
1254         }
1255         _u1=tgline.DotCross(norm2,norm1);
1256         TransitionOK=Standard_True;
1257         if (_u1 > 0.00000001) {
1258           trans1 = IntSurf_Out;
1259           trans2 = IntSurf_In;
1260         }
1261         else if(_u1 < -0.00000001) { 
1262           trans1 = IntSurf_In;
1263           trans2 = IntSurf_Out;
1264         }
1265         else { 
1266           TransitionOK=Standard_False;
1267         }       
1268       }
1269       if(TransitionOK==Standard_False) { 
1270         //-- rline = new IntPatch_RLine (thesegm.Curve(),reversed,Standard_False);
1271         rline =  new IntPatch_RLine (Standard_False);
1272         if(reversed) { 
1273           rline->SetArcOnS1(thesegm.Curve());
1274         }
1275         else { 
1276           rline->SetArcOnS2(thesegm.Curve());
1277         }
1278       }
1279       else { 
1280         //-- rline = new IntPatch_RLine (thesegm.Curve(),reversed,Standard_False,trans1,trans2);
1281         rline =  new IntPatch_RLine (Standard_False,trans1,trans2);
1282         if(reversed) { 
1283           rline->SetArcOnS1(thesegm.Curve());
1284         }
1285         else { 
1286           rline->SetArcOnS2(thesegm.Curve());
1287         }
1288       }
1289
1290       //------------------------------
1291       //-- Ajout des points 
1292       //--
1293       if (thesegm.HasFirstPoint()) {
1294         rline->AddVertex(_thepointAtBeg);
1295         rline->SetFirstPoint(rline->NbVertex());
1296       }
1297
1298       if (thesegm.HasLastPoint()) {
1299         rline->AddVertex(_thepointAtEnd);
1300         rline->SetLastPoint(rline->NbVertex());
1301       }
1302
1303       // Polygone sur restriction solution
1304       if (dofirst && dolast) {
1305         Standard_Real prm;
1306         gp_Pnt ptpoly;
1307         IntSurf_PntOn2S p2s;
1308         Handle(IntSurf_LineOn2S) Thelin = new IntSurf_LineOn2S ();
1309         Handle(Adaptor2d_HCurve2d) arcsegm = thesegm.Curve();
1310         Standard_Integer nbsample = 100;
1311
1312         if (!reversed) {
1313           for (Standard_Integer j=1; j<=nbsample; j++) {
1314             prm = paramf + (j-1)*(paraml-paramf)/(nbsample-1);
1315             arcsegm->D0(prm,p2d);
1316             Surf2->D0(p2d.X(),p2d.Y(),ptpoly);
1317
1318             Quad.Parameters(ptpoly,U1,V1);
1319             p2s.SetValue(ptpoly,U1,V1,p2d.X(),p2d.Y());
1320             Thelin->Add(p2s);
1321           }
1322         }
1323         else {
1324           for (Standard_Integer j=1; j<=nbsample; j++) {
1325             prm = paramf + (j-1)*(paraml-paramf)/(nbsample-1);
1326             arcsegm->D0(prm,p2d);
1327             Surf1->D0(p2d.X(),p2d.Y(),ptpoly);
1328
1329             Quad.Parameters(ptpoly,U2,V2);
1330             p2s.SetValue(ptpoly,p2d.X(),p2d.Y(),U2,V2);
1331             Thelin->Add(p2s);
1332           }
1333         }
1334         rline->Add(Thelin);
1335       }
1336
1337       if (dofirst || dolast) {
1338         Nblines = slin.Length();
1339         for (Standard_Integer j=1; j<=Nblines; j++) {
1340           const Handle(IntPatch_Line)& slinj = slin(j);
1341           typ = slinj->ArcType();
1342           if (typ == IntPatch_Walking) {
1343             Nbpts = Handle(IntPatch_WLine)::DownCast (slinj)->NbVertex();
1344           }
1345           else {
1346             Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
1347           }
1348           for (Standard_Integer k=1; k<=Nbpts;k++) {
1349             if (typ == IntPatch_Walking) {
1350               ptdeb = Handle(IntPatch_WLine)::DownCast (slinj)->Vertex(k);
1351             }
1352             else {
1353               ptdeb = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1354             }
1355             if (dofirst) {
1356
1357               if (ptdeb.Value().Distance(PStartf.Value()) <=TolArc) {
1358                 ptdeb.SetMultiple(Standard_True);
1359                 if (typ == IntPatch_Walking) {
1360                   Handle(IntPatch_WLine)::DownCast (slinj)->Replace(k,ptdeb);
1361                 }
1362                 else {
1363                   Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptdeb);
1364                 }
1365                 ptdeb.SetParameter(paramf);
1366                 rline->AddVertex(ptdeb);
1367                 if (!procf){
1368                   procf=Standard_True;
1369                   rline->SetFirstPoint(rline->NbVertex());
1370                 }
1371               }
1372             }
1373             if (dolast) {
1374               if(dofirst) { //-- on recharge le ptdeb
1375                 if (typ == IntPatch_Walking) {
1376                   ptdeb = Handle(IntPatch_WLine)::DownCast (slinj)->Vertex(k);
1377                 }
1378                 else {
1379                   ptdeb = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1380                 }
1381               }
1382               if (ptdeb.Value().Distance(PStartl.Value()) <=TolArc) {
1383                 ptdeb.SetMultiple(Standard_True);
1384                 if (typ == IntPatch_Walking) {
1385                   Handle(IntPatch_WLine)::DownCast (slinj)->Replace(k,ptdeb);
1386                 }
1387                 else {
1388                   Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptdeb);
1389                 }
1390                 ptdeb.SetParameter(paraml);
1391                 rline->AddVertex(ptdeb);
1392                 if (!procl){
1393                   procl=Standard_True;
1394                   rline->SetLastPoint(rline->NbVertex());
1395                 }
1396               }
1397             }
1398           }
1399         }
1400       }
1401       slin.Append(rline);
1402     }
1403   }// if (NbSegm) 
1404   //
1405   // on traite les restrictions de la surface implicite
1406
1407   for (Standard_Integer i=1, aNbLin = slin.Length(); i<=aNbLin; i++)
1408   {
1409     Handle(IntPatch_PointLine) aL = Handle(IntPatch_PointLine)::DownCast(slin(i));
1410     
1411     if (!reversed)
1412       IntPatch_RstInt::PutVertexOnLine(aL,Surf1,D1,Surf2,Standard_True,TolTang);
1413     else
1414       IntPatch_RstInt::PutVertexOnLine(aL,Surf2,D2,Surf1,Standard_False,TolTang);
1415
1416     if (aL->NbPnts() <= 2)
1417     {
1418       Standard_Boolean aCond = aL->NbPnts() < 2;
1419       if (!aCond)
1420         aCond = (aL->Point(1).IsSame(aL->Point(2), Precision::Confusion()));
1421
1422       if (aCond)
1423       {
1424         slin.Remove(i);
1425         i--;
1426         aNbLin--;
1427         continue;
1428       }
1429     }
1430
1431     if(aL->ArcType() == IntPatch_Walking)
1432     {
1433       const Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(aL);
1434       slin.Append(aWL);
1435       slin.Remove(i);
1436       i--;
1437       aNbLin--;
1438     }
1439   }
1440
1441   // Now slin is filled as follows: lower indices correspond to Restriction line,
1442   // after (higher indices) - only Walking-line.
1443
1444   const Standard_Real aTol3d = Max(Func.Tolerance(), TolTang); 
1445   const Handle(Adaptor3d_HSurface)& aQSurf = (reversed) ? Surf2 : Surf1;
1446   const Handle(Adaptor3d_HSurface)& anOtherSurf = (reversed) ? Surf1 : Surf2;
1447
1448   for (Standard_Integer i = 1; i <= slin.Length(); i++)
1449   {
1450     const Handle(IntPatch_PointLine)& aL1 = Handle(IntPatch_PointLine)::DownCast(slin(i));
1451     const Handle(IntPatch_RLine)& aRL1 = Handle(IntPatch_RLine)::DownCast(aL1);
1452
1453     if(aRL1.IsNull())
1454     {
1455       //Walking-Walking cases are not supported
1456       break;
1457     }
1458
1459     const Handle(Adaptor2d_HCurve2d)& anArc = aRL1->IsArcOnS1() ? 
1460                                               aRL1->ArcOnS1() :
1461                                               aRL1->ArcOnS2();
1462     if(anArc->Curve2d().GetType() != GeomAbs_Line)
1463     {
1464       //Restriction line must be isoline.
1465       //Other cases are not supported by
1466       //existing algorithms.
1467
1468       break;
1469     }
1470
1471     Standard_Boolean isFirstDeleted = Standard_False;
1472
1473     for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
1474     {
1475       Handle(IntPatch_PointLine) aL2 = Handle(IntPatch_PointLine)::DownCast(slin(j));
1476       Handle(IntPatch_RLine) aRL2 = Handle(IntPatch_RLine)::DownCast(aL2);
1477
1478       //Here aL1 (i-th line) is Restriction-line and aL2 (j-th line) is
1479       //Restriction or Walking
1480
1481       if(!aRL2.IsNull())
1482       {
1483         const Handle(Adaptor2d_HCurve2d)& anArc2 = aRL2->IsArcOnS1() ?
1484                                                    aRL2->ArcOnS1() :
1485                                                    aRL2->ArcOnS2();
1486         if(anArc2->Curve2d().GetType() != GeomAbs_Line)
1487         {
1488           //Restriction line must be isoline.
1489           //Other cases are not supported by
1490           //existing algorithms.
1491
1492           continue;
1493         }
1494       }
1495
1496       //aDir can be equal to one of following four values only
1497       //(because Reastriction line is boundary of rectangular surface):
1498       //either {0, 1} or {0, -1} or {1, 0} or {-1, 0}.
1499       const gp_Dir2d aDir = anArc->Curve2d().Line().Direction();
1500
1501       Standard_Real aTol2d = anOtherSurf->UResolution(aTol3d),
1502                     aPeriod = anOtherSurf->IsVPeriodic() ? anOtherSurf->VPeriod() : 0.0;
1503
1504       if(Abs(aDir.X()) < 0.5)
1505       {//Restriction directs along V-direction
1506         aTol2d = anOtherSurf->VResolution(aTol3d);
1507         aPeriod = anOtherSurf->IsUPeriodic() ? anOtherSurf->UPeriod() : 0.0;
1508       }
1509
1510       const Standard_Boolean isCoincide = IsCoincide(Func, aL2, anArc, aRL1->IsArcOnS1(),
1511                                                       aTol3d, aTol2d, aPeriod);
1512
1513       if(isCoincide)
1514       {
1515         if(aRL2.IsNull())
1516         {//Delete Walking-line
1517           slin.Remove(j);
1518           j--;
1519         }
1520         else
1521         {//Restriction-Restriction
1522           const Handle(Adaptor2d_HCurve2d)& anArc2 = aRL2->IsArcOnS1() ?
1523                                                      aRL2->ArcOnS1() :
1524                                                      aRL2->ArcOnS2();
1525
1526           const Standard_Real aRange2 = anArc2->LastParameter() - 
1527                                         anArc2->FirstParameter();
1528           const Standard_Real aRange1 = anArc->LastParameter() -
1529                                         anArc->FirstParameter();
1530
1531           if(aRange2 > aRange1)
1532           {
1533             isFirstDeleted = Standard_True;
1534             break;
1535           }
1536           else
1537           {//Delete j-th line
1538             slin.Remove(j);
1539             j--;
1540           }
1541         }
1542       }
1543     } //for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
1544
1545     if(isFirstDeleted)
1546     {//Delete i-th line
1547       slin.Remove(i--);
1548     }
1549   }//for (Standard_Integer i = 1; i <= slin.Length(); i++)
1550
1551   empt = (slin.Length() == 0 && spnt.Length() == 0);
1552   done = Standard_True;
1553
1554
1555   if(slin.Length() == 0)
1556     return;
1557
1558   Standard_Boolean isDecomposeRequired =  (Quad.TypeQuadric() == GeomAbs_Cone) || 
1559                                           (Quad.TypeQuadric() == GeomAbs_Sphere) ||
1560                                           (Quad.TypeQuadric() == GeomAbs_Cylinder) ||
1561                                           (Quad.TypeQuadric() == GeomAbs_Torus);
1562
1563   if(!isDecomposeRequired)
1564     return;
1565
1566   // post processing for cones and spheres
1567
1568   const Handle(Adaptor3d_TopolTool)& PDomain = (reversed) ? D1 : D2;
1569
1570   IntPatch_SequenceOfLine dslin;
1571   Standard_Boolean isDecompose = Standard_False;
1572   for(Standard_Integer i = 1; i <= slin.Length(); i++ )
1573   {
1574     if(DecomposeResult( Handle(IntPatch_PointLine)::DownCast(slin(i)),
1575                                         reversed, Quad, PDomain, aQSurf,
1576                                         anOtherSurf, TolArc, aTol3d, dslin))
1577     {
1578       isDecompose = Standard_True;
1579     }
1580   }
1581
1582   if(!isDecompose)
1583     return;
1584
1585   slin.Clear();
1586   for(Standard_Integer i = 1; i <= dslin.Length(); i++ )
1587     slin.Append(dslin(i));
1588 }
1589
1590 // correct U parameter of the start point of line on Quadric
1591 // (change 0->2PI or vs, if necessary)
1592 static Standard_Real AdjustUFirst(Standard_Real U1,Standard_Real U2)
1593 {
1594   Standard_Real u = U1;
1595
1596   // case: no adjustment
1597   if( U1 > 0. && U1 < (2.*M_PI) )
1598     return u;
1599
1600   // case: near '0'
1601   if( U1 == 0. || fabs(U1) <= 1.e-9 ) {
1602     if( U2 > 0. && U2 < (2.*M_PI) )
1603       u = ( U2 < ((2.*M_PI)-U2) ) ? 0. : (2.*M_PI);
1604     else {
1605       Standard_Real uu = U2;
1606       if( U2 > (2.*M_PI) )
1607         while( uu > (2.*M_PI) )
1608           uu -= (2.*M_PI);
1609       else 
1610         while( uu < 0.)
1611           uu += (2.*M_PI);
1612
1613       u = ( uu < ((2.*M_PI)-uu) ) ? 0. : (2.*M_PI);
1614     }
1615   }
1616   // case: near '2PI'
1617   else if( U1 == (2.*M_PI) || fabs((2.*M_PI)-fabs(U1)) <= 1.e-9 ) {
1618     if( U2 > 0. && U2 < (2.*M_PI) )
1619       u = ( U2 < ((2.*M_PI)-U2) ) ? 0. : (2.*M_PI);
1620     else {
1621       Standard_Real uu = U2;
1622       if( U2 > (2.*M_PI) )
1623         while( uu > (2.*M_PI) )
1624           uu -= (2.*M_PI);
1625       else 
1626         while( uu < 0.)
1627           uu += (2.*M_PI);
1628
1629       u = ( uu < ((2.*M_PI)-uu) ) ? 0. : (2.*M_PI);
1630     }
1631   }
1632   // case: '<0. || >2PI'
1633   else {
1634     if(U1 < 0.)
1635       while(u < 0.)
1636         u += 2.*M_PI;
1637     if(U1 > (2.*M_PI))
1638       while(u > (2.*M_PI))
1639         u -= (2.*M_PI);
1640   }
1641
1642   return u;
1643 }
1644
1645 // collect vertices, reject equals
1646 static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_PointLine)& thePLine,
1647                                             const Standard_Real           TOL3D,
1648                                             const Standard_Real           TOL2D)
1649 {
1650   //  Standard_Real TOL3D = 1.e-12, TOL2D = 1.e-8;
1651
1652   Handle(IntSurf_LineOn2S) vertices = new IntSurf_LineOn2S();
1653
1654   Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0.;
1655   Standard_Integer i = 0, k = 0;
1656   Standard_Integer NbVrt = thePLine->NbVertex();
1657
1658   TColStd_Array1OfInteger anVrts(1,NbVrt);
1659   anVrts.Init(0);
1660
1661   // check equal vertices
1662   for(i = 1; i <= NbVrt; i++) {
1663
1664     if( anVrts(i) == -1 ) continue;
1665
1666     const IntPatch_Point& Pi = thePLine->Vertex(i);
1667
1668     for(k = (i+1); k <= NbVrt; k++) {
1669
1670       if( anVrts(k) == -1 ) continue;
1671
1672       const IntPatch_Point& Pk = thePLine->Vertex(k);
1673
1674       if(Pi.Value().Distance(Pk.Value()) <= TOL3D) {
1675         // suggest the points are equal;
1676         // test 2d parameters on surface
1677         Standard_Boolean sameU1 = Standard_False;
1678         Standard_Boolean sameV1 = Standard_False;
1679         Standard_Boolean sameU2 = Standard_False;
1680         Standard_Boolean sameV2 = Standard_False;
1681
1682         Pi.ParametersOnS1(U1,V1);
1683         Pk.ParametersOnS1(U2,V2);
1684         if(fabs(U1-U2) <= TOL2D) sameU1 = Standard_True;
1685         if(fabs(V1-V2) <= TOL2D) sameV1 = Standard_True;
1686
1687         Pi.ParametersOnS2(U1,V1);
1688         Pk.ParametersOnS2(U2,V2);
1689         if(fabs(U1-U2) <= TOL2D) sameU2 = Standard_True;
1690         if(fabs(V1-V2) <= TOL2D) sameV2 = Standard_True;
1691
1692         if((sameU1 && sameV1) && (sameU2 && sameV2))
1693           anVrts(k) = -1;
1694       }
1695     }
1696   }
1697
1698   // copy further processed vertices
1699   for(i = 1; i <= NbVrt; i++) {
1700     if( anVrts(i) == -1 ) continue;
1701     vertices->Add(thePLine->Vertex(i).PntOn2S());
1702   }
1703   return vertices;
1704 }
1705
1706 static void SearchVertices(const Handle(IntSurf_LineOn2S)& Line,
1707   const Handle(IntSurf_LineOn2S)& Vertices,
1708   TColStd_Array1OfInteger&        PTypes)
1709 {
1710   Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
1711   Standard_Integer ip = 0, iv = 0;
1712   for(ip = 1; ip <= nbp; ip++) {
1713     const IntSurf_PntOn2S& aP = Line->Value(ip);
1714     Standard_Integer type = 0;
1715     for(iv = 1; iv <= nbv; iv++) {
1716       const IntSurf_PntOn2S& aV = Vertices->Value(iv);
1717       if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
1718         type = iv; 
1719         break;
1720       }
1721     }
1722     PTypes(ip) = type;
1723   }
1724 }
1725
1726 static inline Standard_Boolean IsSeamParameter(const Standard_Real U,
1727   const Standard_Real TOL2D)
1728 {
1729   return (fabs(U) <= TOL2D || fabs(2.*M_PI - U) <= TOL2D);
1730 }
1731
1732 static inline Standard_Real AdjustU(const Standard_Real U)
1733 {
1734   Standard_Real u = U, DBLPI = 2.*M_PI;
1735   if(u < 0. || u > DBLPI) {
1736     if(u < 0.)
1737       while(u < 0.)
1738         u += DBLPI;
1739     else
1740       while(u > DBLPI)
1741         u -= DBLPI;
1742   }
1743   return u;
1744 }
1745
1746 static inline void Correct2DBounds(const Standard_Real UF,
1747   const Standard_Real UL,
1748   const Standard_Real VF,
1749   const Standard_Real VL,
1750   const Standard_Real TOL2D,
1751   Standard_Real&      U,
1752   Standard_Real&      V)
1753 {
1754   Standard_Real Eps = 1.e-16;
1755   Standard_Real dUF = fabs(U - UF);
1756   Standard_Real dUL = fabs(U - UL);
1757   Standard_Real dVF = fabs(V - VF);
1758   Standard_Real dVL = fabs(V - VL);
1759   if(dUF <= TOL2D && dUF > Eps) U = UF;
1760   if(dUL <= TOL2D && dUL > Eps) U = UL;
1761   if(dVF <= TOL2D && dVF > Eps) V = VF;
1762   if(dVL <= TOL2D && dVL > Eps) V = VL;
1763 }
1764
1765 static void AdjustLine(Handle(IntSurf_LineOn2S)& Line,
1766   const Standard_Boolean    IsReversed,
1767   const Handle(Adaptor3d_HSurface)&         QSurf,
1768   const Standard_Real       TOL2D)
1769 {
1770   Standard_Real VF = QSurf->FirstVParameter();
1771   Standard_Real VL = QSurf->LastVParameter();
1772   Standard_Real UF = QSurf->FirstUParameter();
1773   Standard_Real UL = QSurf->LastUParameter();
1774
1775   Standard_Integer nbp = Line->NbPoints(), ip = 0;
1776   Standard_Real U = 0., V = 0.;
1777   for(ip = 1; ip <= nbp; ip++) {
1778     if(IsReversed) {
1779       Line->Value(ip).ParametersOnS2(U,V);
1780       U = AdjustU(U);
1781       Correct2DBounds(UF,UL,VF,VL,TOL2D,U,V);
1782       Line->SetUV(ip,Standard_False,U,V);
1783     }
1784     else {
1785       Line->Value(ip).ParametersOnS1(U,V);
1786       U = AdjustU(U);
1787       Correct2DBounds(UF,UL,VF,VL,TOL2D,U,V);
1788       Line->SetUV(ip,Standard_True,U,V);
1789     }
1790   }
1791 }
1792
1793 static Standard_Boolean InsertSeamVertices(Handle(IntSurf_LineOn2S)&       Line,
1794   const Standard_Boolean          IsReversed,
1795   Handle(IntSurf_LineOn2S)&       Vertices,
1796   const TColStd_Array1OfInteger&  PTypes,
1797   const Standard_Real             TOL2D)
1798 {
1799   Standard_Boolean result = Standard_False;
1800   Standard_Integer ip = 0, nbp = Line->NbPoints();
1801   Standard_Real U = 0., V = 0.;
1802   for(ip = 1; ip <= nbp; ip++) {
1803     Standard_Integer ipt = PTypes(ip);
1804     if(ipt != 0) {
1805       const IntSurf_PntOn2S& aP = Line->Value(ip);
1806       if(IsReversed)
1807         aP.ParametersOnS2(U,V); // S2 - quadric
1808       else
1809         aP.ParametersOnS1(U,V); // S1 - quadric
1810       U = AdjustU(U);
1811       if(IsSeamParameter(U,TOL2D)) {
1812         if(ip == 1 || ip == nbp) {
1813           Standard_Real U1 = 0., V1 = 0.;
1814           Standard_Integer ipp = (ip == 1) ? (ip+1) : (ip-1);
1815           if(IsReversed)
1816             Line->Value(ipp).ParametersOnS2(U1,V1); // S2 - quadric
1817           else
1818             Line->Value(ipp).ParametersOnS1(U1,V1); // S1 - quadric
1819           Standard_Real u = AdjustUFirst(U,U1);
1820           if(fabs(u-U) >= 1.5*M_PI) {
1821             Standard_Real U2 = 0., V2 = 0.;
1822             if(IsReversed) {
1823               Line->Value(ip).ParametersOnS1(U2,V2); // prm
1824               Line->SetUV(ip,Standard_False,u,V);
1825               Line->SetUV(ip,Standard_True,U2,V2);
1826             }
1827             else {
1828               Line->Value(ip).ParametersOnS2(U2,V2); // prm
1829               Line->SetUV(ip,Standard_True,u,V);
1830               Line->SetUV(ip,Standard_False,U2,V2);
1831             }
1832           }
1833         }
1834         else {
1835           Standard_Integer ipp = ip - 1;
1836           Standard_Integer ipn = ip + 1;
1837           Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
1838           if(IsReversed) {
1839             Line->Value(ipp).ParametersOnS2(U1,V1); // quad
1840             Line->Value(ipn).ParametersOnS2(U2,V2); // quad
1841           }
1842           else {
1843             Line->Value(ipp).ParametersOnS1(U1,V1); // quad
1844             Line->Value(ipn).ParametersOnS1(U2,V2); // quad
1845           }
1846           U1 = AdjustU(U1);
1847           U2 = AdjustU(U2);
1848           Standard_Boolean pnearZero = (fabs(U1) < fabs(2.*M_PI-U1)) ? Standard_True : Standard_False;
1849           Standard_Boolean cnearZero = (fabs(U) < fabs(2.*M_PI-U)) ? Standard_True : Standard_False;
1850           if(pnearZero == cnearZero) {
1851             if(!IsSeamParameter(U2,TOL2D) && !IsSeamParameter(U1,TOL2D)) {
1852               Standard_Real nU = (cnearZero) ? (2.*M_PI) : 0.;
1853               IntSurf_PntOn2S nP;
1854               nP.SetValue(aP.Value());
1855               Standard_Real U3 = 0., V3 = 0.;
1856               if(IsReversed) {
1857                 Line->Value(ip).ParametersOnS1(U3,V3); // prm
1858                 nP.SetValue(Standard_False,nU,V);
1859                 nP.SetValue(Standard_True,U3,V3);
1860               }
1861               else {
1862                 Line->Value(ip).ParametersOnS2(U3,V3); // prm
1863                 nP.SetValue(Standard_True,nU,V);
1864                 nP.SetValue(Standard_False,U3,V3);
1865               }
1866               Line->InsertBefore(ipn,nP);
1867               Vertices->Add(nP);
1868               result = Standard_True;
1869               break;
1870             }
1871           }
1872           else {
1873             if(!IsSeamParameter(U2,TOL2D) && !IsSeamParameter(U1,TOL2D)) {
1874               Standard_Real nU = (cnearZero) ? (2.*M_PI) : 0.;
1875               IntSurf_PntOn2S nP;
1876               nP.SetValue(aP.Value());
1877               Standard_Real U3 = 0., V3 = 0.;
1878               if(IsReversed) {
1879                 Line->Value(ip).ParametersOnS1(U3,V3); // prm
1880                 nP.SetValue(Standard_False,nU,V);
1881                 nP.SetValue(Standard_True,U3,V3);
1882               }
1883               else {
1884                 Line->Value(ip).ParametersOnS2(U3,V3); // prm
1885                 nP.SetValue(Standard_True,nU,V);
1886                 nP.SetValue(Standard_False,U3,V3);
1887               }
1888               Line->InsertBefore(ip,nP);
1889               Vertices->Add(nP);
1890               result = Standard_True;
1891               break;
1892             }
1893             else {
1894               // Line->InsertBefore(ip,Line->Value(ipn));
1895               // Line->RemovePoint(ip+2);
1896               // result = Standard_True;
1897               // cout << "swap vertex " << endl;
1898               // break;
1899             }
1900           }
1901         }
1902       }
1903     }
1904   }
1905   return result;
1906 }
1907
1908 static void ToSmooth( const Handle(IntSurf_LineOn2S)& Line,
1909                       const Standard_Boolean          IsReversed,
1910                       const IntSurf_Quadric&          Quad,
1911                       const Standard_Boolean          IsFirst,
1912                       Standard_Real&                  D3D)
1913 {
1914   if(Line->NbPoints() <= 10)
1915     return;
1916
1917   D3D = 0.;
1918   Standard_Integer NbTestPnts = Line->NbPoints() / 5;
1919   if(NbTestPnts < 5) NbTestPnts = 5;
1920
1921   Standard_Integer startp = (IsFirst) ? 2 : (Line->NbPoints() - NbTestPnts - 2);
1922   Standard_Integer ip = 0;
1923   Standard_Real Uc = 0., Vc = 0., Un = 0., Vn = 0., DDU = 0., DDV = 0.;
1924
1925   for(ip = startp; ip <= NbTestPnts; ip++) {
1926     if(IsReversed) {
1927       Line->Value(ip).ParametersOnS2(Uc,Vc); // S2 - quadric
1928       Line->Value(ip+1).ParametersOnS2(Un,Vn);
1929     }
1930     else {
1931       Line->Value(ip).ParametersOnS1(Uc,Vc); // S1 - quadric
1932       Line->Value(ip+1).ParametersOnS1(Un,Vn);
1933     }
1934     DDU += fabs(fabs(Uc)-fabs(Un));
1935     DDV += fabs(fabs(Vc)-fabs(Vn));
1936
1937     if(ip > startp) {
1938       Standard_Real DP = Line->Value(ip).Value().Distance(Line->Value(ip-1).Value());
1939       D3D += DP;
1940     }
1941   }
1942
1943   DDU /= (Standard_Real) NbTestPnts + 1;
1944   DDV /= (Standard_Real) NbTestPnts + 1;
1945
1946   D3D /= (Standard_Real) NbTestPnts + 1;
1947
1948
1949   Standard_Integer Index1 = (IsFirst) ? 1 : (Line->NbPoints());
1950   Standard_Integer Index2 = (IsFirst) ? 2 : (Line->NbPoints()-1);
1951   Standard_Integer Index3 = (IsFirst) ? 3 : (Line->NbPoints()-2);
1952
1953   Standard_Boolean doU = Standard_False;
1954
1955   Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0., U3 = 0., V3 = 0.;
1956
1957   if(IsReversed) {
1958     Line->Value(Index1).ParametersOnS2(U1,V1); // S2 - quadric
1959     Line->Value(Index2).ParametersOnS2(U2,V2);
1960     Line->Value(Index3).ParametersOnS2(U3,V3);
1961   }
1962   else {
1963     Line->Value(Index1).ParametersOnS1(U1,V1); // S1 - quadric
1964     Line->Value(Index2).ParametersOnS1(U2,V2);
1965     Line->Value(Index3).ParametersOnS1(U3,V3);
1966   }
1967
1968   if(!doU && Quad.TypeQuadric() == GeomAbs_Sphere) {
1969     if(fabs(fabs(U1)-fabs(U2)) > (M_PI/16.)) doU = Standard_True;
1970
1971     if(doU && (fabs(U1) <= 1.e-9 || fabs(U1-2.*M_PI) <= 1.e-9)) {
1972       if(fabs(V1-M_PI/2.) <= 1.e-9 || fabs(V1+M_PI/2.) <= 1.e-9) {}
1973       else {
1974         doU = Standard_False;
1975       }
1976     }
1977   }
1978
1979   if(Quad.TypeQuadric() == GeomAbs_Cone) {
1980     Standard_Real Uapx = 0., Vapx = 0.;
1981     Quad.Parameters(Quad.Cone().Apex(),Uapx,Vapx);
1982
1983     if(fabs(fabs(U1)-fabs(U2)) > M_PI/32.) doU = Standard_True;
1984
1985     if(doU && (fabs(U1) <= 1.e-9 || fabs(U1-2.*M_PI) <= 1.e-9)) {
1986       if(fabs(V1-Vapx) <= 1.e-9) {}
1987       else {
1988         doU = Standard_False;
1989       }
1990     }
1991   }
1992
1993   if(doU) {
1994     Standard_Real dU = Min((DDU/10.),5.e-8);
1995     Standard_Real U = (U2 > U3) ? (U2 + dU) : (U2 - dU);
1996     if(IsReversed)
1997       Line->SetUV(Index1,Standard_False,U,V1);
1998     else
1999       Line->SetUV(Index1,Standard_True,U,V1);
2000     U1 = U;
2001   }
2002
2003
2004 static Standard_Boolean TestMiddleOnPrm(const IntSurf_PntOn2S& aP,
2005                                         const IntSurf_PntOn2S& aV,
2006                                         const Standard_Boolean IsReversed,
2007                                         const Standard_Real    ArcTol,
2008                                         const Handle(Adaptor3d_TopolTool)&  PDomain)
2009
2010 {
2011   Standard_Boolean result = Standard_False;
2012   Standard_Real Up = 0., Vp = 0., Uv = 0., Vv = 0.;
2013   if(IsReversed) {
2014     aP.ParametersOnS1(Up,Vp); //S1 - parametric
2015     aV.ParametersOnS1(Uv,Vv);
2016   }
2017   else {
2018     aP.ParametersOnS2(Up,Vp); // S2 - parametric
2019     aV.ParametersOnS2(Uv,Vv);
2020   }
2021   Standard_Real Um = (Up + Uv)*0.5, Vm = (Vp + Vv)*0.5;
2022   gp_Pnt2d a2DPntM(Um,Vm);
2023   TopAbs_State PosM = PDomain->Classify(a2DPntM,ArcTol);
2024   if(PosM == TopAbs_ON || PosM == TopAbs_IN )
2025     result = Standard_True;
2026   return result;
2027 }
2028
2029 static void VerifyVertices( const Handle(IntSurf_LineOn2S)&    Line,
2030                             const Standard_Boolean             IsReversed,
2031                             const Handle(IntSurf_LineOn2S)&    Vertices,
2032                             const Standard_Real                TOL2D,
2033                             const Standard_Real       ArcTol,
2034                             const Handle(Adaptor3d_TopolTool)& PDomain,
2035                             IntSurf_PntOn2S&          VrtF,
2036                             Standard_Boolean&         AddFirst,
2037                             IntSurf_PntOn2S&          VrtL,
2038                             Standard_Boolean&         AddLast)
2039 {
2040   Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
2041   Standard_Integer FIndexSame = 0, FIndexNear = 0, LIndexSame = 0, LIndexNear = 0;
2042   const IntSurf_PntOn2S& aPF = Line->Value(1);
2043   const IntSurf_PntOn2S& aPL = Line->Value(nbp);
2044   Standard_Real UF = 0., VF = 0., UL = 0., VL = 0.;
2045   if(IsReversed) {
2046     aPF.ParametersOnS2(UF,VF);
2047     aPL.ParametersOnS2(UL,VL);
2048   }
2049   else {
2050     aPF.ParametersOnS1(UF,VF);
2051     aPL.ParametersOnS1(UL,VL);
2052   }
2053   gp_Pnt2d a2DPF(UF,VF);
2054   gp_Pnt2d a2DPL(UL,VL);
2055   Standard_Real DistMinF = 1.e+100, DistMinL = 1.e+100;
2056   Standard_Integer FConjugated = 0, LConjugated = 0;
2057
2058   Standard_Integer iv = 0;
2059
2060   for(iv = 1; iv <= nbv; iv++) {
2061     Standard_Real Uv = 0., Vv = 0.;
2062     if(IsReversed) {
2063       Vertices->Value(iv).ParametersOnS2(Uv,Vv);
2064       Uv = AdjustU(Uv);
2065       Vertices->SetUV(iv,Standard_False,Uv,Vv);
2066     }
2067     else {
2068       Vertices->Value(iv).ParametersOnS1(Uv,Vv);
2069       Uv = AdjustU(Uv);
2070       Vertices->SetUV(iv,Standard_True,Uv,Vv);
2071     }
2072   }
2073
2074   for(iv = 1; iv <= nbv; iv++) {
2075     const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2076     if(aPF.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2077       FIndexSame = iv;
2078       break;
2079     }
2080     else {
2081       Standard_Real Uv = 0., Vv = 0.;
2082       if(IsReversed)
2083         aV.ParametersOnS2(Uv,Vv);
2084       else
2085         aV.ParametersOnS1(Uv,Vv);
2086       gp_Pnt2d a2DV(Uv,Vv);
2087       Standard_Real Dist = a2DV.Distance(a2DPF);
2088       if(Dist < DistMinF) {
2089         DistMinF = Dist;
2090         FIndexNear = iv;
2091         if(FConjugated != 0)
2092           FConjugated = 0;
2093       }
2094       if(IsSeamParameter(Uv,TOL2D)) {
2095         Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2096         gp_Pnt2d a2DCV(Ucv,Vv);
2097         Standard_Real CDist = a2DCV.Distance(a2DPF);
2098         if(CDist < DistMinF) {
2099           DistMinF = CDist;
2100           FConjugated = iv;
2101           FIndexNear = iv;
2102         }
2103       }
2104     }
2105   }
2106
2107   for(iv = 1; iv <= nbv; iv++) {
2108     const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2109     if(aPL.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2110       LIndexSame = iv;
2111       break;
2112     }
2113     else {
2114       Standard_Real Uv = 0., Vv = 0.;
2115       if(IsReversed)
2116         aV.ParametersOnS2(Uv,Vv);
2117       else
2118         aV.ParametersOnS1(Uv,Vv);
2119       gp_Pnt2d a2DV(Uv,Vv);
2120       Standard_Real Dist = a2DV.Distance(a2DPL);
2121       if(Dist < DistMinL) {
2122         DistMinL = Dist;
2123         LIndexNear = iv;
2124         if(LConjugated != 0)
2125           LConjugated = 0;
2126       }
2127       if(IsSeamParameter(Uv,TOL2D)) {
2128         Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2129         gp_Pnt2d a2DCV(Ucv,Vv);
2130         Standard_Real CDist = a2DCV.Distance(a2DPL);
2131         if(CDist < DistMinL) {
2132           DistMinL = CDist;
2133           LConjugated = iv;
2134           LIndexNear = iv;
2135         }
2136       }
2137     }
2138   }
2139
2140   AddFirst = Standard_False;
2141   AddLast  = Standard_False;
2142
2143   if(FIndexSame == 0) {
2144     if(FIndexNear != 0) {
2145       const IntSurf_PntOn2S& aV = Vertices->Value(FIndexNear);
2146       Standard_Real Uv = 0., Vv = 0.;
2147       if(IsReversed)
2148         aV.ParametersOnS2(Uv,Vv);
2149       else
2150         aV.ParametersOnS1(Uv,Vv);
2151       if(IsSeamParameter(Uv,TOL2D)) {
2152         Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2153         Standard_Boolean test = TestMiddleOnPrm(aPF,aV,IsReversed,ArcTol,PDomain);
2154         if(test) {
2155           VrtF.SetValue(aV.Value());
2156           if(IsReversed) {
2157             Standard_Real U2 = 0., V2 = 0.;
2158             aV.ParametersOnS1(U2,V2); // S1 - prm
2159             VrtF.SetValue(Standard_True,U2,V2);
2160             if(FConjugated == 0)
2161               VrtF.SetValue(Standard_False,Uv,Vv);
2162             else
2163               VrtF.SetValue(Standard_False,Ucv,Vv);
2164           }
2165           else {
2166             Standard_Real U2 = 0., V2 = 0.;
2167             aV.ParametersOnS2(U2,V2); // S2 - prm
2168             VrtF.SetValue(Standard_False,U2,V2);
2169             if(FConjugated == 0)
2170               VrtF.SetValue(Standard_True,Uv,Vv);
2171             else
2172               VrtF.SetValue(Standard_True,Ucv,Vv);
2173           }
2174           Standard_Real Dist3D = VrtF.Value().Distance(aPF.Value());
2175           if(Dist3D > 1.5e-7 && DistMinF > TOL2D) {
2176             AddFirst = Standard_True;
2177           }
2178         }
2179       }
2180       else {
2181         // to do: analyze internal vertex
2182       }
2183     }
2184   }
2185
2186   if(LIndexSame == 0) {
2187     if(LIndexNear != 0) {
2188       const IntSurf_PntOn2S& aV = Vertices->Value(LIndexNear);
2189       Standard_Real Uv = 0., Vv = 0.;
2190       if(IsReversed)
2191         aV.ParametersOnS2(Uv,Vv);
2192       else
2193         aV.ParametersOnS1(Uv,Vv);
2194       if(IsSeamParameter(Uv,TOL2D)) {
2195         Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2196         Standard_Boolean test = TestMiddleOnPrm(aPL,aV,IsReversed,ArcTol,PDomain);
2197         if(test) {
2198           VrtL.SetValue(aV.Value());
2199           if(IsReversed) {
2200             Standard_Real U2 = 0., V2 = 0.;
2201             aV.ParametersOnS1(U2,V2); // S1 - prm
2202             VrtL.SetValue(Standard_True,U2,V2);
2203             if(LConjugated == 0)
2204               VrtL.SetValue(Standard_False,Uv,Vv);
2205             else
2206               VrtL.SetValue(Standard_False,Ucv,Vv);
2207           }
2208           else {
2209             Standard_Real U2 = 0., V2 = 0.;
2210             aV.ParametersOnS2(U2,V2); // S2 - prm
2211             VrtL.SetValue(Standard_False,U2,V2);
2212             if(LConjugated == 0)
2213               VrtL.SetValue(Standard_True,Uv,Vv);
2214             else
2215               VrtL.SetValue(Standard_True,Ucv,Vv);
2216           }
2217           Standard_Real Dist3D = VrtL.Value().Distance(aPL.Value());
2218           if(Dist3D > 1.5e-7 && DistMinL > TOL2D) {
2219             AddLast = Standard_True;
2220           }
2221         }
2222       }
2223       else {
2224         // to do: analyze internal vertex
2225       }
2226     }
2227   }
2228 }
2229
2230 static Standard_Boolean AddVertices(Handle(IntSurf_LineOn2S)& Line,
2231   const IntSurf_PntOn2S&    VrtF,
2232   const Standard_Boolean    AddFirst,
2233   const IntSurf_PntOn2S&    VrtL,
2234   const Standard_Boolean    AddLast,
2235   const Standard_Real       D3DF,
2236   const Standard_Real       D3DL)
2237 {
2238   Standard_Boolean result = Standard_False;
2239   if(AddFirst) {
2240     Standard_Real DF = Line->Value(1).Value().Distance(VrtF.Value());
2241     if((D3DF*2.) > DF && DF > 1.5e-7) {
2242       Line->InsertBefore(1,VrtF);
2243       result = Standard_True;
2244     }
2245   }
2246   if(AddLast) {
2247     Standard_Real DL = Line->Value(Line->NbPoints()).Value().Distance(VrtL.Value());
2248     if((D3DL*2.) > DL && DL > 1.5e-7) {
2249       Line->Add(VrtL);
2250       result = Standard_True;
2251     }
2252   }
2253   return result;
2254 }
2255
2256
2257 static void PutIntVertices(const Handle(IntPatch_PointLine)&    Line,
2258   Handle(IntSurf_LineOn2S)& Result,
2259   Standard_Boolean          theIsReversed,
2260   Handle(IntSurf_LineOn2S)& Vertices,
2261   const Standard_Real       ArcTol)
2262 {
2263   Standard_Integer nbp = Result->NbPoints(), nbv = Vertices->NbPoints();
2264
2265   if(nbp < 3)
2266     return;
2267
2268   const Handle(IntPatch_RLine) aRLine = Handle(IntPatch_RLine)::DownCast(Line);
2269
2270   Standard_Integer ip = 0, iv = 0;
2271   gp_Pnt aPnt;
2272   IntPatch_Point thePnt;
2273   Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
2274
2275   for(ip = 2; ip <= (nbp-1); ip++) {
2276     const IntSurf_PntOn2S& aP = Result->Value(ip);
2277     for(iv = 1; iv <= nbv; iv++) {
2278       const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2279       if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2280         aPnt = Result->Value(ip).Value();
2281         Result->Value(ip).ParametersOnS1(U1,V1);
2282         Result->Value(ip).ParametersOnS2(U2,V2);
2283         thePnt.SetValue(aPnt,ArcTol,Standard_False);
2284         thePnt.SetParameters(U1,V1,U2,V2);
2285         
2286         Standard_Real aParam = (Standard_Real)ip;
2287
2288         if(!aRLine.IsNull())
2289         {
2290           //In fact, aRLine is always on the parametric surface.
2291           //If (theIsReversed == TRUE) then (U1, V1) - point on
2292           //parametric surface, otherwise - point on quadric.
2293           const Handle(Adaptor2d_HCurve2d)& anArc = aRLine->IsArcOnS1() ?
2294                                                     aRLine->ArcOnS1() :
2295                                                     aRLine->ArcOnS2();
2296
2297           const gp_Lin2d aLin(anArc->Curve2d().Line());
2298           gp_Pnt2d aPSurf;
2299
2300           if(theIsReversed)
2301           {
2302             aPSurf.SetCoord(U1, V1);
2303           }
2304           else
2305           {
2306             aPSurf.SetCoord(U2, V2);
2307           }
2308
2309           aParam = ElCLib::Parameter(aLin, aPSurf);
2310         }
2311         
2312         thePnt.SetParameter(aParam);
2313         Line->AddVertex(thePnt);
2314       }
2315     }
2316   }
2317 }
2318
2319 static Standard_Boolean HasInternals(Handle(IntSurf_LineOn2S)& Line,
2320   Handle(IntSurf_LineOn2S)& Vertices)
2321 {
2322   Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
2323   Standard_Integer ip = 0, iv = 0;
2324   Standard_Boolean result = Standard_False;
2325
2326   if(nbp < 3)
2327     return result;
2328
2329   for(ip = 2; ip <= (nbp-1); ip++) {
2330     const IntSurf_PntOn2S& aP = Line->Value(ip);
2331     for(iv = 1; iv <= nbv; iv++) {
2332       const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2333       if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2334         result = Standard_True;
2335         break;
2336       }
2337     }
2338     if(result)
2339       break;
2340   }
2341
2342   return result;
2343 }
2344 static Handle(IntPatch_WLine) MakeSplitWLine (Handle(IntPatch_WLine)&        WLine,
2345   Standard_Boolean         Tang,
2346   IntSurf_TypeTrans        Trans1,
2347   IntSurf_TypeTrans        Trans2,
2348   Standard_Real            ArcTol,
2349   Standard_Integer         ParFirst,
2350   Standard_Integer         ParLast)
2351 {
2352   Handle(IntSurf_LineOn2S) SLine = WLine->Curve();
2353   Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
2354
2355   Standard_Integer ip = 0;
2356   for(ip = ParFirst; ip <= ParLast; ip++)
2357     sline->Add(SLine->Value(ip));
2358
2359   Handle(IntPatch_WLine) wline = new IntPatch_WLine(sline,Tang,Trans1,Trans2);
2360
2361   gp_Pnt aSPnt;
2362   IntPatch_Point TPntF,TPntL;
2363   Standard_Real uu1 = 0., vv1 = 0., uu2 = 0., vv2 = 0.;
2364
2365   aSPnt = sline->Value(1).Value();
2366   sline->Value(1).ParametersOnS1(uu1,vv1);
2367   sline->Value(1).ParametersOnS2(uu2,vv2);
2368   TPntF.SetValue(aSPnt,ArcTol,Standard_False);
2369   TPntF.SetParameters(uu1,vv1,uu2,vv2);
2370   TPntF.SetParameter(1.);
2371   wline->AddVertex(TPntF);
2372   wline->SetFirstPoint(1);
2373
2374   aSPnt =  sline->Value(sline->NbPoints()).Value();
2375   sline->Value(sline->NbPoints()).ParametersOnS1(uu1,vv1);
2376   sline->Value(sline->NbPoints()).ParametersOnS2(uu2,vv2);
2377   TPntL.SetValue(aSPnt,ArcTol,Standard_False);
2378   TPntL.SetParameters(uu1,vv1,uu2,vv2);
2379   TPntL.SetParameter((Standard_Real)sline->NbPoints());
2380   wline->AddVertex(TPntL);
2381   wline->SetLastPoint(wline->NbVertex());
2382
2383   return wline;
2384 }
2385
2386 static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)&        WLine,
2387   Standard_Boolean         Tang,
2388   IntSurf_TypeTrans        Trans1,
2389   IntSurf_TypeTrans        Trans2,
2390   Standard_Real            ArcTol,
2391   IntPatch_SequenceOfLine& Segments)
2392 {
2393   Standard_Boolean result = Standard_False;
2394   Segments.Clear();
2395
2396   Standard_Integer nbv = WLine->NbVertex();
2397   if(nbv > 3) {
2398     Standard_Integer iv = 0;
2399     for(iv = 1; iv < nbv; iv++) {
2400       Standard_Integer firstPar = 
2401                     (Standard_Integer) WLine->Vertex(iv).ParameterOnLine();
2402       Standard_Integer lastPar  = 
2403                     (Standard_Integer) WLine->Vertex(iv+1).ParameterOnLine();
2404       if((lastPar - firstPar) <= 1)
2405         continue;
2406       else {
2407         Handle(IntPatch_WLine) splitwline = MakeSplitWLine(WLine,Tang,Trans1,Trans2,
2408                                                                 ArcTol,firstPar,lastPar);
2409         Segments.Append(splitwline);
2410         if(!result)
2411           result = Standard_True;
2412       }
2413     }
2414   }
2415   return result;
2416 }
2417
2418 //=======================================================================
2419 //function : DecomposeResult
2420 //purpose  : Split <theLine> in the places where it passes through seam edge
2421 //            or singularity (apex of cone or pole of sphere).
2422 //            This passage is detected by jump of U-parameter
2423 //            from point to point.
2424 //=======================================================================
2425 static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
2426                                         const Standard_Boolean       IsReversed,
2427                                         const IntSurf_Quadric&       theQuad,
2428                                         const Handle(Adaptor3d_TopolTool)& thePDomain,
2429                                         const Handle(Adaptor3d_HSurface)&  theQSurf, //quadric
2430                                         const Handle(Adaptor3d_HSurface)&  thePSurf, //parametric
2431                                         const Standard_Real                theArcTol,
2432                                         const Standard_Real                theTolTang,
2433                                         IntPatch_SequenceOfLine&           theLines)
2434 {
2435   if(theLine->ArcType() == IntPatch_Restriction)
2436   {
2437     const Handle(IntPatch_RLine)& aRL = Handle(IntPatch_RLine)::DownCast(theLine);
2438     if(!aRL.IsNull())
2439     {
2440       const Handle(Adaptor2d_HCurve2d)& anArc = aRL->IsArcOnS1() ?
2441                                         aRL->ArcOnS1() :
2442                                         aRL->ArcOnS2();
2443       if(anArc->Curve2d().GetType() != GeomAbs_Line)
2444       {
2445         //Restriction line must be isoline.
2446         //Other cases are not supported by
2447         //existing algorithms.
2448
2449         return Standard_False;
2450       }
2451     }
2452   }
2453   
2454   const Standard_Real aDeltaUmax = M_PI_2;
2455   const Standard_Real aTOL3D = 1.e-10, 
2456                       aTOL2D = Precision::PConfusion(),
2457                       aTOL2DS = Precision::PConfusion();
2458
2459   const Handle(IntSurf_LineOn2S)& aSLine = theLine->Curve();
2460
2461   if(aSLine->NbPoints() <= 2)
2462   {
2463     return Standard_False;
2464   }
2465   
2466   //Deletes repeated vertices
2467   Handle(IntSurf_LineOn2S) aVLine = GetVertices(theLine,aTOL3D,aTOL2D);
2468   
2469   Handle(IntSurf_LineOn2S) aSSLine(aSLine);
2470
2471   if(aSSLine->NbPoints() <= 1)
2472     return Standard_False;
2473
2474   AdjustLine(aSSLine,IsReversed,theQSurf,aTOL2D);
2475
2476   if(theLine->ArcType() == IntPatch_Walking)
2477   {
2478     Standard_Boolean isInserted = Standard_True;
2479     while(isInserted)
2480     {
2481       const Standard_Integer aNbPnts = aSSLine->NbPoints();
2482       TColStd_Array1OfInteger aPTypes(1,aNbPnts);
2483       SearchVertices(aSSLine,aVLine,aPTypes);
2484       isInserted = InsertSeamVertices(aSSLine,IsReversed,aVLine,aPTypes,aTOL2D);
2485     }
2486   }
2487
2488   const Standard_Integer aLindex = aSSLine->NbPoints();
2489   Standard_Integer aFindex = 1, aBindex = 0;
2490
2491   // build WLine parts (if any)
2492   Standard_Boolean flNextLine = Standard_True;
2493   Standard_Boolean hasBeenDecomposed = Standard_False;
2494   IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
2495
2496   IntSurf_PntOn2S PrePoint;
2497   while(flNextLine)
2498   {
2499     // reset variables
2500     flNextLine = Standard_False;
2501     Standard_Boolean isDecomposited = Standard_False;
2502     Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0.;
2503
2504     Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
2505
2506     //if((Lindex-Findex+1) <= 2 )
2507     if((aLindex <= aFindex) && !aPrePointExist)
2508     {
2509       //break of "while(flNextLine)" cycle
2510       break;
2511     }
2512
2513     if(aPrePointExist)
2514     {
2515       const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aFindex);
2516
2517       const Standard_Real aURes = theQSurf->UResolution(theArcTol),
2518                           aVRes = theQSurf->VResolution(theArcTol);
2519
2520       const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 : 
2521               (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
2522               (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
2523
2524       if(IntPatch_SpecialPoints::ContinueAfterSpecialPoint(theQSurf, thePSurf, aRefPt,
2525                                                               aPrePointExist, aTol2d,
2526                                                               PrePoint, IsReversed))
2527       {
2528         sline->Add(PrePoint);
2529       }
2530       else
2531       {
2532         //break of "while(flNextLine)" cycle
2533         break;
2534       }
2535     }
2536
2537     aPrePointExist = IntPatch_SPntNone;
2538
2539     // analyze other points
2540     for(Standard_Integer k = aFindex; k <= aLindex; k++)
2541     {
2542       if( k == aFindex )
2543       {
2544         PrePoint = aSSLine->Value(k);
2545         sline->Add(PrePoint);
2546         continue;
2547       }
2548
2549       if(IsReversed)
2550       {
2551         aSSLine->Value(k).ParametersOnS2(U1,V1);   // S2 - quadric, set U,V by Pnt3D
2552       }
2553       else
2554       {
2555         aSSLine->Value(k).ParametersOnS1(U1,V1);    // S1 - quadric, set U,V by Pnt3D
2556       }
2557
2558       aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k-1, aDeltaUmax);
2559
2560       if(aPrePointExist != IntPatch_SPntNone)
2561       {
2562         aBindex = k;
2563         isDecomposited = Standard_True;
2564         ////
2565         const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aBindex-1);
2566
2567         Standard_Real aCompareTol3D = Precision::Confusion();
2568         Standard_Real aCompareTol2D = Precision::PConfusion();
2569
2570         IntSurf_PntOn2S aNewPoint = aRefPt;
2571         IntPatch_SpecPntType aLastType = IntPatch_SPntNone;
2572
2573         if(aPrePointExist == IntPatch_SPntSeamUV)
2574         {
2575           aPrePointExist = IntPatch_SPntNone;
2576           aLastType = IntPatch_SPntSeamUV;
2577           IntPatch_SpecialPoints::AddCrossUVIsoPoint(theQSurf, thePSurf, 
2578                                                         aRefPt, theTolTang,
2579                                                         aNewPoint, IsReversed);
2580         }
2581         else if(aPrePointExist == IntPatch_SPntSeamV)
2582         {//WLine goes through seam
2583           aPrePointExist = IntPatch_SPntNone;
2584           aLastType = IntPatch_SPntSeamV;
2585
2586           //Not quadric point
2587           Standard_Real aU0 = 0.0, aV0 = 0.0;
2588           //Quadric point
2589           Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
2590
2591           if(IsReversed)
2592           {
2593             aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
2594           }
2595           else
2596           {
2597             aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
2598           }
2599
2600           math_Vector aTol(1, 3), aStartPoint(1,3),
2601             anInfBound(1, 3), aSupBound(1, 3);
2602
2603           //Parameters on parametric surface
2604           Standard_Real aUp = 0.0, aVp = 0.0;
2605           if(IsReversed)
2606           {
2607             aSSLine->Value(k).ParametersOnS1(aUp, aVp);
2608           }
2609           else
2610           {
2611             aSSLine->Value(k).ParametersOnS2(aUp, aVp);
2612           }
2613
2614           aTol(1) = thePSurf->UResolution(theArcTol);
2615           aTol(2) = thePSurf->VResolution(theArcTol);
2616           aTol(3) = theQSurf->UResolution(theArcTol);
2617           aStartPoint(1) = 0.5*(aU0 + aUp);
2618           aStartPoint(2) = 0.5*(aV0 + aVp);
2619           aStartPoint(3) = 0.5*(aUQuadRef + U1);
2620           anInfBound(1) = thePSurf->FirstUParameter();
2621           anInfBound(2) = thePSurf->FirstVParameter();
2622           anInfBound(3) = theQSurf->FirstUParameter();
2623           aSupBound(1) = thePSurf->LastUParameter();
2624           aSupBound(2) = thePSurf->LastVParameter();
2625           aSupBound(3) = theQSurf->LastUParameter();
2626
2627           IntPatch_SpecialPoints::
2628                       AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False,
2629                                         aTol, aStartPoint, anInfBound, aSupBound,
2630                                         aNewPoint, IsReversed);
2631         }
2632         else if(aPrePointExist == IntPatch_SPntPoleSeamU)
2633         {
2634           aPrePointExist = IntPatch_SPntNone;          
2635
2636           IntPatch_Point aVert;
2637           aVert.SetValue(aRefPt);
2638
2639           if(IntPatch_SpecialPoints::
2640                       AddSingularPole(theQSurf, thePSurf, aRefPt, theTolTang,
2641                                       aVert, aNewPoint, IsReversed))
2642           {
2643             aPrePointExist = IntPatch_SPntPole;
2644             aLastType = IntPatch_SPntPole;
2645             aCompareTol2D = -1.0;
2646           } //if(IntPatch_AddSpecialPoints::AddSingularPole(...))
2647           else
2648           {//Pole is not an intersection point
2649             aPrePointExist = IntPatch_SPntSeamU;
2650           }
2651         }
2652
2653         if(aPrePointExist == IntPatch_SPntSeamU)
2654         {//WLine goes through seam
2655           aPrePointExist = IntPatch_SPntNone;
2656           aLastType = IntPatch_SPntSeamU;
2657
2658           //Not quadric point
2659           Standard_Real aU0 = 0.0, aV0 = 0.0;
2660           //Quadric point
2661           Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
2662
2663           if(IsReversed)
2664           {
2665             aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
2666           }
2667           else
2668           {
2669             aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
2670           }
2671
2672           math_Vector aTol(1, 3), aStartPoint(1,3),
2673                       anInfBound(1, 3), aSupBound(1, 3);
2674           
2675           //Parameters on parametric surface
2676           Standard_Real aUp = 0.0, aVp = 0.0;
2677           if(IsReversed)
2678           {
2679             aSSLine->Value(k).ParametersOnS1(aUp, aVp);
2680           }
2681           else
2682           {
2683             aSSLine->Value(k).ParametersOnS2(aUp, aVp);
2684           }
2685
2686           aTol(1) = thePSurf->UResolution(theArcTol);
2687           aTol(2) = thePSurf->VResolution(theArcTol);
2688           aTol(3) = theQSurf->VResolution(theArcTol);
2689           aStartPoint(1) = 0.5*(aU0 + aUp);
2690           aStartPoint(2) = 0.5*(aV0 + aVp);
2691           aStartPoint(3) = 0.5*(aVQuadRef + V1);
2692           anInfBound(1) = thePSurf->FirstUParameter();
2693           anInfBound(2) = thePSurf->FirstVParameter();
2694           anInfBound(3) = theQSurf->FirstVParameter();
2695           aSupBound(1) = thePSurf->LastUParameter();
2696           aSupBound(2) = thePSurf->LastVParameter();
2697           aSupBound(3) = theQSurf->LastVParameter();
2698
2699           IntPatch_SpecialPoints::
2700                 AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, aTol,
2701                                   aStartPoint, anInfBound, aSupBound, aNewPoint,
2702                                   IsReversed);
2703         }
2704
2705         if(!aNewPoint.IsSame(aRefPt, aCompareTol3D, aCompareTol2D))
2706         {
2707           sline->Add(aNewPoint);
2708           aPrePointExist = aLastType;
2709           PrePoint = aNewPoint;
2710         }
2711         else
2712         {
2713           if(sline->NbPoints() == 1)
2714           {
2715             //FIRST point of the sline is the pole of the quadric.
2716             //Therefore, there is no point in decomposition.
2717
2718             PrePoint = aRefPt;
2719             aPrePointExist = aLastType;
2720           }
2721         }
2722
2723         ////
2724         break;
2725       } //if(Abs(U1-AnU1) > aDeltaUmax)
2726
2727       sline->Add(aSSLine->Value(k));
2728       PrePoint = aSSLine->Value(k);
2729     } //for(Standard_Integer k = aFindex; k <= aLindex; k++)
2730
2731     //Creation of new line as part of existing theLine.
2732     //This part is defined by sline.
2733
2734     if(sline->NbPoints() == 1)
2735     {
2736       flNextLine = Standard_True;
2737       aFindex = aBindex;
2738
2739       //Go to the next part of aSSLine
2740       //because we cannot create the line
2741       //with single point.
2742
2743       continue;
2744     }
2745
2746     IntSurf_PntOn2S aVF, aVL;
2747     Standard_Boolean addVF = Standard_False, addVL = Standard_False;
2748     VerifyVertices(sline,IsReversed,aVLine,aTOL2DS,theArcTol,
2749                                     thePDomain,aVF,addVF,aVL,addVL);
2750
2751     Standard_Boolean hasInternals = HasInternals(sline,aVLine);
2752
2753     Standard_Real D3F = 0., D3L = 0.;
2754     ToSmooth(sline,IsReversed,theQuad,Standard_True,D3F);
2755     ToSmooth(sline,IsReversed,theQuad,Standard_False,D3L);
2756
2757     //if(D3F <= 1.5e-7 && sline->NbPoints() >=3) {
2758     //  D3F = sline->Value(2).Value().Distance(sline->Value(3).Value());
2759     //}
2760     //if(D3L <= 1.5e-7 && sline->NbPoints() >=3) {
2761     //  D3L = sline->Value(sline->NbPoints()-1).Value().Distance(sline->
2762     //                                  Value(sline->NbPoints()-2).Value());
2763     //}
2764
2765     if(addVF || addVL)
2766     {
2767       Standard_Boolean isAdded = AddVertices(sline,aVF,addVF,aVL,addVL,D3F,D3L);
2768       if(isAdded)
2769       {
2770         ToSmooth(sline,IsReversed,theQuad,Standard_True,D3F);
2771         ToSmooth(sline,IsReversed,theQuad,Standard_False,D3L);
2772       }
2773     }
2774
2775     if(theLine->ArcType() == IntPatch_Walking)
2776     {
2777       IntPatch_Point aTPntF, aTPntL;
2778
2779       Handle(IntPatch_WLine) wline = 
2780                           new IntPatch_WLine(sline,Standard_False,
2781                           theLine->TransitionOnS1(),theLine->TransitionOnS2());
2782
2783       gp_Pnt aSPnt(sline->Value(1).Value());
2784       sline->Value(1).ParametersOnS1(U1,V1);
2785       sline->Value(1).ParametersOnS2(U2,V2);
2786       aTPntF.SetValue(aSPnt,theArcTol,Standard_False);
2787       aTPntF.SetParameters(U1,V1,U2,V2);
2788       aTPntF.SetParameter(1.);
2789       wline->AddVertex(aTPntF);
2790       wline->SetFirstPoint(1);
2791
2792       if(hasInternals)
2793       {
2794         PutIntVertices(wline,sline,IsReversed,aVLine,theArcTol);
2795       }
2796
2797       aSPnt =  sline->Value(sline->NbPoints()).Value();
2798       sline->Value(sline->NbPoints()).ParametersOnS1(U1,V1);
2799       sline->Value(sline->NbPoints()).ParametersOnS2(U2,V2);
2800       aTPntL.SetValue(aSPnt,theArcTol,Standard_False);
2801       aTPntL.SetParameters(U1,V1,U2,V2);
2802       aTPntL.SetParameter(sline->NbPoints());
2803       wline->AddVertex(aTPntL);
2804       wline->SetLastPoint(wline->NbVertex());
2805
2806       IntPatch_SequenceOfLine segm;
2807       Standard_Boolean isSplited = SplitOnSegments(wline,Standard_False,
2808                       theLine->TransitionOnS1(),theLine->TransitionOnS2(),theArcTol,segm);
2809
2810       if(!isSplited)
2811       {
2812         theLines.Append(wline);
2813       }
2814       else
2815       {
2816         Standard_Integer nbsegms = segm.Length();
2817         Standard_Integer iseg = 0;
2818         for(iseg = 1; iseg <= nbsegms; iseg++)
2819           theLines.Append(segm(iseg));
2820       }
2821     }
2822     else
2823     {//theLine->ArcType() == IntPatch_Restriction
2824       if(!isDecomposited && !hasBeenDecomposed)
2825       {
2826         //The line has not been changed
2827         theLines.Append(Handle(IntPatch_RLine)::DownCast(theLine));
2828         return hasBeenDecomposed;
2829       }
2830
2831       IntPatch_Point aTPnt;
2832       gp_Pnt2d aPSurf;
2833       gp_Pnt aSPnt;
2834
2835       Handle(IntPatch_RLine) aRLine = new IntPatch_RLine(*Handle(IntPatch_RLine)::DownCast(theLine));
2836       
2837       aRLine->ClearVertexes();
2838       aRLine->SetCurve(sline);
2839
2840       if(hasInternals)
2841       {
2842         PutIntVertices(aRLine,sline,IsReversed,aVLine,theArcTol);
2843       }
2844
2845       const Handle(Adaptor2d_HCurve2d)& anArc = aRLine->IsArcOnS1() ?
2846                                                 aRLine->ArcOnS1() :
2847                                                 aRLine->ArcOnS2();
2848
2849       Standard_Real aFPar = anArc->FirstParameter(),
2850                     aLPar = anArc->LastParameter();
2851
2852       const IntSurf_PntOn2S &aRFirst = sline->Value(1),
2853                             &aRLast = sline->Value(sline->NbPoints());
2854
2855       const gp_Lin2d aLin(anArc->Curve2d().Line());
2856       
2857       for(Standard_Integer aFLIndex = 0; aFLIndex < 2; aFLIndex++)
2858       {
2859         if(aFLIndex == 0)
2860         {
2861           aRFirst.Parameters(U1, V1, U2, V2);
2862           aSPnt.SetXYZ(aRFirst.Value().XYZ());
2863         }
2864         else
2865         {
2866           aRLast.Parameters(U1, V1, U2, V2);
2867           aSPnt.SetXYZ(aRLast.Value().XYZ());
2868         }
2869
2870         if(IsReversed)
2871         {
2872           aPSurf.SetCoord(U1, V1);
2873         }
2874         else
2875         {
2876           aPSurf.SetCoord(U2, V2);
2877         }
2878
2879         Standard_Real aPar = ElCLib::Parameter(aLin, aPSurf);
2880
2881         if(aFLIndex == 0)
2882         {
2883           aFPar = Max(aFPar, aPar);
2884           aPar = aFPar;
2885         }
2886         else
2887         {
2888           aLPar = Min(aLPar, aPar);
2889           aPar = aLPar;
2890         }
2891
2892         aTPnt.SetParameter(aPar);
2893         aTPnt.SetValue(aSPnt,theArcTol,Standard_False);
2894         aTPnt.SetParameters(U1, V1, U2, V2);
2895
2896         aRLine->AddVertex(aTPnt);
2897       }
2898
2899       if(aLPar - aFPar > Precision::PConfusion())
2900       {
2901         aRLine->SetFirstPoint(1);
2902         aRLine->SetLastPoint(aRLine->NbVertex());
2903
2904         anArc->Trim(aFPar, aLPar, theArcTol);
2905
2906         theLines.Append(aRLine);
2907       }
2908     }
2909
2910     if(isDecomposited)
2911     {
2912       aFindex = aBindex;
2913       flNextLine = hasBeenDecomposed = Standard_True;
2914     }
2915   }
2916
2917   return hasBeenDecomposed;
2918 }
2919
2920 //=======================================================================
2921 //function : CheckSegmSegm
2922 //purpose  : Returns TRUE if the segment [theParF, theParL] is included
2923 //            in the segment [theRefParF, theRefParL] segment.
2924 //=======================================================================
2925 static Standard_Boolean CheckSegmSegm(const Standard_Real theRefParF,
2926                                       const Standard_Real theRefParL,
2927                                       const Standard_Real theParF,
2928                                       const Standard_Real theParL)
2929 {
2930   if((theParF < theRefParF) || (theParF > theRefParL))
2931   {
2932     return Standard_False;
2933   }
2934
2935   if((theParL < theRefParF) || (theParL > theRefParL))
2936   {
2937     return Standard_False;
2938   }
2939
2940   return Standard_True;
2941 }
2942
2943 //=======================================================================
2944 //function : IsCoincide
2945 //purpose  : Check, if theLine is coincided with theArc (in 2d-space).
2946 //
2947 // Attention!!!
2948 //            Cases when theArc is not 2d-line adaptor are suppored by
2949 //          TopOpeBRep classes only (i.e. are archaic).
2950 //=======================================================================
2951 Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
2952                             const Handle(IntPatch_PointLine)& theLine,
2953                             const Handle(Adaptor2d_HCurve2d)& theArc,
2954                             const Standard_Boolean isTheSurface1Using, //Surf1 is parametric?
2955                             const Standard_Real theToler3D,
2956                             const Standard_Real theToler2D,
2957                             const Standard_Real thePeriod) // Period of parametric surface in direction which is perpendicular to theArc direction.
2958 {
2959   if(theLine->ArcType() == IntPatch_Restriction)
2960   {//Restriction-restriction processing
2961     const Handle(IntPatch_RLine)& aRL2 = Handle(IntPatch_RLine)::DownCast(theLine);
2962     const Handle(Adaptor2d_HCurve2d)& anArc = aRL2->IsArcOnS1() ? aRL2->ArcOnS1() : aRL2->ArcOnS2();
2963     
2964     if(anArc->Curve2d().GetType() != GeomAbs_Line)
2965     {
2966       //Restriction line must be isoline.
2967       //Other cases are not supported by
2968       //existing algorithms.
2969
2970       return Standard_False;
2971     }
2972
2973     const gp_Lin2d aLin1(theArc->Curve2d().Line()),
2974                    aLin2(anArc->Curve2d().Line());
2975
2976     if(!aLin1.Direction().IsParallel(aLin2.Direction(), Precision::Angular()))
2977     {
2978       return Standard_False;
2979     }
2980
2981     const Standard_Real aDist = 
2982             theArc->Curve2d().Line().Distance(anArc->Curve2d().Line());
2983     if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
2984     {
2985       const Standard_Real aRf = theArc->FirstParameter(),
2986                           aRl = theArc->LastParameter();
2987       const Standard_Real aParf = anArc->FirstParameter(),
2988                           aParl = anArc->LastParameter();
2989       const gp_Pnt2d aP1(ElCLib::Value(aParf, aLin2)),
2990                      aP2(ElCLib::Value(aParl, aLin2));
2991
2992       Standard_Real aParam1 = ElCLib::Parameter(aLin1, aP1),
2993                     aParam2 = ElCLib::Parameter(aLin1, aP2);
2994
2995       if(CheckSegmSegm(aRf, aRl, aParam1, aParam2))
2996         return Standard_True;
2997
2998       //Lines are parallel. Therefore, there is no point in
2999       //projecting points to another line in order to check
3000       //if segment second line is included in segment of first one.
3001
3002       return CheckSegmSegm(aParam1, aParam2, aRf, aRl);
3003     }
3004
3005     return Standard_False;
3006   }
3007
3008   const Standard_Integer aNbPnts = theLine->NbPnts();
3009   const Standard_Real aUAf = theArc->FirstParameter(),
3010                       aUAl = theArc->LastParameter();
3011   const gp_Lin2d anArcLin(theArc->Curve2d().Line());
3012
3013   math_Vector aX(1, 2), aVal(1, 1);
3014
3015   for(Standard_Integer aPtID = 1; aPtID <= aNbPnts; aPtID++)
3016   {
3017     Standard_Real aUf = 0.0, aVf = 0.0;
3018     if(isTheSurface1Using)
3019       theLine->Point(aPtID).ParametersOnS1(aUf, aVf);
3020     else
3021       theLine->Point(aPtID).ParametersOnS2(aUf, aVf);
3022
3023     //Take 2d-point in parametric surface (because theArc is
3024     //2d-line in parametric surface).
3025     const gp_Pnt2d aPloc(aUf, aVf);
3026
3027     const Standard_Real aRParam = ElCLib::Parameter(anArcLin, aPloc);
3028
3029     if((aRParam < aUAf) || (aRParam > aUAl))
3030       return Standard_False;
3031
3032     const gp_Pnt2d aPmin(ElCLib::Value(aRParam, anArcLin));
3033     
3034     const Standard_Real aDist = aPloc.Distance(aPmin);
3035     if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
3036     {//Considered point is in Restriction line.
3037      //Go to the next point.
3038       continue;
3039     }
3040
3041     //Check if intermediate points between aPloc and theArc are
3042     //intersection point (i.e. if aPloc is in tangent zone between
3043     //two intersected surfaces).
3044
3045     const Standard_Real aUl = aPmin.X(), aVl = aPmin.Y();
3046
3047     const Standard_Integer aNbPoints = 4;
3048     const Standard_Real aStepU = (aUl - aUf)/aNbPoints,
3049                         aStepV = (aVl - aVf)/aNbPoints;
3050
3051     Standard_Real aU = aUf+aStepU, aV = aVf+aStepV;
3052     for(Standard_Integer i = 1; i < aNbPoints; i++)
3053     {
3054       aX.Value(1) = aU;
3055       aX.Value(2) = aV;
3056
3057       if(!theFunc.Value(aX, aVal))
3058       {
3059         return Standard_False;
3060       }
3061
3062       if(Abs(aVal(1)) > theToler3D)
3063       {
3064         return Standard_False;
3065       }
3066       
3067       aU += aStepU;
3068       aV += aStepV;
3069     }
3070   }
3071
3072   return Standard_True;
3073 }