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