0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / IntPatch / IntPatch_LineConstructor.cxx
1 // Created on: 1996-11-07
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1996-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_LineConstructor.ixx>
18
19 #include <IntPatch_GLine.hxx>
20 #include <IntPatch_ALine.hxx>
21 #include <IntPatch_WLine.hxx>
22 #include <IntPatch_RLine.hxx>
23 #include <Adaptor2d_HCurve2d.hxx>
24
25 #define XPU1009 1
26
27 #include <gp_Pnt.hxx>
28 #include <gp_Vec.hxx>
29 #include <IntSurf_Quadric.hxx>
30 #include <IntSurf_PntOn2S.hxx>
31 #include <Standard_ConstructionError.hxx>
32 #include <GeomAbs_SurfaceType.hxx>
33 #include <ElCLib.hxx>
34 #include <Geom2dInt_TheProjPCurOfGInter.hxx>
35 #include <TColStd_SequenceOfInteger.hxx>
36 #include <TColStd_IndexedMapOfTransient.hxx>
37 #include <TColStd_Array1OfTransient.hxx>
38 #include <TColStd_Array1OfReal.hxx>
39
40
41 //=======================================================================
42 //function : Recadre
43 //purpose  : 
44 //=======================================================================
45
46 static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
47                     const Handle(Adaptor3d_HSurface)& myHS2,
48                     Standard_Real& u1,
49                     Standard_Real& v1,
50                     Standard_Real& u2,
51                     Standard_Real& v2) { 
52   Standard_Real f,l,lmf;
53   GeomAbs_SurfaceType typs1 = myHS1->GetType();
54   GeomAbs_SurfaceType typs2 = myHS2->GetType();
55
56   Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
57   switch (typs1) { 
58   case GeomAbs_Cylinder:
59   case GeomAbs_Cone:
60   case GeomAbs_Sphere: 
61     { 
62       myHS1IsUPeriodic = Standard_True;
63       myHS1IsVPeriodic = Standard_False;
64       break;
65     }
66   case GeomAbs_Torus:
67     {
68       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
69       break;
70     }
71   default:
72      {
73        //-- Le cas de biparametrees periodiques est gere en amont
74        myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
75        break;
76      }
77   }
78
79   Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
80   switch (typs2) { 
81   case GeomAbs_Cylinder:
82   case GeomAbs_Cone:
83   case GeomAbs_Sphere: 
84     { 
85       myHS2IsUPeriodic = Standard_True;
86       myHS2IsVPeriodic = Standard_False;
87       break;
88     }
89   case GeomAbs_Torus:
90     {
91       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
92       break;
93     }
94   default:
95      {
96        //-- Le cas de biparametrees periodiques est gere en amont
97        myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
98        break;
99      }
100   }
101   if(myHS1IsUPeriodic) {
102     lmf = M_PI+M_PI; //-- myHS1->UPeriod();
103     f = myHS1->FirstUParameter();
104     l = myHS1->LastUParameter();
105     while(u1 < f) { u1+=lmf; } 
106     while(u1 > l) { u1-=lmf; }
107   }
108   if(myHS1IsVPeriodic) {
109     lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
110     f = myHS1->FirstVParameter();
111     l = myHS1->LastVParameter();
112     while(v1 < f) { v1+=lmf; } 
113     while(v1 > l) { v1-=lmf; }
114   }
115   if(myHS2IsUPeriodic) { 
116     lmf = M_PI+M_PI; //-- myHS2->UPeriod();
117     f = myHS2->FirstUParameter();
118     l = myHS2->LastUParameter();
119     while(u2 < f) { u2+=lmf; } 
120     while(u2 > l) { u2-=lmf; }
121   }
122   if(myHS2IsVPeriodic) { 
123     lmf = M_PI+M_PI; //-- myHS2->VPeriod();
124     f = myHS2->FirstVParameter();
125     l = myHS2->LastVParameter();
126     while(v2 < f) { v2+=lmf; } 
127     while(v2 > l) { v2-=lmf; }
128   }
129 }
130
131 //=======================================================================
132 //function : Parameters
133 //purpose  : 
134 //=======================================================================
135
136 static void Parameters(const Handle(Adaptor3d_HSurface)& myHS1,
137                        const Handle(Adaptor3d_HSurface)& myHS2,
138                        const gp_Pnt& Ptref,
139                        Standard_Real& U1,
140                        Standard_Real& V1,
141                        Standard_Real& U2,
142                        Standard_Real& V2)
143 {
144   IntSurf_Quadric quad1,quad2;
145   GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
146   switch (typs) {
147   case GeomAbs_Plane:
148     quad1.SetValue(myHS1->Surface().Plane());
149     break;
150   case GeomAbs_Cylinder:
151     quad1.SetValue(myHS1->Surface().Cylinder());
152     break;
153   case GeomAbs_Cone:
154     quad1.SetValue(myHS1->Surface().Cone());
155     break;
156   case GeomAbs_Sphere:
157     quad1.SetValue(myHS1->Surface().Sphere());
158     break;
159   case GeomAbs_Torus:
160     quad1.SetValue(myHS1->Surface().Torus());
161     break;
162   default:
163     Standard_ConstructionError::Raise("IntPatch_IntSS::MakeCurve");
164   }
165   
166   typs = myHS2->Surface().GetType();
167   switch (typs) {
168   case GeomAbs_Plane:
169     quad2.SetValue(myHS2->Surface().Plane());
170     break;
171   case GeomAbs_Cylinder:
172     quad2.SetValue(myHS2->Surface().Cylinder());
173     break;
174   case GeomAbs_Cone:
175     quad2.SetValue(myHS2->Surface().Cone());
176     break;
177   case GeomAbs_Sphere:
178     quad2.SetValue(myHS2->Surface().Sphere());
179     break;
180   case GeomAbs_Torus:
181     quad2.SetValue(myHS2->Surface().Torus());
182     break;
183   default:
184     Standard_ConstructionError::Raise("IntPatch_IntSS::MakeCurve");
185   }
186   quad1.Parameters(Ptref,U1,V1);
187   quad2.Parameters(Ptref,U2,V2);
188 }
189
190 //=======================================================================
191 //function : LocalFirstParameter
192 //purpose  : 
193 //=======================================================================
194
195 static Standard_Real LocalFirstParameter (const Handle(IntPatch_Line)& L)
196 {
197   Standard_Real firstp =0.;
198   IntPatch_IType typl = L->ArcType();
199   switch (typl) {
200   case IntPatch_Analytic:
201     {
202       Handle(IntPatch_ALine)& alin = Handle(IntPatch_ALine)::DownCast (L);
203       if (alin->HasFirstPoint()) {
204         firstp = alin->FirstPoint().ParameterOnLine();
205       }
206       else {
207         Standard_Boolean included;
208         firstp = alin->FirstParameter(included);
209         if (!included) {
210           firstp +=Epsilon(firstp);
211         }
212       }
213       return firstp;
214     }
215
216   case IntPatch_Restriction:
217     {
218       Handle(IntPatch_RLine)& rlin = Handle(IntPatch_RLine)::DownCast (L);
219       if (rlin->HasFirstPoint()) {
220         firstp = rlin->FirstPoint().ParameterOnLine();
221       }
222       else {
223         firstp = -Precision::Infinite(); // a voir selon le type de la ligne 2d
224       }
225       return firstp;
226     }
227    case IntPatch_Walking:
228     {
229       
230       Handle(IntPatch_WLine)& wlin = Handle(IntPatch_WLine)::DownCast (L);
231       if (wlin->HasFirstPoint()) {
232         firstp = wlin->FirstPoint().ParameterOnLine();
233       }
234       else {
235         firstp = 1.;
236       }
237       return firstp;
238     }
239         
240   default:
241     {
242       Handle(IntPatch_GLine)& glin = Handle(IntPatch_GLine)::DownCast (L);
243       if (glin->HasFirstPoint()) {
244         firstp = glin->FirstPoint().ParameterOnLine();
245       }
246       else {
247         switch (typl) {
248         case IntPatch_Lin:
249         case IntPatch_Parabola:
250         case IntPatch_Hyperbola:
251           firstp = -Precision::Infinite();
252           break;
253
254         case IntPatch_Circle:
255         case IntPatch_Ellipse:
256           firstp = 0.;
257           break;
258         default:
259           {
260           }
261         }
262       }
263       return firstp;
264     }
265   }
266 //  return firstp;
267 }
268
269 //=======================================================================
270 //function : LocalLastParameter
271 //purpose  : 
272 //=======================================================================
273
274 static Standard_Real LocalLastParameter (const Handle(IntPatch_Line)& L)
275 {
276   Standard_Real lastp =0.;
277   IntPatch_IType typl = L->ArcType();
278   switch (typl) {
279   case IntPatch_Analytic:
280     {
281       Handle(IntPatch_ALine)& alin = Handle(IntPatch_ALine)::DownCast (L);
282
283       if (alin->HasLastPoint()) {
284         lastp = alin->LastPoint().ParameterOnLine();
285       }
286       else {
287         Standard_Boolean included;
288         lastp = alin->LastParameter(included);
289         if (!included) {
290           lastp -=Epsilon(lastp);
291         }
292       }
293       return lastp;
294     }
295
296   case IntPatch_Restriction:
297     {
298       Handle(IntPatch_RLine)& rlin = Handle(IntPatch_RLine)::DownCast (L);
299       
300       if (rlin->HasLastPoint()) {
301         lastp = rlin->LastPoint().ParameterOnLine();
302       }
303       else {
304         lastp = Precision::Infinite(); // a voir selon le type de la ligne 2d
305       }
306       return lastp;
307     }
308    case IntPatch_Walking:
309     {
310       Handle(IntPatch_WLine)& wlin = Handle(IntPatch_WLine)::DownCast (L);
311
312       if (wlin->HasLastPoint()) {
313         lastp = wlin->LastPoint().ParameterOnLine();
314       }
315       else {
316         lastp = wlin->NbPnts();
317       }
318       return lastp;
319     }
320         
321   default:
322     {
323       Handle(IntPatch_GLine)& glin = Handle(IntPatch_GLine)::DownCast (L);
324       
325       if (glin->HasLastPoint()) {
326         lastp = glin->LastPoint().ParameterOnLine();
327       }
328       else {
329         switch (typl) {
330         case IntPatch_Lin:
331         case IntPatch_Parabola:
332         case IntPatch_Hyperbola:
333           lastp = Precision::Infinite();
334           break;
335
336         case IntPatch_Circle:
337         case IntPatch_Ellipse:
338           lastp = M_PI+M_PI;
339           break;
340         default:
341           {
342           }
343         }
344       }
345       return lastp;
346     }
347   }
348 }
349
350
351 // modified by NIZHNY-MKK  Tue Apr  3 15:03:06 2001.BEGIN
352 //=======================================================================
353 //function : ComputeParametricTolerance
354 //purpose  : 
355 //=======================================================================
356
357 static Standard_Real ComputeParametricTolerance(const Standard_Real theTol3d,
358                                                 const gp_Vec&       theD1u,
359                                                 const gp_Vec&       theD1v) {
360   Standard_Real nad1u = theD1u.Magnitude();
361   Standard_Real nad1v = theD1v.Magnitude();
362   Standard_Real tolu = 0., tolv = 0.;
363   if(nad1u > 1e-12) 
364     tolu = theTol3d/nad1u; 
365   else tolu = 0.1;
366   if(nad1v > 1e-12) 
367     tolv = theTol3d/nad1v; 
368   else tolv = 0.1;
369   Standard_Real aTolerance = (tolu > tolv) ? tolu : tolv;
370   return aTolerance;
371 }
372 // modified by NIZHNY-MKK  Tue Apr  3 15:03:11 2001.END
373
374
375 //=======================================================================
376 //function : IntPatch_LineConstructor
377 //purpose  : 
378 //=======================================================================
379
380 IntPatch_LineConstructor::IntPatch_LineConstructor(const Standard_Integer )
381 {
382 }
383
384 //=======================================================================
385 //function : AppendSameVertexA
386 //purpose  : 
387 //=======================================================================
388
389 static Standard_Integer AppendSameVertexA(Handle(IntPatch_ALine)&alig,
390                                   const Handle(IntPatch_ALine)& L,
391                                   const Standard_Integer index,
392                                   Standard_Integer *TabIndex) { 
393   Standard_Integer i,a,n;
394   a=0;
395   n=L->NbVertex();
396   const IntPatch_Point& Vtxindex = L->Vertex(index);
397   Standard_Real thetol1=Vtxindex.Tolerance();
398   for(i=1;i<=n;i++) { 
399     if(i!=index) { 
400       const IntPatch_Point& Vtxi = L->Vertex(i);
401       Standard_Real thetol2=Vtxi.Tolerance();
402       if(thetol2<thetol1) 
403         thetol2=thetol1;
404       Standard_Real d_4=Vtxindex.Value().Distance(Vtxi.Value());
405       if(d_4 <= thetol2) { 
406         alig->AddVertex(Vtxi);
407         a++;
408         TabIndex[i]=TabIndex[index];
409       }
410     }
411   }
412   return(a);
413 }
414
415 //=======================================================================
416 //function : AppendSameVertexG
417 //purpose  : 
418 //=======================================================================
419
420 static Standard_Integer AppendSameVertexG(Handle(IntPatch_GLine)& glig,const Handle(IntPatch_GLine)&L,
421                                   const Standard_Integer index,
422                                   const Standard_Real decal,
423                                   Standard_Integer *TabIndex) { 
424   Standard_Integer i,a,n;
425   Standard_Real p1,p2,d; //,tol
426   Standard_Boolean aajouter;
427   a=0;
428   n=L->NbVertex();
429   const IntPatch_Point& Vtxindex = L->Vertex(index);
430   Standard_Real thetol1=Vtxindex.Tolerance();
431   for(i=1;i<=n;i++) { 
432     if(i!=index) { 
433       const IntPatch_Point& Vtxi = L->Vertex(i);
434       aajouter=Standard_False;
435       Standard_Real thetol2=Vtxi.Tolerance();
436       if(thetol2<thetol1) 
437         thetol2=thetol1;
438       d=Vtxindex.Value().Distance(Vtxi.Value());
439       if(d <= thetol2) { 
440         aajouter=Standard_True;
441       }
442       
443       
444       //-- Le test suivant a ete ajoute le 20 aout 98 (??? mefiance ???) 
445       else { 
446         p1=Vtxindex.ParameterOnLine();
447         p2=Vtxi.ParameterOnLine();
448         if(Abs(p1-p2)<Precision::PConfusion()) { 
449           aajouter=Standard_True;
450         }
451       }
452       if(aajouter) { 
453         p1= Vtxindex.ParameterOnLine();
454         IntPatch_Point aVtx = Vtxi;
455         aVtx.SetParameter(p1+decal);
456         glig->AddVertex(aVtx);
457         a++;
458         TabIndex[i]=TabIndex[index];
459       }
460     }
461   }
462   return(a);
463 }
464
465 //=======================================================================
466 //function : AppendSameVertexW
467 //purpose  : 
468 //=======================================================================
469
470 static Standard_Integer AppendSameVertexW(Handle(IntPatch_WLine)& wlig,
471                                   const Handle(IntPatch_WLine)&L,
472                                   const Standard_Integer index,
473                                   const Standard_Real par,
474                                   Standard_Integer *TabIndex) { 
475   Standard_Integer i,a,n;
476   a=0;
477   n=L->NbVertex();
478   const IntPatch_Point& Vtxindex = L->Vertex(index);
479   const gp_Pnt& Pntindex = Vtxindex.Value();
480   Standard_Real thetol1=Vtxindex.Tolerance();
481   for(i=1;i<=n;i++) { 
482     if(i!=index) { 
483       IntPatch_Point Vtxi = L->Vertex(i);
484       Standard_Real d_2 = Pntindex.Distance(Vtxi.Value());
485       Standard_Real thetol2=Vtxi.Tolerance();
486       if(thetol2<thetol1) 
487         thetol2=thetol1;
488       //-- le debugger voit 2 fois la variable d ici. ???? -> d_2
489       if(d_2 <= thetol2) { 
490         Vtxi.SetParameter(par);
491         Standard_Real u1,v1,u2,v2;
492         Vtxindex.ParametersOnS1(u1,v1);
493         Vtxindex.ParametersOnS2(u2,v2);
494         Vtxi.SetParameters(u1,v1,u2,v2);
495         Vtxi.SetValue(Pntindex);
496         wlig->AddVertex(Vtxi);
497         a++;
498         TabIndex[i]=TabIndex[index];
499       }
500     }
501   }
502   return(a);
503 }
504
505 //=======================================================================
506 //function : AppendSameVertexR
507 //purpose  : 
508 //=======================================================================
509
510 static Standard_Integer AppendSameVertexR(Handle(IntPatch_RLine)&rlig,
511                                   const Handle(IntPatch_RLine)& L,
512                                   const Standard_Integer index,
513                                   Standard_Integer *TabIndex) { 
514   Standard_Integer i,a,n;
515   a=0;
516   n=L->NbVertex();
517   const IntPatch_Point& Vtxindex = L->Vertex(index);
518   Standard_Real thetol1=Vtxindex.Tolerance();
519   for(i=1;i<=n;i++) { 
520     if(i!=index) { 
521       const IntPatch_Point& Vtxi = L->Vertex(i);
522       Standard_Real d_3=Vtxindex.Value().Distance(Vtxi.Value());
523       Standard_Real thetol2=Vtxi.Tolerance();
524       if(thetol2<thetol1) 
525         thetol2=thetol1;
526       if(d_3<thetol2) { 
527         if(Vtxi.ParameterOnLine() != Vtxindex.ParameterOnLine()) { 
528           IntPatch_Point Vtxicop = L->Vertex(i);
529           Vtxicop.SetParameter(Vtxindex.ParameterOnLine());
530           rlig->AddVertex(Vtxicop);
531         }
532         else { 
533           rlig->AddVertex(Vtxi);
534         }
535         a++;
536         TabIndex[i]=TabIndex[index];
537       }
538     }
539   }
540   return(a);
541 }
542
543 //=======================================================================
544 //function : AddLine
545 //purpose  : 
546 //=======================================================================
547
548 static void AddLine(const Handle(IntPatch_Line)& L,
549              const Standard_Integer i,
550              const Standard_Integer j,
551 //           const GeomAbs_SurfaceType TypeS1,
552              const GeomAbs_SurfaceType ,
553 //           const GeomAbs_SurfaceType TypeS2,
554              const GeomAbs_SurfaceType ,
555              Standard_Integer *TabIndex,
556              IntPatch_SequenceOfLine& slin) { 
557   Standard_Integer IndexFirstVertex = 1;
558   Standard_Integer IndexLastVertex  = 2;
559   if(i==j) { 
560     IndexLastVertex  = 1;
561   }
562   IntPatch_IType typl = L->ArcType();
563   switch (typl) {
564     case IntPatch_Analytic: { 
565       Handle(IntPatch_ALine)& ALine = Handle(IntPatch_ALine)::DownCast (L);
566       Handle(IntPatch_ALine) alig;
567       if(L->TransitionOnS1() == IntSurf_Undecided)
568         alig = new IntPatch_ALine(ALine->Curve(),L->IsTangent());
569       else if(L->TransitionOnS1() == IntSurf_Touch)
570         alig = new IntPatch_ALine(ALine->Curve(),L->IsTangent(),L->SituationS1(),L->SituationS2());
571       else
572         alig = new IntPatch_ALine(ALine->Curve(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
573       alig->AddVertex(ALine->Vertex(i));
574       IndexLastVertex+=AppendSameVertexA(alig,ALine,i,TabIndex);
575       if(i!=j) { 
576         alig->AddVertex(ALine->Vertex(j));
577         IndexLastVertex+=AppendSameVertexA(alig,ALine,j,TabIndex);
578       }
579       alig->SetFirstPoint(IndexFirstVertex);
580       alig->SetLastPoint(IndexLastVertex);
581       slin.Append(alig);
582       break;
583     }
584     case IntPatch_Walking: {  //-- ****************************************
585       Handle(IntPatch_WLine)& WLine = Handle(IntPatch_WLine)::DownCast (L);
586       const Handle(IntSurf_LineOn2S)& Lori = WLine->Curve();
587       Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
588       Standard_Integer ParamMinOnLine = (Standard_Integer) WLine->Vertex(i).ParameterOnLine();   
589       Standard_Integer ParamMaxOnLine = (Standard_Integer) WLine->Vertex(j).ParameterOnLine();
590       for(Standard_Integer k=ParamMinOnLine; k<=ParamMaxOnLine; k++) { 
591         LineOn2S->Add(Lori->Value(k));
592       }
593       Handle(IntPatch_WLine) wlig;
594       if(L->TransitionOnS1() == IntSurf_Undecided)
595         wlig = new IntPatch_WLine(LineOn2S,L->IsTangent());
596       else if(L->TransitionOnS1() == IntSurf_Touch)
597         wlig = new IntPatch_WLine(LineOn2S,L->IsTangent(),L->SituationS1(),L->SituationS2());
598       else
599         wlig = new IntPatch_WLine(LineOn2S,L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
600       if(WLine->HasArcOnS1()) { 
601         wlig->SetArcOnS1(WLine->GetArcOnS1());
602       }
603       if(WLine->HasArcOnS2()) { 
604         wlig->SetArcOnS2(WLine->GetArcOnS2());
605       }
606       IntPatch_Point Vtx=WLine->Vertex(i);
607       Vtx.SetParameter(1);
608       wlig->AddVertex(Vtx);
609       IndexLastVertex+=AppendSameVertexW(wlig,WLine,i,1,TabIndex);
610       if(i!=j) { 
611         Vtx=WLine->Vertex(j);
612         Vtx.SetParameter(LineOn2S->NbPoints());
613         wlig->AddVertex(Vtx);
614         IndexLastVertex+=AppendSameVertexW(wlig,WLine,j,LineOn2S->NbPoints(),TabIndex);
615       }
616       wlig->SetFirstPoint(IndexFirstVertex);
617       wlig->SetLastPoint(IndexLastVertex);
618       wlig->SetPeriod(WLine->U1Period(),WLine->V1Period(),WLine->U2Period(),WLine->V2Period());
619       wlig->ComputeVertexParameters(Precision::Confusion());
620       slin.Append(wlig);
621       //-- **********************************************************************
622
623       break;
624     }
625     case IntPatch_Restriction: { 
626       Handle(IntPatch_RLine)& RLine = Handle(IntPatch_RLine)::DownCast (L);
627       IndexLastVertex=2;
628       IndexFirstVertex=1;
629       Handle(IntPatch_RLine) rlig;
630       if(L->TransitionOnS1() == IntSurf_Undecided)
631         rlig = new IntPatch_RLine(L->IsTangent());
632       else if(L->TransitionOnS1() == IntSurf_Touch)
633         rlig = new IntPatch_RLine(L->IsTangent(),L->SituationS1(),L->SituationS2());
634       else
635         rlig = new IntPatch_RLine(L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
636       if(RLine->IsArcOnS1()) { rlig->SetArcOnS1(RLine->ArcOnS1()); } 
637       if(RLine->IsArcOnS2()) { rlig->SetArcOnS2(RLine->ArcOnS2()); } 
638
639       rlig->AddVertex(RLine->Vertex(i));     
640 #if XPU1009
641       IndexLastVertex+=AppendSameVertexR(rlig,RLine,i,TabIndex);
642 #endif
643       for(Standard_Integer k=i+1; k<j;k++) { 
644         rlig->AddVertex(RLine->Vertex(k));
645         IndexLastVertex++;
646       }
647       if(i!=j) { 
648         rlig->AddVertex(RLine->Vertex(j)); 
649 #if XPU1009     
650         IndexLastVertex+=AppendSameVertexR(rlig,RLine,j,TabIndex);
651 #endif
652       }
653       rlig->SetFirstPoint(IndexFirstVertex);
654       rlig->SetLastPoint(IndexLastVertex);
655       rlig->ComputeVertexParameters(Precision::Confusion());
656       slin.Append(rlig);
657       break;
658     }
659     case IntPatch_Lin:
660     case IntPatch_Parabola:
661     case IntPatch_Hyperbola:
662     case IntPatch_Circle:
663     case IntPatch_Ellipse: { 
664       Handle(IntPatch_GLine)& GLine = Handle(IntPatch_GLine)::DownCast (L);
665       Handle(IntPatch_GLine) glig;
666       switch (typl) {
667       case IntPatch_Lin:
668         if(L->TransitionOnS1() == IntSurf_Undecided)
669           glig = new IntPatch_GLine(GLine->Line(),L->IsTangent());
670         else if(L->TransitionOnS1() == IntSurf_Touch)
671           glig = new IntPatch_GLine(GLine->Line(),L->IsTangent(),L->SituationS1(),L->SituationS2());
672         else
673           glig = new IntPatch_GLine(GLine->Line(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
674         break;
675       case IntPatch_Parabola:
676         if(L->TransitionOnS1() == IntSurf_Undecided)
677           glig = new IntPatch_GLine(GLine->Parabola(),L->IsTangent());
678         else if(L->TransitionOnS1() == IntSurf_Touch)
679           glig = new IntPatch_GLine(GLine->Parabola(),L->IsTangent(),L->SituationS1(),L->SituationS2());
680         else
681           glig = new IntPatch_GLine(GLine->Parabola(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
682         break;
683       case IntPatch_Hyperbola:
684         if(L->TransitionOnS1() == IntSurf_Undecided)
685           glig = new IntPatch_GLine(GLine->Hyperbola(),L->IsTangent());
686         else if(L->TransitionOnS1() == IntSurf_Touch)
687           glig = new IntPatch_GLine(GLine->Hyperbola(),L->IsTangent(),L->SituationS1(),L->SituationS2());
688         else
689           glig = new IntPatch_GLine(GLine->Hyperbola(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
690         break;
691       case IntPatch_Circle:
692         if(L->TransitionOnS1() == IntSurf_Undecided)
693           glig = new IntPatch_GLine(GLine->Circle(),L->IsTangent());
694         else if(L->TransitionOnS1() == IntSurf_Touch)
695           glig = new IntPatch_GLine(GLine->Circle(),L->IsTangent(),L->SituationS1(),L->SituationS2());
696         else
697           glig = new IntPatch_GLine(GLine->Circle(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
698         break;
699       case IntPatch_Ellipse: default:
700         if(L->TransitionOnS1() == IntSurf_Undecided)
701           glig = new IntPatch_GLine(GLine->Ellipse(),L->IsTangent());
702         else if(L->TransitionOnS1() == IntSurf_Touch)
703           glig = new IntPatch_GLine(GLine->Ellipse(),L->IsTangent(),L->SituationS1(),L->SituationS2());
704         else
705           glig = new IntPatch_GLine(GLine->Ellipse(),L->IsTangent(),L->TransitionOnS1(),L->TransitionOnS2());
706         break;
707       }
708       glig->AddVertex(GLine->Vertex(i));
709       IndexLastVertex+=AppendSameVertexG(glig,GLine,i,0,TabIndex);
710       if(i!=j) { 
711         if ((typl == IntPatch_Circle || typl == IntPatch_Ellipse) && i>j) {
712           IntPatch_Point Vtx=GLine->Vertex(j);
713           Vtx.SetParameter(GLine->Vertex(j).ParameterOnLine()+M_PI+M_PI);
714           glig->AddVertex(Vtx);
715           IndexLastVertex+=AppendSameVertexG(glig,GLine,j,M_PI+M_PI,TabIndex);
716         }
717         else {
718           glig->AddVertex(GLine->Vertex(j));
719           IndexLastVertex+=AppendSameVertexG(glig,GLine,j,0,TabIndex);
720         }
721       }
722       glig->SetFirstPoint(IndexFirstVertex);
723       glig->SetLastPoint(IndexLastVertex);
724       slin.Append(glig);
725       break;
726     }
727     default: { 
728       Standard_ConstructionError::Raise("IntPatch_LineConstructor::AddLine");
729     }
730       break;
731     }
732 }
733
734 //=======================================================================
735 //function : Line
736 //purpose  : 
737 //=======================================================================
738
739 Handle(IntPatch_Line) IntPatch_LineConstructor::Line(const Standard_Integer l) const { 
740   return(slin.Value(l));
741 }
742
743 //=======================================================================
744 //function : NbLines
745 //purpose  : 
746 //=======================================================================
747
748 Standard_Integer IntPatch_LineConstructor::NbLines() const { 
749   return(slin.Length());
750 }
751
752 //=======================================================================
753 //function : GetVertexTolerance
754 //purpose  : 
755 //=======================================================================
756
757 static Standard_Real GetVertexTolerance(const IntPatch_Point& vtx/*,
758                                         const Handle(Adaptor3d_TopolTool)& aDomain1,
759                                         const Handle(Adaptor3d_TopolTool)& aDomain2*/)
760 {
761   Standard_Real tol = vtx.Tolerance();
762 //    if (aDomain1->Has3d() && vtx.IsVertexOnS1()) {
763 //      Standard_Real tolv = aDomain1->Tol3d(vtx.VertexOnS1());
764 //      if (tolv > tol) tol = tolv;
765 //    }
766 //    if (aDomain2->Has3d() && vtx.IsVertexOnS2()) {
767 //      Standard_Real tolv = aDomain2->Tol3d(vtx.VertexOnS2());
768 //      if (tolv > tol) tol = tolv;
769 //    }
770   return tol;
771 }
772
773 //=======================================================================
774 //function : IsSegmentSmall
775 //purpose  : 
776 //=======================================================================
777
778 static Standard_Boolean IsSegmentSmall(const Handle(IntPatch_WLine)& WLine,
779                                        const Standard_Integer ivFirst,
780                                        const Standard_Integer ivLast/*,
781                                        const Standard_Real TolArc*/)
782 {
783   const IntPatch_Point& vtxF = WLine->Vertex(ivFirst);
784   const IntPatch_Point& vtxL = WLine->Vertex(ivLast);
785   Standard_Integer ipF = (Standard_Integer) vtxF.ParameterOnLine();
786   Standard_Integer ipL = (Standard_Integer) vtxL.ParameterOnLine();
787   if (ipF >= ipL) return Standard_True;
788
789   Standard_Real tolF = GetVertexTolerance(vtxF);
790   Standard_Real tolL = GetVertexTolerance(vtxL);
791   Standard_Real tol = Max (tolF, tolL);
792
793   Standard_Real len = 0.;
794   gp_Pnt p1 = WLine->Point(ipF).Value();
795   for (Standard_Integer i=ipF+1; i <= ipL; i++) {
796     const gp_Pnt& p2 = WLine->Point(i).Value();
797     len += p1.Distance(p2);
798     if (len > tol) break;
799     p1 = p2;
800   }
801   return len <= tol;
802 }
803
804 //=======================================================================
805 //function : TestWLineIsARLine
806 //purpose  : 
807 //=======================================================================
808
809 static Standard_Boolean TestWLineIsARLine(const IntPatch_SequenceOfLine& slinref,
810                                           const Handle(IntPatch_WLine)& wlin,
811                                           const Standard_Real tol2d) {
812   int nbpnt=wlin->NbPnts();
813   int indicepnt=nbpnt/2;
814   if(indicepnt<1) return(Standard_False);
815   const IntSurf_PntOn2S& POn2S=wlin->Point(indicepnt);
816   const IntSurf_PntOn2S& POn2S1=wlin->Point(indicepnt+1);
817   Standard_Integer lastl=slinref.Length();
818   for(int i=1;i<=lastl;i++) { 
819     if(slinref.Value(i)->ArcType()==IntPatch_Restriction) { 
820       Handle(IntPatch_RLine)& rlin = *((Handle(IntPatch_RLine) *)&(slinref(i)));
821       for (Standard_Integer is=0; is<2; is++) {
822         Standard_Boolean onFirst = is==0;
823         if((onFirst && rlin->IsArcOnS1()) || (!onFirst && rlin->IsArcOnS2())) {
824           Handle(Adaptor2d_HCurve2d) arc;
825           Standard_Real u,v,u1,v1;
826           if (onFirst) {
827             arc = rlin->ArcOnS1();
828             POn2S.ParametersOnS1(u,v);
829             POn2S1.ParametersOnS1(u1,v1);
830           }
831           else {
832             arc = rlin->ArcOnS2();
833             POn2S.ParametersOnS2(u,v);
834             POn2S1.ParametersOnS2(u1,v1);
835           }
836           if (indicepnt == 1) {
837             u = (u+u1)*0.5;
838             v = (v+v1)*0.5;
839           }
840           const Adaptor2d_Curve2d& C2d=arc->Curve2d();
841           gp_Pnt2d PObt,P2d(u,v);
842           Standard_Real par= Geom2dInt_TheProjPCurOfGInter::FindParameter(C2d,P2d,1e-7);
843           PObt=C2d.Value(par);
844           if(PObt.Distance(P2d) < tol2d) {
845             return Standard_True;
846           }
847         }
848       }
849     }
850   }
851   return Standard_False;
852 }
853
854 //=======================================================================
855 //function : TestIfWLineIsRestriction
856 //purpose  : 
857 //=======================================================================
858
859 static Standard_Boolean TestIfWLineIsRestriction(const IntPatch_SequenceOfLine& slinref,
860                                           const Handle(IntPatch_WLine)& wlin,
861                                           const Handle(Adaptor3d_HSurface)& S1,
862                                           const Handle(Adaptor3d_TopolTool)&D1,
863                                           const Handle(Adaptor3d_HSurface)& S2,
864                                           const Handle(Adaptor3d_TopolTool)&D2,
865                                           Standard_Real TolArc) { 
866
867   Standard_Integer NbPnts = wlin->NbPnts();
868   Standard_Integer allon1=0,allon2=0,i;
869   Standard_Real tol2d1=0., tol2d2=0.;
870   for(i=1;i<=NbPnts;i++) { 
871     const IntSurf_PntOn2S& Pmid = wlin->Point(i);
872     Standard_Real u1,v1,u2,v2;
873     Pmid.Parameters(u1,v1,u2,v2);
874     //-- Estimation d un majorant de Toluv a partir de Tol
875     gp_Pnt ap;
876     gp_Vec ad1u,ad1v;
877     Standard_Real tol;
878     //------------------------------------------
879     S1->D1(u1,v1,ap,ad1u,ad1v);
880     tol = ComputeParametricTolerance(TolArc,ad1u,ad1v);
881     if (tol > tol2d1) tol2d1 = tol;
882     //--
883     if(allon1+1 == i && D1->IsThePointOn(gp_Pnt2d(u1,v1),tol)) {
884       allon1++;
885     }
886     //------------------------------------------
887     S2->D1(u2,v2,ap,ad1u,ad1v);
888     tol = ComputeParametricTolerance(TolArc,ad1u,ad1v);
889     if (tol > tol2d2) tol2d2 = tol;
890     //--
891     if(allon2+1 == i && D2->IsThePointOn(gp_Pnt2d(u2,v2),tol)) { 
892       allon2++;
893     }
894     if(allon1!=i && allon2!=i) 
895       break;
896   }
897   if(allon1==NbPnts || allon2==NbPnts) {
898 #ifdef OCCT_DEBUG
899     cout<<" IntPatch_LineConstructor.gxx :  CC**ONS"<<(allon1==NbPnts?1:2)<<"** Traitement WLIne + ARC CLASS "<<endl;
900 #endif
901     Standard_Real tol2d = Max(tol2d1,tol2d2);
902     return TestWLineIsARLine(slinref,wlin,tol2d);
903   }
904   return Standard_False;
905 }
906
907 //=======================================================================
908 //function : ProjectOnArc
909 //purpose  : 
910 //=======================================================================
911
912 static Standard_Boolean ProjectOnArc(const Standard_Real u,
913                                      const Standard_Real v,
914                                      const Handle(Adaptor2d_HCurve2d)& arc,
915                                      const Handle(Adaptor3d_HSurface)& surf,
916                                      const Standard_Real TolArc,
917                                      Standard_Real& par,
918                                      Standard_Real& dist)
919 {
920   gp_Pnt aPbid;
921   gp_Vec ad1u, ad1v;
922   surf->D1(u,v,aPbid,ad1u,ad1v);
923   Standard_Real tol2d = ComputeParametricTolerance(TolArc,ad1u,ad1v);
924   const Adaptor2d_Curve2d& C2d=arc->Curve2d();
925   gp_Pnt2d aP(u,v),aPprj;
926   par=Geom2dInt_TheProjPCurOfGInter::FindParameter(C2d,aP,1e-7);
927   aPprj=C2d.Value(par);
928   dist = aPprj.Distance(aP);
929   return dist <= tol2d;
930 }
931
932 //=======================================================================
933 //function : TestWLineToRLine
934 //purpose  : 
935 //=======================================================================
936
937 static void TestWLineToRLine(const IntPatch_SequenceOfLine& slinref,
938                       IntPatch_SequenceOfLine& slin,
939                       const Handle(Adaptor3d_HSurface)& mySurf1,
940                       const Handle(Adaptor3d_TopolTool)& myDom1,
941                       const Handle(Adaptor3d_HSurface)& mySurf2,
942                       const Handle(Adaptor3d_TopolTool)& myDom2,
943                       const Standard_Real TolArc) { 
944
945   Standard_Integer lastwline=slin.Length();
946   Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)& (slin.Value(lastwline)));
947
948   Standard_Integer nbvtx=WLine->NbVertex();
949   if (nbvtx < 2) return;
950   Standard_Integer ParamMinOnLine = (Standard_Integer) WLine->Vertex(1).ParameterOnLine();
951   Standard_Integer ParamMaxOnLine = (Standard_Integer) WLine->Vertex(nbvtx).ParameterOnLine();
952   if (ParamMinOnLine >= ParamMaxOnLine) return;
953   Standard_Integer midInd = (ParamMaxOnLine + ParamMinOnLine) / 2;
954
955   TColStd_SequenceOfInteger indicesV1,indicesV2;
956   Standard_Integer iv;
957   for (iv=1; iv <= nbvtx; iv++) {
958     Standard_Integer plin = (Standard_Integer) WLine->Vertex(iv).ParameterOnLine();
959     if (plin == ParamMinOnLine) indicesV1.Append(iv);
960     else if (plin == ParamMaxOnLine) indicesV2.Append(iv);
961   }
962
963   Standard_Boolean isRLine = Standard_False;
964
965   typedef void (IntSurf_PntOn2S::* PiParOnS)(Standard_Real&,Standard_Real&) const;
966   typedef Standard_Boolean (IntPatch_Point::* PQuery)() const;
967   typedef const Handle(Adaptor2d_HCurve2d)& (IntPatch_Point::* PArcOnS)() const;
968   typedef Standard_Real (IntPatch_Point::* PParOnArc)() const;
969
970   // cycle for both surfaces
971   Standard_Integer is;
972   for (is=0; is<2; is++) {
973     Standard_Boolean onFirst = is==0;
974     if(( onFirst && WLine->HasArcOnS1()) ||
975        (!onFirst && WLine->HasArcOnS2())) {
976       PiParOnS piParOnS;
977       PQuery pIsOnDomS;
978       PArcOnS pArcOnS;
979       PParOnArc pParOnArc;
980       Handle(Adaptor3d_HSurface) surf;
981       Handle(Adaptor3d_TopolTool) aDomain;
982       if (onFirst) {
983         piParOnS = &IntSurf_PntOn2S::ParametersOnS1;
984         pIsOnDomS = &IntPatch_Point::IsOnDomS1;
985         pArcOnS = &IntPatch_Point::ArcOnS1;
986         pParOnArc = &IntPatch_Point::ParameterOnArc1;
987         surf = mySurf1;
988         aDomain = myDom1;
989       }
990       else {
991         piParOnS = &IntSurf_PntOn2S::ParametersOnS2;
992         pIsOnDomS = &IntPatch_Point::IsOnDomS2;
993         pArcOnS = &IntPatch_Point::ArcOnS2;
994         pParOnArc = &IntPatch_Point::ParameterOnArc2;
995         surf = mySurf2;
996         aDomain = myDom2;
997       }
998
999       // resolve arcs for vertices not having a link to an arc
1000       Standard_Real utst,vtst;
1001       TColStd_Array1OfReal paramsResolved(1,nbvtx);
1002       TColStd_Array1OfTransient arcsResolved(1,nbvtx);
1003       arcsResolved.Init(Handle(Adaptor2d_HCurve2d)());
1004       for (iv=1; iv <= nbvtx; iv++) {
1005         if (!(WLine->Vertex(iv).*pIsOnDomS)()) {
1006           Standard_Integer ip = (Standard_Integer) WLine->Vertex(iv).ParameterOnLine();
1007           (WLine->Point(ip).*piParOnS)(utst,vtst);
1008           Standard_Real distmin=RealLast();
1009           for (aDomain->Init(); aDomain->More(); aDomain->Next()) {
1010             const Handle(Adaptor2d_HCurve2d)& arc = aDomain->Value();
1011             Standard_Real par,dist;
1012             if (ProjectOnArc(utst,vtst,arc,surf,TolArc,par,dist) && dist < distmin) {
1013               arcsResolved(iv) = arc;
1014               paramsResolved(iv) = par;
1015               distmin = dist;
1016             }
1017           }
1018         }
1019       }
1020
1021       // prepare list of common arcs for both ends of wline
1022       TColStd_IndexedMapOfTransient mapArcsV1,mapArcs;
1023       Standard_Integer i;
1024       for (i=1; i <= indicesV1.Length(); i++) {
1025         iv = indicesV1(i);
1026         Handle(Adaptor2d_HCurve2d) arc;
1027         if ((WLine->Vertex(iv).*pIsOnDomS)()) arc = (WLine->Vertex(iv).*pArcOnS)();
1028         else arc = (const Handle(Adaptor2d_HCurve2d)&) arcsResolved(iv);
1029         if (!arc.IsNull()) mapArcsV1.Add(arc);
1030       }
1031       for (i=1; i <= indicesV2.Length(); i++) {
1032         iv = indicesV2(i);
1033         Handle(Adaptor2d_HCurve2d) arc;
1034         if ((WLine->Vertex(iv).*pIsOnDomS)()) arc = (WLine->Vertex(iv).*pArcOnS)();
1035         else arc = (const Handle(Adaptor2d_HCurve2d)&) arcsResolved(iv);
1036         if (!arc.IsNull() && mapArcsV1.Contains(arc)) mapArcs.Add(arc);
1037       }
1038
1039       // for each common arc
1040       for (Standard_Integer ia=1; ia <= mapArcs.Extent(); ia++) {
1041         const Handle(Adaptor2d_HCurve2d)& arc = (const Handle(Adaptor2d_HCurve2d)&) mapArcs(ia);
1042         // get end vertices of wline linked with this arc
1043         Standard_Integer iv1=0,iv2=0;
1044         for (i=1; i <= indicesV1.Length() && iv1==0; i++) {
1045           iv = indicesV1(i);
1046           Handle(Adaptor2d_HCurve2d) arc1;
1047           if ((WLine->Vertex(iv).*pIsOnDomS)()) arc1 = (WLine->Vertex(iv).*pArcOnS)();
1048           else arc1 = (const Handle(Adaptor2d_HCurve2d)&) arcsResolved(iv);
1049           if (!arc1.IsNull() && arc1 == arc) iv1 = iv;
1050         }
1051         for (i=1; i <= indicesV2.Length() && iv2==0; i++) {
1052           iv = indicesV2(i);
1053           Handle(Adaptor2d_HCurve2d) arc1;
1054           if ((WLine->Vertex(iv).*pIsOnDomS)()) arc1 = (WLine->Vertex(iv).*pArcOnS)();
1055           else arc1 = (const Handle(Adaptor2d_HCurve2d)&) arcsResolved(iv);
1056           if (!arc1.IsNull() && arc1 == arc) iv2 = iv;
1057         }
1058         if (!iv1 || !iv2) {
1059 #ifdef OCCT_DEBUG
1060           cout<<" Pb getting vertices linked with arc"<<endl;
1061 #endif
1062           continue;
1063         }
1064         Standard_Real par1 = (arcsResolved(iv1).IsNull()
1065                               ? (WLine->Vertex(iv1).*pParOnArc)()
1066                               : paramsResolved(iv1));
1067         Standard_Real par2 = (arcsResolved(iv2).IsNull()
1068                               ? (WLine->Vertex(iv2).*pParOnArc)()
1069                               : paramsResolved(iv2));
1070 #ifdef OCCT_DEBUG
1071         cout<<"****** Parameters on arc on S"<<is+1<<": "<<par1<<" "<<par2<<endl;
1072 #endif
1073
1074         // check that the middle point is on arc
1075         (WLine->Point(midInd).*piParOnS)(utst,vtst);
1076         if (midInd == ParamMinOnLine) {
1077           Standard_Real utst1=0.0,vtst1=0.0;
1078           (WLine->Point(midInd+1).*piParOnS)(utst1,vtst1);
1079           utst = (utst+utst1)*0.5;
1080           vtst = (vtst+vtst1)*0.5;
1081         }
1082         Standard_Real par,dist;
1083         if (!ProjectOnArc(utst,vtst,arc,surf,TolArc,par,dist)) {
1084 #ifdef OCCT_DEBUG
1085           cout<<" Pb en projection ds IntPatch_LineConstructor"<<endl;
1086 #endif
1087           continue;
1088         }
1089
1090         //-- codage de la WLine en RLine 
1091         Handle(IntPatch_RLine) rlig = new IntPatch_RLine(Standard_True,IntSurf_Unknown,IntSurf_Unknown);
1092         if (onFirst) rlig->SetArcOnS1(arc);
1093         else         rlig->SetArcOnS2(arc);
1094
1095         Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
1096         const Handle(IntSurf_LineOn2S)& Lori = WLine->Curve();
1097         Standard_Integer ivmin,ivmax;
1098         Standard_Real parmin, parmax;
1099         Standard_Boolean reverse = Standard_False;
1100         TColStd_SequenceOfInteger *pIndVmin, *pIndVmax;
1101         if (par1<par2) {
1102           for(i=ParamMinOnLine; i<=ParamMaxOnLine; i++) { 
1103             LineOn2S->Add(Lori->Value(i));
1104           }
1105           ivmin = iv1; ivmax = iv2;
1106           parmin = par1; parmax = par2;
1107           pIndVmin = &indicesV1; pIndVmax = &indicesV2;
1108         }
1109         else { 
1110           for(i=ParamMaxOnLine; i>=ParamMinOnLine; i--) {
1111             LineOn2S->Add(Lori->Value(i));
1112           }
1113           ivmin = iv2; ivmax = iv1;
1114           parmin = par2; parmax = par1;
1115           pIndVmin = &indicesV2; pIndVmax = &indicesV1;
1116           reverse = Standard_True;
1117         }
1118         rlig->Add(LineOn2S);
1119         IntSurf_Transition TransitionUndecided;
1120         IntPatch_Point VtxFirst = WLine->Vertex(ivmin);
1121         VtxFirst.SetParameter(parmin);
1122         if (!arcsResolved(ivmin).IsNull())
1123           VtxFirst.SetArc(onFirst,arc,parmin,TransitionUndecided,TransitionUndecided);
1124         if (reverse)
1125           VtxFirst.ReverseTransition();  //-- inversion des transitions
1126         rlig->AddVertex(VtxFirst);
1127         for (i=1; i <= pIndVmin->Length(); i++) {
1128           iv = pIndVmin->Value(i);
1129           if (iv != ivmin) {
1130             IntPatch_Point Vtx=WLine->Vertex(iv);
1131             Vtx.SetParameter(parmin);
1132             if (!arcsResolved(iv).IsNull())
1133               Vtx.SetArc(onFirst,arc,parmin,TransitionUndecided,TransitionUndecided);
1134             if (reverse)
1135               Vtx.ReverseTransition();
1136             rlig->AddVertex(Vtx);
1137           }
1138         }
1139         for (i=1; i <= pIndVmax->Length(); i++) {
1140           iv = pIndVmax->Value(i);
1141           if (iv != ivmax) {
1142             IntPatch_Point Vtx=WLine->Vertex(iv);
1143             Vtx.SetParameter(parmax);
1144             if (!arcsResolved(iv).IsNull())
1145               Vtx.SetArc(onFirst,arc,parmax,TransitionUndecided,TransitionUndecided);
1146             if (reverse)
1147               Vtx.ReverseTransition();
1148             rlig->AddVertex(Vtx);
1149           }
1150         }
1151         IntPatch_Point VtxLast=WLine->Vertex(ivmax);
1152         VtxLast.SetParameter(parmax);
1153         if (!arcsResolved(ivmax).IsNull())
1154           VtxLast.SetArc(onFirst,arc,parmax,TransitionUndecided,TransitionUndecided);
1155         if (reverse)
1156           VtxLast.ReverseTransition();
1157         rlig->AddVertex(VtxLast);
1158         rlig->SetFirstPoint(1);
1159         rlig->SetLastPoint(indicesV1.Length()+indicesV2.Length());
1160         slin.Append(rlig);
1161         isRLine = Standard_True;
1162       }
1163     }
1164   }
1165
1166   if(isRLine ||
1167      TestIfWLineIsRestriction(slinref,WLine,
1168                               mySurf1,myDom1,
1169                               mySurf2,myDom2,
1170                               TolArc)) {
1171     slin.Remove(lastwline);
1172   }
1173 }
1174
1175 //=======================================================================
1176 //function : Perform
1177 //purpose  : 
1178 //=======================================================================
1179
1180 void IntPatch_LineConstructor::Perform(const IntPatch_SequenceOfLine& slinref,
1181                                        const Handle(IntPatch_Line)& L,
1182                                        const Handle(Adaptor3d_HSurface)& mySurf1,
1183                                        const Handle(Adaptor3d_TopolTool)& myDom1,
1184                                        const Handle(Adaptor3d_HSurface)& mySurf2,
1185                                        const Handle(Adaptor3d_TopolTool)& myDom2,
1186                                        const Standard_Real TolArc)  {
1187
1188   Standard_Integer i=1,nbvtx;
1189   Standard_Real firstp,lastp;
1190   Standard_Real Tol = Precision::PConfusion()*100.; // JMB le 13 Jan 2000. Report de la correction du PRO19653
1191   GeomAbs_SurfaceType typs1 = mySurf1->GetType();
1192   GeomAbs_SurfaceType typs2 = mySurf2->GetType();
1193
1194   IntPatch_IType typl = L->ArcType();
1195   if(typl == IntPatch_Analytic) { 
1196     Standard_Real u1,v1,u2,v2;
1197     Handle(IntPatch_ALine)& ALine 
1198       =  Handle(IntPatch_ALine)::DownCast (L);
1199     slin.Clear();
1200     nbvtx = ALine->NbVertex();
1201     //-- -------------------------------------------------------------------
1202     Standard_Integer *TabIndex=new Standard_Integer [nbvtx+2];
1203     Standard_Integer numline=0;
1204     for(i=1;i<=nbvtx;i++) { 
1205     //for(Standard_Integer i=1;i<=nbvtx;i++) { 
1206       TabIndex[i]=0; 
1207     }
1208     //-- -------------------------------------------------------------------
1209     for(i=1;i<nbvtx;i++) { 
1210       const IntPatch_Point& ALine_Vertex_i  =ALine->Vertex(i);
1211       const IntPatch_Point& ALine_Vertex_ip1=ALine->Vertex(i+1);
1212       firstp = ALine_Vertex_i.ParameterOnLine();
1213       lastp =  ALine_Vertex_ip1.ParameterOnLine();
1214       if(firstp!=lastp) { 
1215         Standard_Real pmid = (firstp+lastp)*0.5;
1216         gp_Pnt Pmid = ALine->Value(pmid);
1217         Parameters(mySurf1,mySurf2,Pmid,u1,v1,u2,v2);
1218         Recadre(mySurf1,mySurf2,u1,v1,u2,v2);
1219         TopAbs_State in1,in2;
1220         in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol,Standard_False);
1221         in2 = (in1!=TopAbs_OUT)? myDom2->Classify(gp_Pnt2d(u2,v2),Tol,Standard_False) : TopAbs_OUT;
1222         if(in1 == TopAbs_OUT || in2 == TopAbs_OUT) { 
1223         }
1224         else { 
1225           //-- cout<<"Analytic   : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;        
1226           TabIndex[i]=TabIndex[i+1]=++numline;
1227           AddLine(L,i,i+1,typs1,typs2,TabIndex,slin);
1228         }
1229       }
1230     }
1231     //-- -------------------------------------------------------------------
1232     //-- On recherche les vertex interference Edge Edge Externe 
1233     //-- Ces vertex ne figurent sur aucune ligne et sont Restriction 
1234     //-- sur les 2 edges
1235     for(i=1;i<=nbvtx;i++) { 
1236       if(TabIndex[i]==0) { 
1237         const IntPatch_Point& ALine_Vertex_i  =ALine->Vertex(i);
1238         if(ALine_Vertex_i.IsOnDomS1() && ALine_Vertex_i.IsOnDomS2()) { 
1239           TabIndex[i]=++numline;
1240           AddLine(L,i,i,typs1,typs2,TabIndex,slin);       
1241         }
1242       }
1243     }
1244     delete [] TabIndex;
1245     //-- -------------------------------------------------------------------
1246     return;
1247   }
1248   else if(typl == IntPatch_Walking) { 
1249     Standard_Real u1,v1,u2,v2;
1250     Handle(IntPatch_WLine)& WLine 
1251       =  Handle(IntPatch_WLine)::DownCast (L);
1252     slin.Clear();
1253     nbvtx = WLine->NbVertex();
1254     //-- -------------------------------------------------------------------
1255     Standard_Integer *TabIndex=new Standard_Integer [nbvtx+2];
1256     Standard_Integer numline=0;
1257     for(i=1;i<=nbvtx;i++)  {
1258     //for(Standard_Integer i=1;i<=nbvtx;i++)  {
1259       TabIndex[i]=0;
1260     }
1261     //-- -------------------------------------------------------------------
1262     for(i=1;i<nbvtx;i++) { 
1263       const IntPatch_Point& WLineVertex_i   =  WLine->Vertex(i);
1264       const IntPatch_Point& WLineVertex_ip1 =  WLine->Vertex(i+1);
1265       firstp = WLineVertex_i.ParameterOnLine();
1266       lastp =  WLineVertex_ip1.ParameterOnLine();
1267       if(firstp!=lastp && !IsSegmentSmall(WLine,i,i+1/*,TolArc*/)) {  
1268         Standard_Integer pmid;
1269         pmid = (Standard_Integer)((firstp+lastp)/2);
1270         Standard_Integer int_lastp = (Standard_Integer)lastp;
1271         Standard_Integer int_firstp = (Standard_Integer)firstp;
1272         if(pmid==int_lastp) pmid=int_firstp;
1273         const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
1274         Pmid.Parameters(u1,v1,u2,v2);
1275         Recadre(mySurf1,mySurf2,u1,v1,u2,v2);
1276         
1277         // modified by NIZHNY-MKK  Tue Apr  3 15:03:40 2001.BEGIN
1278         //------------------------------------------    
1279         gp_Pnt ap;
1280         gp_Vec ad1u,ad1v;
1281         mySurf1->D1(u1,v1,ap,ad1u,ad1v);
1282         Standard_Real aTolerance = ComputeParametricTolerance(TolArc, ad1u, ad1v);
1283         //------------------------------------------
1284
1285         //TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol,Standard_False);
1286         TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1), aTolerance, Standard_False);
1287         //TopAbs_State in2 = (in1!=TopAbs_OUT)? myDom2->Classify(gp_Pnt2d(u2,v2),Tol,Standard_False) : TopAbs_OUT;
1288         TopAbs_State in2 = TopAbs_OUT;
1289         if (in1!=TopAbs_OUT) {
1290           //------------------------------------------
1291           mySurf2->D1(u2,v2,ap,ad1u,ad1v);
1292           aTolerance = ComputeParametricTolerance(TolArc, ad1u, ad1v);
1293           //------------------------------------------
1294           in2 = myDom2->Classify(gp_Pnt2d(u2,v2), aTolerance, Standard_False);
1295         }
1296         // modified by NIZHNY-MKK  Tue Apr  3 15:06:31 2001.END
1297         
1298         // modified by NIZHNY-OFV  Wed Jun 13 17:31:23 2001
1299         // --purpose: If on a face (lastp-firstp) == 1,
1300         //            sometimes it could mean a bad parametrisation of WLine.
1301         //            In this case we try to classify the "virtual" WLine point:
1302         //            the geometrical point between two vertexes. This emulates
1303         //            situation when (lastp-firstp) != 1.
1304         if(Abs(int_lastp-int_firstp) == 1)
1305           {
1306             Standard_Real vFu1,vFv1,vFu2,vFv2,vLu1,vLv1,vLu2,vLv2;
1307             const IntSurf_PntOn2S& vF = WLineVertex_i. PntOn2S();
1308             const IntSurf_PntOn2S& vL = WLineVertex_ip1. PntOn2S();
1309             vF.Parameters(vFu1,vFv1,vFu2,vFv2);
1310             Recadre(mySurf1,mySurf2,vFu1,vFv1,vFu2,vFv2);
1311             vL.Parameters(vLu1,vLv1,vLu2,vLv2);
1312             Recadre(mySurf1,mySurf2,vLu1,vLv1,vLu2,vLv2);
1313             if(in1 != TopAbs_IN)
1314               {
1315                 Standard_Real du,dv;
1316                 gp_Pnt2d pvF(vFu1,vFv1);
1317                 gp_Pnt2d pvL(vLu1,vLv1);
1318                 gp_Pnt2d pPm(u1,v1);
1319                 Standard_Real dpvFpPm = pvF.Distance(pPm);
1320                 Standard_Real dpvLpPm = pvL.Distance(pPm);
1321                 if(dpvFpPm > dpvLpPm)
1322                   {
1323                     du = (vFu1 + u1) * 0.5;
1324                     dv = (vFv1 + v1) * 0.5;
1325                   }
1326                 else
1327                   {
1328                     du = (vLu1 + u1) * 0.5;
1329                     dv = (vLv1 + v1) * 0.5;
1330                   }
1331                 mySurf1->D1(du,dv,ap,ad1u,ad1v);
1332                 aTolerance = ComputeParametricTolerance(TolArc, ad1u, ad1v);
1333                 in1 = myDom1->Classify(gp_Pnt2d(du,dv), aTolerance, Standard_False);
1334               }
1335             if(in2 != TopAbs_IN)
1336               {
1337                 Standard_Real du,dv;
1338                 gp_Pnt2d pvF(vFu2,vFv2);
1339                 gp_Pnt2d pvL(vLu2,vLv2);
1340                 gp_Pnt2d pPm(u2,v2);
1341                 Standard_Real dpvFpPm = pvF.Distance(pPm);
1342                 Standard_Real dpvLpPm = pvL.Distance(pPm);
1343                 if(dpvFpPm > dpvLpPm)
1344                   {
1345                     du = (vFu2 + u2) * 0.5;
1346                     dv = (vFv2 + v2) * 0.5;
1347                   }
1348                 else
1349                   {
1350                     du = (vLu2 + u2) * 0.5;
1351                     dv = (vLv2 + v2) * 0.5;
1352                   }
1353                 mySurf2->D1(du,dv,ap,ad1u,ad1v);
1354                 aTolerance = ComputeParametricTolerance(TolArc, ad1u, ad1v);
1355                 in2 = myDom2->Classify(gp_Pnt2d(du,dv), aTolerance, Standard_False);
1356               }
1357           } //end of if(Abs(int_lastp-int_firstp) == 1)
1358
1359         if (in1 != TopAbs_OUT && in2 != TopAbs_OUT)
1360           {
1361             Standard_Boolean   LignetropPetite=Standard_False;
1362             Standard_Real u1a,v1a,u2a,v2a;
1363             const IntSurf_PntOn2S& Pmid1 = WLine->Point((Standard_Integer)firstp);
1364             Pmid1.Parameters(u1a,v1a,u2a,v2a);
1365             Recadre(mySurf1,mySurf2,u1a,v1a,u2a,v2a);
1366             
1367             const IntSurf_PntOn2S& Pmid2 = WLine->Point((Standard_Integer)lastp);
1368             Standard_Real u1b,v1b,u2b,v2b;
1369             Pmid2.Parameters(u1b,v1b,u2b,v2b);
1370             Recadre(mySurf1,mySurf2,u1b,v1b,u2b,v2b);
1371             
1372             Standard_Real dd12_u=Abs(u1a-u1b); 
1373             Standard_Real dd12_v=Abs(v1a-v1b); 
1374             if(dd12_u+dd12_v < 1e-12) { 
1375               dd12_u=Abs(u1-u1b);
1376               dd12_v=Abs(v1-v1b);
1377               if(dd12_u+dd12_v < 1e-12) { 
1378                 LignetropPetite=Standard_True;
1379               }
1380             }
1381             if(LignetropPetite==Standard_False) {           
1382               //-- cout<<"WLine      : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
1383               TabIndex[i]=TabIndex[i+1]=++numline;
1384               AddLine(L,i,i+1,typs1,typs2,TabIndex,slin);
1385               TestWLineToRLine(slinref,slin,mySurf1,myDom1,mySurf2,myDom2,TolArc); //-- on teste la derniere entree de slin
1386             }
1387           } //end of if (in1 != TopAbs_OUT && in2 != TopAbs_OUT)
1388       } //end of if(firstp!=lastp && !IsSegmentSmall(WLine,i,i+1/*,TolArc*/))
1389     } //end of for(i=1;i<nbvtx;i++)
1390
1391     //-- -------------------------------------------------------------------
1392     //-- On recherche les vertex interference Edge Edge Externe 
1393     //-- Ces vertex ne figurent sur aucune ligne et sont Restriction 
1394     //-- sur les 2 edges
1395     for(i=1;i<=nbvtx;i++) { 
1396       if(TabIndex[i]==0) { 
1397         const IntPatch_Point& WLine_Vertex_i  =WLine->Vertex(i);
1398         if(WLine_Vertex_i.IsOnDomS1() && WLine_Vertex_i.IsOnDomS2()) { 
1399           TabIndex[i]=++numline;
1400           AddLine(L,i,i,typs1,typs2,TabIndex,slin);       
1401         }
1402       }
1403     }
1404     delete [] TabIndex;
1405     //-- -------------------------------------------------------------------
1406     return;
1407   }
1408   else if (typl != IntPatch_Restriction) { // JAG 01.07.96
1409     Standard_Real u1,v1,u2,v2;
1410     Handle(IntPatch_GLine)& GLine 
1411       =  Handle(IntPatch_GLine)::DownCast (L);
1412     slin.Clear();
1413     nbvtx = GLine->NbVertex();
1414     //-- -------------------------------------------------------------------
1415     Standard_Integer *TabIndex=new Standard_Integer [nbvtx+2];
1416     Standard_Integer numline=0;
1417 //    for(Standard_Integer i=1;i<=nbvtx;i++) { 
1418     for(i=1;i<=nbvtx;i++) { 
1419      TabIndex[i]=0;
1420     }
1421     //-- -------------------------------------------------------------------
1422     Standard_Boolean intrvtested = Standard_False;
1423     for(i=1;i<nbvtx;i++) { 
1424       firstp = GLine->Vertex(i).ParameterOnLine();
1425       lastp =  GLine->Vertex(i+1).ParameterOnLine();
1426       if(Abs(firstp-lastp)>Precision::PConfusion()) {
1427         intrvtested = Standard_True;
1428         Standard_Real pmid = (firstp+lastp)*0.5;
1429         gp_Pnt Pmid;
1430         if (typl == IntPatch_Lin) {
1431           Pmid = ElCLib::Value(pmid,GLine->Line());
1432         }
1433         else if (typl == IntPatch_Circle) {
1434           Pmid = ElCLib::Value(pmid,GLine->Circle());
1435         }
1436         else if (typl == IntPatch_Ellipse) {
1437           Pmid = ElCLib::Value(pmid,GLine->Ellipse());
1438         }
1439         else if (typl == IntPatch_Hyperbola) {
1440           Pmid = ElCLib::Value(pmid,GLine->Hyperbola());
1441         }
1442         else if (typl == IntPatch_Parabola) {
1443           Pmid = ElCLib::Value(pmid,GLine->Parabola());
1444         }
1445         Parameters(mySurf1,mySurf2,Pmid,u1,v1,u2,v2);
1446         Recadre(mySurf1,mySurf2,u1,v1,u2,v2);
1447
1448         gp_Vec Du,Dv;
1449         gp_Pnt P;
1450         myDom1->Init();
1451         if (myDom2->More()) {
1452           mySurf1->D1(u1,v1,P,Du,Dv);
1453           Tol = ComputeParametricTolerance( myDom1->Tol3d(myDom1->Value()) ,Du,Dv);
1454         }
1455         TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol,Standard_False);
1456         
1457         myDom2->Init();
1458         if (in1 != TopAbs_OUT  &&  myDom2->More() ) {
1459           mySurf2->D1(u2,v2,P,Du,Dv);
1460           Tol = ComputeParametricTolerance( myDom2->Tol3d(myDom2->Value()) ,Du,Dv);
1461         }
1462         TopAbs_State in2 = (in1!=TopAbs_OUT)? myDom2->Classify(gp_Pnt2d(u2,v2),Tol,Standard_False) : TopAbs_OUT;
1463         // modified by NIZHNY-OFV  Wed May 30 17:04:08 2001.BEGIN
1464         // --purpose: section algo with infinite prism works now!!!
1465         if(in1 == TopAbs_UNKNOWN) in1 = TopAbs_OUT;
1466         if(in2 == TopAbs_UNKNOWN) in2 = TopAbs_OUT;
1467         // modified by NIZHNY-OFV  Wed May 30 17:05:47 2001.END
1468         if(in1 == TopAbs_OUT || in2 == TopAbs_OUT) { 
1469         }
1470         else { 
1471           //-- cout<<"GLine      : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
1472           TabIndex[i]=TabIndex[i+1]=++numline;
1473           AddLine(L,i,i+1,typs1,typs2,TabIndex,slin); 
1474         }
1475       }
1476     }
1477     if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) { 
1478       firstp = GLine->Vertex(nbvtx).ParameterOnLine();
1479       lastp  = M_PI + M_PI + GLine->Vertex(1).ParameterOnLine();
1480       Standard_Real cadrinf = LocalFirstParameter(L);
1481       Standard_Real cadrsup = LocalLastParameter(L);
1482       Standard_Real acadr = (firstp+lastp)*0.5;
1483       while(acadr < cadrinf) { acadr+=M_PI+M_PI; }
1484       while(acadr > cadrsup) { acadr-=M_PI+M_PI; } 
1485       if(acadr>=cadrinf && acadr<=cadrsup) { 
1486         if(Abs(firstp-lastp)>Precision::PConfusion()) {
1487           intrvtested = Standard_True;
1488           Standard_Real pmid = (firstp+lastp)*0.5;
1489           gp_Pnt Pmid;
1490           if (typl == IntPatch_Circle) {
1491             Pmid = ElCLib::Value(pmid,GLine->Circle());
1492           }
1493           else {
1494             Pmid = ElCLib::Value(pmid,GLine->Ellipse());
1495           }
1496           Parameters(mySurf1,mySurf2,Pmid,u1,v1,u2,v2);
1497           Recadre(mySurf1,mySurf2,u1,v1,u2,v2);
1498           TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol,Standard_False);
1499           TopAbs_State in2 = (in1!=TopAbs_OUT)?  myDom2->Classify(gp_Pnt2d(u2,v2),Tol,Standard_False) : TopAbs_OUT;
1500           // modified by NIZHNY-OFV  Wed May 30 17:04:08 2001.BEGIN
1501           // --purpose: section algo with infinite prism works now!!!
1502           if(in1 == TopAbs_UNKNOWN) in1 = TopAbs_OUT;
1503           if(in2 == TopAbs_UNKNOWN) in2 = TopAbs_OUT;
1504           // modified by NIZHNY-OFV  Wed May 30 17:05:47 2001.END
1505           if(in1 == TopAbs_OUT || in2 == TopAbs_OUT) { 
1506           }
1507           else { 
1508             //-- cout<<"GLine  bis : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
1509             TabIndex[nbvtx]=TabIndex[1]=++numline;
1510             AddLine(L,nbvtx,1,typs1,typs2,TabIndex,slin); 
1511           }
1512         }
1513       }
1514     }      
1515     if (!intrvtested) {
1516       // on garde a priori. Il faudrait un point 2d sur chaque
1517       // surface pour prendre la decision. Sera fait dans 
1518       // l`appelant
1519       //if(nbvtx) { 
1520       //        TabIndex[nbvtx]=TabIndex[1]=++numline;
1521       //        AddLine(L,1,nbvtx,typs1,typs2,TabIndex,slin);
1522       //}
1523     }
1524     //-- -------------------------------------------------------------------
1525     //-- On recherche les vertex interference Edge Edge Externe 
1526     //-- Ces vertex ne figurent sur aucune ligne et sont Restriction 
1527     //-- sur les 2 edges
1528     for(i=1;i<=nbvtx;i++) { 
1529       if(TabIndex[i]==0) { 
1530         const IntPatch_Point& GLine_Vertex_i  =GLine->Vertex(i);
1531         if(GLine_Vertex_i.IsOnDomS1() && GLine_Vertex_i.IsOnDomS2()) { 
1532           TabIndex[i]=++numline;
1533           AddLine(L,i,i,typs1,typs2,TabIndex,slin);       
1534         }
1535       }
1536     }
1537     delete [] TabIndex;
1538     //-- -------------------------------------------------------------------    
1539     return;
1540   }
1541   else {  //-- Restriction
1542     Handle(IntPatch_RLine)& RLine 
1543       =  Handle(IntPatch_RLine)::DownCast (L);
1544     slin.Clear();
1545     Standard_Integer NbVtx    = RLine->NbVertex();
1546     Standard_Boolean RestOnS1 = RLine->IsArcOnS1();
1547     Standard_Boolean RestOnS2 = RLine->IsArcOnS2();
1548     //-- -------------------------------------------------------------------
1549     Standard_Integer *TabIndex=new Standard_Integer [NbVtx+2];
1550     //Standard_Integer numline=0;
1551     for(i=1; i<=NbVtx; i++) { 
1552       TabIndex[i]=0;
1553     }
1554     //-- -------------------------------------------------------------------    
1555     for(i=1; i<NbVtx; i++) { 
1556       const IntPatch_Point&  Vtx1=RLine->Vertex(i);
1557       const IntPatch_Point&  Vtx2=RLine->Vertex(i+1);
1558       if(RestOnS1 && RestOnS2) { 
1559         AddLine(L,i,i+1,typs1,typs2,TabIndex,slin); 
1560       }
1561       else if(RestOnS1) { //-- On na classifie pas sur 1 
1562         Standard_Real u0 = Vtx1.ParameterOnLine();
1563         Standard_Real u1 = Vtx2.ParameterOnLine();
1564         if(Abs(u1-u0)>Precision::PConfusion()) { 
1565           Standard_Real u  = (999.0*u0+u1)*0.001;
1566           
1567           gp_Pnt P0=Vtx1.Value();
1568           gp_Pnt2d Px2d=RLine->ArcOnS1()->Value(u);
1569           gp_Pnt   Px = mySurf1->Value(Px2d.X(),Px2d.Y());
1570           gp_Vec P0Px=gp_Vec(P0,Px);
1571           
1572           Standard_Real U1,V1,U2,V2;
1573           Vtx1.PntOn2S().Parameters(U1,V1,U2,V2);
1574
1575           gp_Vec D1u,D1v;
1576           gp_Pnt P;
1577           mySurf2->D1(U2,V2,P,D1u,D1v);
1578           myDom2->Init();
1579           if (myDom2->More())
1580             Tol = ComputeParametricTolerance( myDom2->Tol3d(myDom2->Value()), D1u,D1v);
1581
1582           //-- le 23 mars 1999 
1583           TopAbs_State bornin = myDom2->Classify(gp_Pnt2d(U2,V2),Tol,Standard_False);
1584           if(bornin!=TopAbs_OUT) { 
1585             Standard_Real U1t,V1t,U2t,V2t;
1586             Vtx2.PntOn2S().Parameters(U1t,V1t,U2t,V2t);
1587             bornin = myDom2->Classify(gp_Pnt2d(U2t,V2t),Tol,Standard_False);
1588           }
1589           if (bornin==TopAbs_OUT) continue;
1590           
1591           
1592           //-- Attention , on faisait  une estimatoin de deltau et deltav 
1593           //-- Maintenant : 
1594           //-- POPx . D1u = deltau * D1u.D1u  + deltav * D1u.D1v
1595           //-- POPx . D1v = deltau * D1u.D1v  + deltav * D1v.D1v
1596           //--
1597           //-- deltau=
1598           Standard_Real D1uD1v,TgD1u,TgD1v,D1uD1u,D1vD1v,DIS;
1599           //Standard_Real DeltaU,DeltaV;
1600           D1uD1u = D1u.Dot(D1u);
1601           D1vD1v = D1v.Dot(D1v);
1602           D1uD1v = D1u.Dot(D1v);
1603           TgD1u = P0Px.Dot(D1u);
1604           TgD1v = P0Px.Dot(D1v);
1605           DIS  = D1uD1u * D1vD1v - D1uD1v * D1uD1v;
1606           
1607           Standard_Real deltau=1e-10;
1608           Standard_Real deltav=1e-10;
1609           if(DIS<-1e-10 || DIS>1e-10) {
1610             deltau=(TgD1u*D1vD1v-TgD1v*D1uD1v)/DIS;
1611             deltav=(TgD1v*D1uD1u-TgD1u*D1uD1v)/DIS;
1612           }
1613
1614           U2+=deltau;
1615           V2+=deltav;
1616           if(bornin!=TopAbs_OUT) { 
1617             TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(U2,V2),Tol,Standard_False);
1618             deltau*=0.05;
1619             deltav*=0.05;
1620             if(in2==TopAbs_OUT) { 
1621               in2 = myDom2->Classify(gp_Pnt2d(U2+deltau,V2),Tol,Standard_False);
1622             }
1623             if(in2==TopAbs_OUT) { 
1624               in2 = myDom2->Classify(gp_Pnt2d(U2-deltau,V2),Tol,Standard_False);
1625             }
1626             if(in2==TopAbs_OUT) { 
1627               in2 = myDom2->Classify(gp_Pnt2d(U2,V2+deltav),Tol,Standard_False);
1628             }
1629             if(in2==TopAbs_OUT) { 
1630               in2 = myDom2->Classify(gp_Pnt2d(U2,V2-deltav),Tol,Standard_False);
1631             }
1632             
1633             if(in2!=TopAbs_OUT) { 
1634               //-- cout<<"RLine ons1 : u0    ="<<u0<<" u1   ="<<u1<<" Vtx:"<<i<<","<<i+1<<endl;
1635               AddLine(L,i,i+1,typs1,typs2,TabIndex,slin); 
1636             }
1637           }
1638         }
1639       }
1640       else {
1641         Standard_Real u0 = Vtx1.ParameterOnLine();
1642         Standard_Real u1 = Vtx2.ParameterOnLine();
1643         if(Abs(u1-u0)>Precision::PConfusion()) { 
1644           Standard_Real u  = (999.0*u0+u1)*0.001;
1645           
1646           gp_Pnt P0=Vtx1.Value();
1647           gp_Pnt2d Px2d=RLine->ArcOnS2()->Value(u);
1648           gp_Pnt   Px = mySurf2->Value(Px2d.X(),Px2d.Y());
1649           gp_Vec P0Px=gp_Vec(P0,Px);
1650           
1651           Standard_Real U1,V1,U2,V2;
1652           Vtx1.PntOn2S().Parameters(U1,V1,U2,V2);
1653           
1654           gp_Vec D1u,D1v;
1655           gp_Pnt P;
1656           mySurf1->D1(U1,V1,P,D1u,D1v);
1657           myDom1->Init();
1658           if (myDom2->More())
1659             Tol = ComputeParametricTolerance( myDom1->Tol3d(myDom1->Value()) ,D1u,D1v);
1660           
1661           //-- le 23 mars 1999 
1662           TopAbs_State bornin = myDom1->Classify(gp_Pnt2d(U1,V1),Tol,Standard_False);
1663           if(bornin!=TopAbs_OUT) { 
1664             Standard_Real U1t,V1t,U2t,V2t;
1665             Vtx2.PntOn2S().Parameters(U1t,V1t,U2t,V2t);
1666             bornin = myDom1->Classify(gp_Pnt2d(U1t,V1t),Tol,Standard_False);
1667           }
1668           if (bornin==TopAbs_OUT) continue;
1669           
1670           
1671           //-- Attention , on faisait  une estimatoin de deltau et deltav 
1672           //-- Maintenant : 
1673           //-- POPx . D1u = deltau * D1u.D1u  + deltav * D1u.D1v
1674           //-- POPx . D1v = deltau * D1u.D1v  + deltav * D1v.D1v
1675           //--
1676           //-- deltau=
1677           Standard_Real D1uD1v,TgD1u,TgD1v,D1uD1u,D1vD1v,DIS;
1678           //Standard_Real DeltaU,DeltaV;
1679           D1uD1u = D1u.Dot(D1u);
1680           D1vD1v = D1v.Dot(D1v);
1681           D1uD1v = D1u.Dot(D1v);
1682           TgD1u = P0Px.Dot(D1u);
1683           TgD1v = P0Px.Dot(D1v);
1684           DIS  = D1uD1u * D1vD1v - D1uD1v * D1uD1v;
1685           
1686           Standard_Real deltau=1e-10;
1687           Standard_Real deltav=1e-10;
1688           if(DIS<-1e-10 || DIS>1e-10) {
1689             deltau=(TgD1u*D1vD1v-TgD1v*D1uD1v)/DIS;
1690             deltav=(TgD1v*D1uD1u-TgD1u*D1uD1v)/DIS;
1691           }
1692           
1693           U1+=deltau;
1694           V1+=deltav;
1695           
1696           if(bornin!=TopAbs_OUT) { 
1697             TopAbs_State in2 = myDom1->Classify(gp_Pnt2d(U1,V1),Tol,Standard_False);      
1698             deltau*=0.05;
1699             deltav*=0.05;
1700             if(in2==TopAbs_OUT) { 
1701               in2 = myDom1->Classify(gp_Pnt2d(U1+deltau,V1),Tol,Standard_False);
1702             }
1703             if(in2==TopAbs_OUT) { 
1704               in2 = myDom1->Classify(gp_Pnt2d(U1-deltau,V1),Tol,Standard_False);
1705             }
1706             if(in2==TopAbs_OUT) { 
1707               in2 = myDom1->Classify(gp_Pnt2d(U1,V1+deltav),Tol,Standard_False);
1708             }
1709             if(in2==TopAbs_OUT) { 
1710               in2 = myDom1->Classify(gp_Pnt2d(U1,V1-deltav),Tol,Standard_False);
1711             }
1712             
1713             if(in2!=TopAbs_OUT) { 
1714               //-- cout<<"RLine ons2 : u0    ="<<u0<<" u1   ="<<u1<<" Vtx:"<<i<<","<<i+1<<endl;
1715               
1716               AddLine(L,i,i+1,typs1,typs2,TabIndex,slin); 
1717             }
1718           }
1719         }
1720       }
1721     }
1722     delete [] TabIndex;
1723   }
1724 }