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