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