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