0029807: [Regression to 7.0.0] Impossible to cut cone from prism
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_0.gxx
1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455
18
19 #include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
20 #include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
21 #include <IntPatch_RLine.hxx>
22 #include <IntSurf.hxx>
23 #include <TColStd_Array1OfInteger.hxx>
24 #include <TColStd_SequenceOfReal.hxx>
25 #include <IntPatch_GLine.hxx>
26 #include <Extrema_ExtPC.hxx>
27 #include <GeomAdaptor_Curve.hxx>
28 #include <Geom_Ellipse.hxx>
29 #include <Geom_Parabola.hxx>
30 #include <Geom_Hyperbola.hxx>
31 #include <IntPatch_ALine.hxx>
32
33
34 static void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
35                             const Handle(Adaptor3d_HSurface)& S2,
36                             const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
37                             const IntPatch_SequenceOfLine&,
38                             const Standard_Boolean,
39                             const Handle(Adaptor3d_TopolTool)&,
40                             const IntSurf_Quadric&,
41                             const IntSurf_Quadric&,
42                             const Standard_Boolean,
43                             const Standard_Real);
44
45 static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
46                                       const Handle(Adaptor3d_TopolTool)& Domain,
47                                       const IntSurf_Quadric& QuadSurf,
48                                       const gp_Vec&    Normale,
49                                       const IntPatch_SequenceOfLine& slin,
50                                       TColStd_Array1OfInteger& Done,
51                                       TColStd_Array1OfInteger& UsedLine,
52                                       const Standard_Integer Index,
53                                       const Standard_Boolean OnFirst,
54                                       const Standard_Real theToler);
55
56 static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
57                                          const Handle(Adaptor3d_TopolTool)& Domain,
58                                          const IntSurf_Quadric& QuadSurf,
59                                          const gp_Vec&    Normale,
60                                          const gp_Vec&    Vtgint,
61                                          const Handle(IntPatch_Line)& lin,
62                                          TColStd_Array1OfInteger& Done,
63                                          const Standard_Integer Index,
64                                          const Standard_Real theToler);
65
66 static Standard_Boolean SingleLine (const gp_Pnt&,
67                                     const Handle(IntPatch_Line)&,
68                                     const Standard_Real,
69                                     Standard_Real&,
70                                     gp_Vec&);
71
72
73 static Standard_Boolean FindLine(gp_Pnt& Psurf,
74                                  const IntPatch_SequenceOfLine& slin,
75                                  const Standard_Real Tol,
76                                  TColStd_ListOfReal& theLParams,
77                                  gp_Vec& Vtgtint,
78                                  Standard_Integer& theLineIdx,
79                                  Standard_Integer OnlyThisLine,
80                                  const Handle(Adaptor2d_HCurve2d)& thearc,
81                                  Standard_Real& theparameteronarc,
82                                  gp_Pnt& thepointonarc,
83                                  const IntSurf_Quadric& QuadSurf1,
84                                  const IntSurf_Quadric& QuadSurf2,
85                                  Standard_Real& theOutputToler);
86
87 static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
88                              IntPatch_SequenceOfLine&,
89                              const IntSurf_Quadric&,
90                              const IntSurf_Quadric&,
91                              const Standard_Boolean,
92                              const Standard_Real);
93
94 static void ProcessRLine (IntPatch_SequenceOfLine&,
95                           const IntSurf_Quadric&,
96                           const IntSurf_Quadric&,
97                           const Standard_Real,
98                           const Standard_Boolean theIsReqToKeepRLine);
99
100 //-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
101 Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
102                                        const Handle(IntPatch_ALine)& alin,
103                                        Standard_Real& para,
104                                        const Handle(Adaptor2d_HCurve2d)& thearc,
105                                        Standard_Real& _theparameteronarc,
106                                        gp_Pnt& thepointonarc,
107                                        const IntSurf_Quadric& QuadSurf,
108                                        const Standard_Real u0alin,
109                                        const Standard_Real u1alin) { 
110   Standard_Real dtheta,theta;
111 #ifdef OCCT_DEBUG
112   //Standard_Real u,v,A,B,C,cost,sint,sign;
113 #endif
114   //-- recherche bete du point le plus proche de thearc->Value(...)
115   dtheta = (u1alin-u0alin)*0.01;
116   Standard_Real du=0.000000001;
117   if (du >= dtheta)
118     du = dtheta/2;
119   Standard_Real distmin = RealLast();
120
121   Standard_Real thetamin = 0.;
122
123   Standard_Real theparameteronarc = _theparameteronarc;
124   for(Standard_Real _theta=u0alin+dtheta; _theta<=u1alin-dtheta; _theta+=dtheta) { 
125     gp_Pnt P=alin->Value(_theta);
126     Standard_Real d=P.Distance(PSurf);
127     if(d<distmin) { 
128       thetamin=_theta;
129       distmin=d;
130     }
131   }
132
133   Standard_Real bestpara =0., besttheta =0., bestdist =0., distinit =0. ;
134
135   //-- Distance initiale
136   {
137     gp_Pnt pp0 = alin->Value(thetamin);
138     Standard_Real ua0,va0;
139     QuadSurf.Parameters(pp0,ua0,va0);
140     gp_Pnt2d p2d;
141     gp_Vec2d d2d;
142     thearc->D1(theparameteronarc,p2d,d2d);
143     gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
144     distinit=PaPr.Magnitude();
145   }
146   theta = thetamin;
147   //-- recherche a partir de theta et theparameteronarc
148   Standard_Boolean cpasok=Standard_True;
149   Standard_Integer nbiter=0;
150   Standard_Real drmax = (thearc->LastParameter() - thearc->FirstParameter())*0.05;
151   Standard_Real damax = (u1alin-u0alin)*0.05;
152
153
154   
155   bestdist = RealLast();
156
157   do { 
158     Standard_Real ua0,va0,ua1,va1;
159     //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
160     //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
161     gp_Pnt pp0 = alin->Value(theta);
162     gp_Pnt pp1 = alin->Value(theta+du);
163     QuadSurf.Parameters(pp0,ua0,va0);
164     QuadSurf.Parameters(pp1,ua1,va1);
165     
166     
167     gp_Vec2d D1a((ua1-ua0)/du,(va1-va0)/du);
168     gp_Pnt2d p2d;
169     gp_Vec2d d2d;
170     thearc->D1(theparameteronarc,p2d,d2d);
171     gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
172     
173     Standard_Real pbd=PaPr.Magnitude();
174     if(bestdist>pbd) {
175       bestdist = pbd;
176       bestpara = theparameteronarc;
177       besttheta = theta;
178     }
179
180     D1a.SetCoord(-D1a.X(),-D1a.Y());
181     
182     Standard_Real d  = D1a.X()    *   d2d.Y()   -   D1a.Y()     * d2d.X();
183     
184     Standard_Real da = (-PaPr.X())*   d2d.Y()   -   (-PaPr.Y()) * d2d.X();
185     Standard_Real dr =  D1a.X()   * (-PaPr.Y()) -   D1a.Y()     * (-PaPr.X());
186     if(Abs(d)>1e-15) { 
187       da/=d;
188       dr/=d;
189     }
190     else { 
191       if(Abs(PaPr.X())>Abs(PaPr.Y())) { 
192         Standard_Real xx=PaPr.X();
193         xx*=0.5;
194         if(D1a.X()) { 
195           da = -xx/D1a.X();
196         }
197         if(d2d.X()) { 
198           dr = -xx/d2d.X();
199         }
200       }
201       else { 
202         Standard_Real yy=PaPr.Y();
203         yy*=0.5;
204         if(D1a.Y()) { 
205           da = -yy/D1a.Y();
206         }
207         if(d2d.Y()) { 
208           dr = -yy/d2d.Y();
209         }       
210       }
211     } 
212 //--     Standard_Real da = -PaPr.Dot(D1a);
213 //--     Standard_Real dr = -PaPr.Dot(d2d);
214     
215     if(da<-damax) da=-damax;
216     else if(da>damax) da=damax;
217     if(dr<-drmax) dr=-drmax;
218     else if(dr>drmax) dr=drmax;
219
220     if(Abs(da)<1e-10 && Abs(dr)<1e-10) { 
221       para = theta; 
222       PSurf = alin->Value(para);
223       _theparameteronarc=theparameteronarc;
224       thepointonarc = alin->Value(para);
225       cpasok=Standard_False;
226 //--      printf("\nt:%d",nbiter);
227       return(Standard_True);
228     }
229     else { 
230       theta+=da;
231       theparameteronarc+=dr;
232       if(   theparameteronarc>thearc->LastParameter() ) { 
233         theparameteronarc = thearc->LastParameter();
234       }
235       if(  theparameteronarc<thearc->FirstParameter() ) { 
236         theparameteronarc = thearc->FirstParameter();
237       }
238       if( theta < u0alin) { 
239         theta = u0alin;
240       }
241       if( theta > u1alin-du) { 
242         theta = u1alin-du-du; 
243       }
244     }
245     nbiter++;
246   }
247   while(cpasok && nbiter<20);
248   if(bestdist < distinit) { 
249     para = besttheta; 
250     PSurf = alin->Value(para);
251     _theparameteronarc=bestpara;
252     thepointonarc = alin->Value(para);
253 //--     printf("\nT:%d",nbiter);
254     return(Standard_True);
255   }
256 //--   printf("\nF:%d",nbiter);
257   return(Standard_False);
258 }
259
260
261
262
263
264 //-- ======================================================================
265 static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
266                     const Handle(Adaptor3d_HSurface)& myHS2,
267                     Standard_Real& u1,
268                     Standard_Real& v1,
269                     Standard_Real& u2,
270                     Standard_Real& v2) { 
271   Standard_Real f,l,lmf,fpls2;
272   GeomAbs_SurfaceType typs1 = myHS1->GetType();
273   GeomAbs_SurfaceType typs2 = myHS2->GetType();
274
275   Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
276   switch (typs1) { 
277   case GeomAbs_Cylinder:
278   case GeomAbs_Cone:
279   case GeomAbs_Sphere: 
280     { 
281       myHS1IsUPeriodic = Standard_True;
282       myHS1IsVPeriodic = Standard_False;
283       break;
284     }
285   case GeomAbs_Torus:
286     {
287       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
288       break;
289     }
290   default:
291      {
292        //-- Le cas de biparametrees periodiques est gere en amont
293        myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
294        break;
295      }
296   }
297
298   Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
299   switch (typs2) { 
300   case GeomAbs_Cylinder:
301   case GeomAbs_Cone:
302   case GeomAbs_Sphere: 
303     { 
304       myHS2IsUPeriodic = Standard_True;
305       myHS2IsVPeriodic = Standard_False;
306       break;
307     }
308   case GeomAbs_Torus:
309     {
310       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
311       break;
312     }
313   default:
314      {
315        //-- Le cas de biparametrees periodiques est gere en amont
316        myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
317        break;
318      }
319   }
320   if(myHS1IsUPeriodic) {
321     lmf = M_PI+M_PI; //-- myHS1->UPeriod();
322     f = myHS1->FirstUParameter();
323     l = myHS1->LastUParameter();
324     fpls2=0.5*(f+l);
325     while((u1 < f)&&((fpls2-u1) > (u1+lmf-fpls2)   )) { u1+=lmf; } 
326     while((u1 > l)&&((u1-fpls2) > (fpls2-(u1-lmf)) )) { u1-=lmf; }
327     
328   }
329   if(myHS1IsVPeriodic) {
330     lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
331     f = myHS1->FirstVParameter();
332     l = myHS1->LastVParameter();
333     fpls2=0.5*(f+l);
334     while((v1 < f)&&((fpls2-v1) > (v1+lmf-fpls2)   )) { v1+=lmf; } 
335     while((v1 > l)&&((v1-fpls2) > (fpls2-(v1-lmf)) )) { v1-=lmf; }
336     //--    while(v1 < f) { v1+=lmf; } 
337     //--    while(v1 > l) { v1-=lmf; }
338   }
339   if(myHS2IsUPeriodic) { 
340     lmf = M_PI+M_PI; //-- myHS2->UPeriod();
341     f = myHS2->FirstUParameter();
342     l = myHS2->LastUParameter();
343     fpls2=0.5*(f+l);
344     while((u2 < f)&&((fpls2-u2) > (u2+lmf-fpls2)   )) { u2+=lmf; } 
345     while((u2 > l)&&((u2-fpls2) > (fpls2-(u2-lmf)) )) { u2-=lmf; }
346     //-- while(u2 < f) { u2+=lmf; } 
347     //-- while(u2 > l) { u2-=lmf; }
348   }
349   if(myHS2IsVPeriodic) { 
350     lmf = M_PI+M_PI; //-- myHS2->VPeriod();
351     f = myHS2->FirstVParameter();
352     l = myHS2->LastVParameter();
353     fpls2=0.5*(f+l);
354     while((v2 < f)&&((fpls2-v2) > (v2+lmf-fpls2)   )) { v2+=lmf; } 
355     while((v2 > l)&&((v2-fpls2) > (fpls2-(v2-lmf)) )) { v2-=lmf; }
356     //-- while(v2 < f) { v2+=lmf; } 
357     //-- while(v2 > l) { v2-=lmf; }
358   }
359 }
360 //=======================================================================
361 //function : PutPointsOnLine
362 //purpose  : 
363 //=======================================================================
364 void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
365                      const Handle(Adaptor3d_HSurface)& S2, 
366                      const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
367                      const IntPatch_SequenceOfLine& slin,
368                      const Standard_Boolean OnFirst,
369                      const Handle(Adaptor3d_TopolTool)& Domain,
370                      const IntSurf_Quadric& QuadSurf,
371                      const IntSurf_Quadric& OtherQuad,
372                      const Standard_Boolean multpoint,
373                      const Standard_Real Tolarc) { 
374   
375   // Traitement des point (de listpnt) de depart. On les replace sur
376   // la ligne d intersection, en leur affectant la transition correcte sur
377   // cette ligne.
378   Standard_Integer nbpnt = listpnt.Length();
379   Standard_Integer nblin=slin.Length();
380
381   if (!slin.Length() || !nbpnt) {
382     return;
383   }
384   //
385   Standard_Integer i,k;
386   Standard_Integer linenumber;
387   Standard_Real currentparameter,tolerance;
388   Standard_Real U1,V1,U2,V2;
389   Standard_Boolean goon;
390   
391   
392   gp_Pnt Psurf, ptbid;
393   gp_Vec Normale, Vtgint, Vtgrst;
394   
395   gp_Vec d1u,d1v;
396   gp_Pnt2d p2d;
397   gp_Vec2d d2d;
398   
399   IntSurf_Transition Transline,Transarc;
400
401   Handle(Adaptor2d_HCurve2d) currentarc;
402   Handle(Adaptor3d_HVertex) vtx,vtxbis;
403   
404   IntPatch_Point solpnt;
405   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
406   IntPatch_IType TheType;
407
408   TColStd_Array1OfInteger UsedLine(1,nblin);
409   TColStd_Array1OfInteger Done(1,nbpnt);
410   for(i=1;i<=nbpnt;i++) Done(i) = 0; //-- Initialisation a la main 
411   
412   for (i=1; i<=nbpnt; i++) {
413     
414     if (Done(i) != 1) {
415       currentpointonrst = listpnt.Value(i);
416       Psurf   = currentpointonrst.Value();   // Point dans l espace
417       tolerance = currentpointonrst.Tolerance();
418       
419       // On recherche d abord si on a correspondance avec un "point multiple"
420       UsedLine.Init(0);
421
422       goon = Standard_True;
423       if (multpoint) {
424 #if 1 
425         Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
426         currentarc = currentpointonrst.Arc();
427         currentparameter = currentpointonrst.Parameter();
428         currentarc->D1(currentparameter,p2d,d2d);
429         QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
430         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
431 #endif      
432         goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
433                              i, OnFirst, Tolarc);
434       }
435       if (goon) {
436         Standard_Boolean linefound = Standard_False;
437         
438         for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) { 
439           if( UsedLine(indiceline) != 0 )
440             continue;
441           linenumber = indiceline;
442
443           //-- Attention , les points peuvent etre deplaces 
444           //-- il faut reprendre le point original
445           currentpointonrst = listpnt.Value(i);
446           currentarc = currentpointonrst.Arc();
447           currentparameter = currentpointonrst.Parameter();
448           Psurf   = currentpointonrst.Value();   // Point dans l espace
449           tolerance = currentpointonrst.Tolerance();
450           //-- 
451
452
453           //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
454           if (! currentpointonrst.IsNew()) {
455             Handle(Adaptor3d_HVertex) aVtx    = currentpointonrst.Vertex();
456             Standard_Real aVtxTol = aVtx->Resolution(currentarc);
457             Standard_Real aTolAng = 0.01*tolerance;
458
459             tolerance = Max(tolerance, aVtxTol);
460
461             gp_Vec aNorm1  = QuadSurf.Normale(Psurf);
462             gp_Vec aNorm2  = OtherQuad.Normale(Psurf);
463             //
464             if (aNorm1.Magnitude()>gp::Resolution() &&
465                 aNorm2.Magnitude()>gp::Resolution()) { 
466             
467               if (aNorm1.IsParallel(aNorm2, aTolAng))
468                 tolerance = Sqrt(tolerance);
469             }//
470           }
471           //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
472           gp_Pnt pointonarc;
473           Vtgint.SetCoord(0,0,0);
474           Standard_Real aVertTol = Tolarc;
475           TColStd_ListOfReal aLParams;
476           linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
477                                indiceline, currentarc, currentparameter,
478                                pointonarc, QuadSurf, OtherQuad, aVertTol);
479           if (linefound) {
480             
481 #if 1 
482             Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
483             currentarc = currentpointonrst.Arc();
484             //-- currentparameter = currentpointonrst.Parameter();
485             currentarc->D1(currentparameter,p2d,d2d);
486             QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
487             Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
488 #endif      
489             
490             
491             
492             const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
493             TheType = lin->ArcType();
494             
495             if (!OnFirst) { // on cherche la correspondance entre point sur domaine
496               // de la premiere surface et point sur domaine de la
497               // deuxieme surface
498               
499               goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale, 
500                                        Vtgint, lin, Done, i, aVertTol);
501             }
502             
503             if (goon) {
504               //-- Modification du 4 avril 97    tolerance->Tolarc
505               //-- on replace sur le vertex la tolerance d entree et 
506               //-- non la tolerance qui a servi au FindLine
507               solpnt.SetValue(Psurf, aVertTol, Standard_False);
508               
509               U1 = p2d.X(); V1 = p2d.Y();
510               OtherQuad.Parameters(Psurf,U2,V2);
511               
512               if (OnFirst) {
513                 Recadre(S1,S2,U1,V1,U2,V2);
514                 solpnt.SetParameters(U1,V1,U2,V2);
515               }
516               else {
517                 Recadre(S1,S2,U2,V2,U1,V1);
518                 solpnt.SetParameters(U2,V2,U1,V1);
519               }
520               
521               if (! currentpointonrst.IsNew()) {
522                 vtx = currentpointonrst.Vertex();
523                 solpnt.SetVertex(OnFirst,vtx);
524               }
525               else {
526                 //-- goon = Standard_False; ???? 
527               }
528               
529               if(Normale.SquareMagnitude()<1e-16) { 
530                 Transline.SetValue(Standard_True,IntSurf_Undecided);
531                 Transarc.SetValue(Standard_True,IntSurf_Undecided);         
532               }
533               else {                            
534                 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
535               }
536               solpnt.SetArc(OnFirst,currentarc, currentparameter,
537                             Transline,Transarc);
538
539               for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
540                    anItr.More(); anItr.Next())
541               {
542                 solpnt.SetParameter(anItr.Value());
543                 if (TheType == IntPatch_Analytic)
544                 {
545                   Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
546                 }
547                 else
548                 {
549                   Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
550                 }
551               }
552
553               Done(i) = 1;
554               
555               if (goon) {
556                 for (k=i+1; k<= nbpnt; k++) {
557                   if (Done(k) != 1) {
558                     currentpointonrst = listpnt.Value(k);
559                     if (!currentpointonrst.IsNew()) {
560                       vtxbis = currentpointonrst.Vertex();
561                       if(vtx.IsNull()) { 
562                       }               
563                       else if (Domain->Identical(vtx, vtxbis)) {
564                         solpnt.SetVertex(OnFirst,vtxbis);
565                         solpnt.SetTolerance(Tolarc);
566                         currentarc = currentpointonrst.Arc();
567                         currentparameter = currentpointonrst.Parameter();
568                         
569                         //                    currentarc->D1(currentparameter,ptbid,Vtgrst);
570                         currentarc->D1(currentparameter,p2d,d2d);
571                         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
572                         if(Normale.SquareMagnitude()<1e-16) { 
573                           Transline.SetValue(Standard_True,IntSurf_Undecided);
574                           Transarc.SetValue(Standard_True,IntSurf_Undecided);       
575                         }
576                         else {                                    
577                           IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
578                                                   Transline,Transarc);
579                         }
580                         solpnt.SetArc(OnFirst,currentarc,currentparameter,
581                                       Transline,Transarc);
582                         if (TheType == IntPatch_Analytic) {
583                           Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
584                         }
585                         else {
586                           Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
587                         }
588                         Done(k) = 1;
589                       }
590                     }
591                   }
592                 }
593               }
594             }
595           }
596           else {
597             Done(i) = 1; // il faudra tester si IsNew ou pas
598             // et traiter en consequence
599           }
600         }
601       }
602     }
603   }
604 }
605
606
607 Standard_Boolean  MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
608                                  const Handle(Adaptor3d_TopolTool)& Domain,
609                                  const IntSurf_Quadric& QuadSurf,
610                                  const gp_Vec&    Normale,
611                                  const IntPatch_SequenceOfLine& slin,
612                                  TColStd_Array1OfInteger& Done,
613                                  TColStd_Array1OfInteger& UsedLine,
614                                  const Standard_Integer Index,
615                                  const Standard_Boolean OnFirst,
616                                  const Standard_Real theToler) {
617
618 // Traitement des points "multiples".
619
620   
621   Standard_Integer k,ii,jj,nbvtx;
622   Standard_Integer nblin = slin.Length();
623   IntPatch_IType TheType;
624   
625   
626   IntSurf_Transition Transline,Transarc;
627
628
629   IntPatch_Point intpt;
630   Handle(Adaptor2d_HCurve2d) currentarc;
631   Handle(Adaptor3d_HVertex) vtx,vtxbis;
632
633   Standard_Integer nbpnt = listpnt.Length();
634   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
635   IntPatch_ThePathPointOfTheSOnBounds otherpt;
636   gp_Pnt Point = currentpointonrst.Value();
637   TColStd_Array1OfInteger localdone(1,nbpnt); localdone.Init(0);
638   for (ii=1; ii<=nbpnt; ii++) {
639     localdone(ii)=Done(ii);
640   }
641
642   Standard_Real currentparameter;
643   Standard_Real Paraint;
644   gp_Vec Vtgint,Vtgrst;
645   gp_Pnt ptbid;
646
647   gp_Vec d1u,d1v;
648   gp_Pnt2d p2d;
649   gp_Vec2d d2d;
650
651   Standard_Boolean goon;
652
653   Standard_Boolean Retvalue = Standard_True;
654
655   for (ii = 1; ii <= nblin; ii++) {
656     const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
657     TheType = slinValueii->ArcType();
658     if (TheType == IntPatch_Analytic) {
659       nbvtx = Handle(IntPatch_ALine)::DownCast (slinValueii)->NbVertex();
660     }
661     else {
662       nbvtx = Handle(IntPatch_GLine)::DownCast (slinValueii)->NbVertex();
663     }
664     jj = 1;
665     while (jj <= nbvtx) {
666       if (TheType == IntPatch_Analytic) {
667         intpt = Handle(IntPatch_ALine)::DownCast (slinValueii)->Vertex(jj);
668       }
669       else {
670         intpt = Handle(IntPatch_GLine)::DownCast (slinValueii)->Vertex(jj);
671       }
672       if (intpt.IsMultiple() && 
673           (( OnFirst && !intpt.IsOnDomS1()) ||
674            (!OnFirst && !intpt.IsOnDomS2()))) {
675         if (Point.Distance(intpt.Value()) <= intpt.Tolerance()) {
676           Retvalue = Standard_False;
677           Standard_Boolean foo = SingleLine(Point,slinValueii,
678                                             intpt.Tolerance(),Paraint,Vtgint);
679           if (!foo) {
680             return Standard_False;   // ne doit pas se produire
681           }
682
683           if (!currentpointonrst.IsNew()) {
684             goon = Standard_True;
685             vtx = currentpointonrst.Vertex();
686             intpt.SetVertex(OnFirst,vtx);
687           } 
688           else {
689             goon = Standard_False;
690           }
691           currentarc = currentpointonrst.Arc();
692           currentparameter = currentpointonrst.Parameter();
693           currentarc->D1(currentparameter,p2d,d2d);
694           QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
695           Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
696
697           //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
698           if(Normale.SquareMagnitude()<1e-16) { 
699             Transline.SetValue(Standard_True,IntSurf_Undecided);
700             Transarc.SetValue(Standard_True,IntSurf_Undecided);     
701           }
702           else { 
703             IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
704           }
705
706           //-- Avant, on ne mettait pas ce point (17 nov 97)
707           //--printf("\n ImpImp_0  : Point(%g,%g,%g)  intpt(%g,%g,%g) \n",
708           //--  Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
709           intpt.SetValue(Point);
710
711           intpt.SetArc(OnFirst,currentarc,currentparameter,
712                        Transline,Transarc);
713           intpt.SetTolerance(theToler);
714
715           if (TheType == IntPatch_Analytic) {
716             Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
717           }
718           else {
719             Handle(IntPatch_GLine)::DownCast (slinValueii)->Replace(jj,intpt);
720           }
721           localdone(Index) = 1;
722           if (goon) {
723             for (k=Index+1; k<= nbpnt; k++) {
724               if (Done(k) != 1) {
725                 otherpt= listpnt.Value(k);
726                 if (!otherpt.IsNew()) {
727                   vtxbis = otherpt.Vertex();
728                   if (Domain->Identical(vtx, vtxbis)) {
729                     intpt.SetVertex(OnFirst,vtxbis);
730                     currentarc = otherpt.Arc();
731                     currentparameter = otherpt.Parameter();
732                     
733                     currentarc->D1(currentparameter,p2d,d2d);
734                     Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
735                     if(Normale.SquareMagnitude()<1e-16) { 
736                       Transline.SetValue(Standard_True,IntSurf_Undecided);
737                       Transarc.SetValue(Standard_True,IntSurf_Undecided);           
738                     }
739                     else {    
740                       IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
741                                               Transline,Transarc);
742                     }
743                     intpt.SetArc(OnFirst,currentarc,currentparameter,
744                                  Transline,Transarc);
745                     intpt.SetTolerance(theToler);
746                     if (TheType == IntPatch_Analytic) {
747                       Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
748                     }
749                     else {
750                       Handle(IntPatch_GLine)::DownCast (slinValueii)->AddVertex(intpt);
751                     }
752                     UsedLine(ii) = 1;
753                     Retvalue = Standard_True;
754                     localdone(k) = 1;
755                   }
756                 }
757               }
758             }
759           }
760 //--           jj = nbvtx +1;
761         }
762 //--         else {
763           jj = jj+1;
764 //--        }
765       }
766       else {
767         jj = jj+1;
768       }
769     }
770   }
771   
772   for (ii=1; ii<=nbpnt;ii++) {
773     Done(ii) = localdone(ii);
774   }
775   
776   return Retvalue;
777 }
778     
779
780
781 Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
782                                    const Handle(Adaptor3d_TopolTool)& Domain,
783                                    const IntSurf_Quadric& QuadSurf,
784                                    const gp_Vec&    Normale,
785                                    const gp_Vec&    Vtgint,
786                                    const Handle(IntPatch_Line)& lin,
787                                    TColStd_Array1OfInteger& Done,
788                                    const Standard_Integer Index,
789                                    const Standard_Real theToler)
790      
791
792 // Duplication des points sur domaine de l autre surface.
793 // On sait que le vertex sous-jacent est PntRef
794
795
796 {
797
798   Standard_Integer k,jj,nbvtx;
799   IntPatch_IType TheType;
800
801   IntSurf_Transition Transline,Transarc;
802   IntPatch_Point intpt;
803   Handle(Adaptor2d_HCurve2d) currentarc;
804   Handle(Adaptor3d_HVertex) vtx,vtxbis;
805   gp_Pnt ptbid;
806   gp_Vec Vtgrst;
807
808   gp_Vec d1u,d1v;
809   gp_Pnt2d p2d;
810   gp_Vec2d d2d;
811
812   Standard_Integer nbpnt = listpnt.Length();
813   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
814   Standard_Real currentparameter;
815
816   Standard_Boolean goon;
817   Standard_Boolean Retvalue = Standard_True;
818
819   TheType = lin->ArcType();
820   if (TheType == IntPatch_Analytic) {
821     nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
822   }
823   else {
824     nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
825   }
826   jj = 1;
827   while (jj <= nbvtx) {
828     if (TheType == IntPatch_Analytic) {
829       intpt = Handle(IntPatch_ALine)::DownCast (lin)->Vertex(jj);
830     }
831     else {
832       intpt = Handle(IntPatch_GLine)::DownCast (lin)->Vertex(jj);
833     }
834     if (!intpt.IsOnDomS2()) {
835       if (currentpointonrst.Value().Distance(intpt.Value()) <= 
836           intpt.Tolerance()) {
837         Retvalue = Standard_False;
838         if (!currentpointonrst.IsNew()) {
839           goon = Standard_True;
840           vtx = currentpointonrst.Vertex();
841           intpt.SetVertex(Standard_False,vtx);
842         }
843         else {
844           goon = Standard_False;
845         }
846         currentarc = currentpointonrst.Arc();
847         currentparameter = currentpointonrst.Parameter();
848         currentarc->D1(currentparameter,p2d,d2d);
849         QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
850         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
851         if(Normale.SquareMagnitude()<1e-16) { 
852           Transline.SetValue(Standard_True,IntSurf_Undecided);
853           Transarc.SetValue(Standard_True,IntSurf_Undecided);       
854         }
855         else {          
856           IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
857         }
858         intpt.SetArc(Standard_False,currentarc,currentparameter,
859                      Transline,Transarc);
860         intpt.SetTolerance(theToler);
861
862         if (TheType == IntPatch_Analytic) {
863           Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
864         }
865         else {
866           Handle(IntPatch_GLine)::DownCast (lin)->Replace(jj,intpt);
867         }
868         Done(Index) = 1;
869
870         if (goon) {
871           for (k=Index+1; k<= nbpnt; k++) {
872             if (Done(k) != 1) {
873               currentpointonrst = listpnt.Value(k);
874               if (!currentpointonrst.IsNew()) {
875                 vtxbis = currentpointonrst.Vertex();
876                   if (Domain->Identical(vtx, vtxbis)) {
877                   intpt.SetVertex(Standard_False,vtxbis);
878                   currentarc = currentpointonrst.Arc();
879                   currentparameter = currentpointonrst.Parameter();
880                   currentarc->D1(currentparameter,p2d,d2d);
881                   Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
882                   if(Normale.SquareMagnitude()<1e-16) { 
883                     Transline.SetValue(Standard_True,IntSurf_Undecided);
884                     Transarc.SetValue(Standard_True,IntSurf_Undecided);     
885                   }
886                   else {                                    
887                     IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
888                                             Transline,Transarc);
889                   }
890                   intpt.SetArc(Standard_False,currentarc,currentparameter,
891                                Transline,Transarc);
892                   intpt.SetTolerance(theToler);
893                   if (TheType == IntPatch_Analytic) {
894                     Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
895                   }
896                   else {
897                     Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(intpt);
898                   }
899                   Done(k) = 1;
900                 }
901               }
902             }
903           }
904         }
905         //-- jj = nbvtx + 1;
906         jj++;
907       }
908       else {
909         jj = jj+1;
910       }
911     }
912     else {
913       jj = jj+1;
914     }
915     if (TheType == IntPatch_Analytic) {
916       nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
917     }
918     else {
919       nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
920     }
921   }
922   return Retvalue;
923 }
924
925
926
927 Standard_Boolean FindLine(gp_Pnt& Psurf,
928                           const IntPatch_SequenceOfLine& slin,
929                           const Standard_Real Tol,
930                           TColStd_ListOfReal& theLParams,
931                           gp_Vec& Vtgtint,
932                           Standard_Integer& theLineIdx,
933                           Standard_Integer OnlyThisLine,
934                           const Handle(Adaptor2d_HCurve2d)& thearc,
935                           Standard_Real& theparameteronarc,
936                           gp_Pnt& thepointonarc,
937                           const IntSurf_Quadric& QuadSurf1,
938                           const IntSurf_Quadric& QuadSurf2,
939                           Standard_Real& theOutputToler)
940 {
941   if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
942     return Standard_False;
943
944 // Traitement du point de depart ayant pour representation Psurf
945 // dans l espace. On recherche la ligne d intersection contenant ce point.
946 // On a en sortie la ligne, et le parametre et sa tangente du point sur
947 // la ligne d intersection.
948   const Standard_Real aSqTol = Tol*Tol;
949   Standard_Real aSqDistMin = RealLast();
950   Standard_Real aSqDist, para;
951   Standard_Real lower,upper;
952   gp_Pnt pt;
953   Standard_Integer i;
954   IntPatch_IType typarc;
955
956   Standard_Real aParaInt = RealLast();
957   Standard_Integer nblin = slin.Length();
958   for (i=1; i<=nblin; i++) {
959     if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
960     const Handle(IntPatch_Line)& lin = slin.Value(i);
961     typarc = lin->ArcType();
962     if (typarc == IntPatch_Analytic) {
963       Standard_Boolean foo;
964       lower = Handle(IntPatch_ALine)::DownCast (lin)->FirstParameter(foo);
965       upper = Handle(IntPatch_ALine)::DownCast (lin)->LastParameter(foo);
966     }
967     else {
968       if (Handle(IntPatch_GLine)::DownCast (lin)->HasFirstPoint()) {
969         lower = Handle(IntPatch_GLine)::DownCast (lin)->FirstPoint().ParameterOnLine();
970       }
971       else {
972         lower = RealFirst();
973       }
974       if (Handle(IntPatch_GLine)::DownCast (lin)->HasLastPoint()) {
975         upper = Handle(IntPatch_GLine)::DownCast (lin)->LastPoint().ParameterOnLine();
976       }
977       else {
978         upper = RealLast();
979       }
980     }
981
982     switch (typarc) {
983     case IntPatch_Lin :
984       {
985         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
986         if (para <= upper && para >= lower) {
987           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
988           aSqDist = Psurf.SquareDistance(pt);
989           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
990           {
991             aSqDistMin = aSqDist;
992             aParaInt = para;
993             theLineIdx = i;
994           }
995         }
996       }
997       break;
998     case IntPatch_Circle :
999       {
1000         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1001         if ((para <= upper && para >= lower) ||
1002             (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1003             (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1004           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
1005           aSqDist = Psurf.SquareDistance(pt);
1006           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1007           {
1008             aSqDistMin = aSqDist;
1009             aParaInt = para;
1010             theLineIdx = i;
1011           }
1012         }
1013       }
1014       break;
1015     case IntPatch_Ellipse :
1016       {
1017         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1018         if ((para <= upper && para >= lower) ||
1019             (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1020             (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1021           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
1022           aSqDist = Psurf.SquareDistance(pt);
1023           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1024           {
1025             aSqDistMin = aSqDist;
1026             aParaInt = para;
1027             theLineIdx = i;
1028           }
1029         }
1030       }
1031       break;
1032     case IntPatch_Parabola :
1033       {
1034         
1035 #if 0   
1036         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1037         if (para <= upper && para >= lower) {
1038           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
1039           dist = Psurf.Distance(pt);
1040           if (dist< distmin) {
1041             distmin = dist;
1042             Paraint = para;
1043             Range = i;
1044           }
1045         }
1046 #else 
1047         //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
1048         //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres 
1049         //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
1050         //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
1051         const gp_Parab& Parab=Handle(IntPatch_GLine)::DownCast (lin)->Parabola();
1052         para = ElCLib::Parameter(Parab,Psurf);
1053         if (para <= upper && para >= lower) {
1054           Standard_Integer amelioration=0;
1055           //-- cout<<"\n ****** \n";
1056           do { 
1057             Standard_Real parabis = para+0.0000001;
1058             
1059             pt = ElCLib::Value(para,Parab);
1060             aSqDist = Psurf.SquareDistance(pt);
1061             
1062             const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
1063             const Standard_Real distbis = Psurf.Distance(ptbis);
1064             const Standard_Real aDist = Sqrt(aSqDist);
1065             const Standard_Real ddist = distbis - aDist;
1066             
1067             //--cout<<" para: "<<para<<"    dist:"<<dist<<"   ddist:"<<ddist<<endl;
1068             
1069             if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1070             {
1071               aSqDistMin = aSqDist;
1072               aParaInt = para;
1073               theLineIdx = i;
1074             }
1075             if (aSqDist < Precision::SquarePConfusion())
1076             {
1077               amelioration = 100;
1078             }
1079               
1080             if(ddist>1.0e-9 || ddist<-1.0e-9 ) { 
1081               para = para - aDist*(parabis - para) / ddist;
1082             }
1083             else { 
1084               amelioration=100;
1085             }
1086           }
1087           while(++amelioration < 5);
1088         }
1089
1090
1091 #endif
1092       }
1093       break;
1094     case IntPatch_Hyperbola :
1095       {
1096         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1097         if (para <= upper && para >= lower) {
1098           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
1099           aSqDist = Psurf.SquareDistance(pt);
1100           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1101           {
1102             aSqDistMin = aSqDist;
1103             aParaInt = para;
1104             theLineIdx = i;
1105           }
1106         }
1107       }
1108       break;
1109
1110     case IntPatch_Analytic :
1111       {
1112         Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1113         TColStd_ListOfReal aLParams;
1114         alin->FindParameter(Psurf, aLParams);
1115         if (!aLParams.IsEmpty())
1116         {
1117           // All found distances are already in some internal tolerance
1118           // set in alin->FindParameter(...) method.
1119
1120           aSqDist = RealLast();
1121           for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
1122                anItr.More(); anItr.Next())
1123           {
1124             pt = alin->Value(anItr.Value());
1125             const Standard_Real aSqD = Psurf.SquareDistance(pt);
1126             if (aSqD < aSqDist)
1127             {
1128               aSqDist = aSqD;
1129             }
1130           }
1131
1132           if (aSqDist < aSqDistMin)
1133           {
1134             aSqDistMin = aSqDist;
1135             theLParams = aLParams;
1136             theLineIdx = i;
1137           }
1138         }
1139         else { 
1140           //-- le point n a pas ete trouve par bete projection.
1141           //-- on essaie l intersection avec la restriction en 2d
1142           Standard_Real theparamonarc = theparameteronarc;
1143 //#ifdef OCCT_DEBUG
1144 //        Standard_Real anpara=para;
1145 //#endif
1146           gp_Pnt CopiePsurf=Psurf;
1147           Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para, 
1148                                                                  thearc, theparamonarc,
1149                                                                  thepointonarc,
1150                                                                  QuadSurf1,
1151                                                                  lower, upper);
1152           aSqDist = CopiePsurf.SquareDistance(Psurf);
1153           if(IntersectIsOk) {
1154             if (aSqDist < aSqTol)
1155             {
1156               theparameteronarc = theparamonarc;
1157               Psurf = thepointonarc;
1158               aSqDistMin = aSqDist;
1159               theLParams.Append(para);
1160               theLineIdx = i;
1161             }
1162           }
1163         }
1164       }
1165       break;
1166
1167     case IntPatch_Walking: // impossible . c est pour eviter les warnings
1168       {
1169       }
1170     case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1171       {
1172       }
1173     }
1174   }
1175
1176   if (aSqDistMin == RealLast())
1177     return Standard_False;
1178
1179   theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
1180
1181   typarc = slin.Value(theLineIdx)->ArcType();
1182
1183   // Computation of tangent vector
1184   switch (typarc) {
1185   case IntPatch_Lin :
1186     theLParams.Append(aParaInt);
1187     Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
1188     break;
1189   case IntPatch_Circle :
1190     theLParams.Append(aParaInt);
1191     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
1192     break;
1193   case IntPatch_Ellipse :
1194     theLParams.Append(aParaInt);
1195     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
1196     break;
1197   case IntPatch_Parabola :
1198     theLParams.Append(aParaInt);
1199     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
1200     break;
1201   case IntPatch_Hyperbola :
1202     theLParams.Append(aParaInt);
1203     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
1204     break;
1205
1206   case IntPatch_Analytic:
1207     {
1208       if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
1209       {
1210         //Previously (before the fix #29807) this code tried to process case
1211         //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1212         //computed Vtgtint input argument value. Currently, any singularities
1213         //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1214         //Therefore this code has been deleted as deprecated.
1215
1216         Vtgtint.SetCoord(0.0, 0.0, 0.0);
1217       }
1218     }
1219     break;
1220   case IntPatch_Walking: // impossible . c est pour eviter les warnings
1221     {
1222     }
1223   case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1224     {
1225     }
1226     
1227   }
1228   return Standard_True;
1229 }
1230
1231 //=======================================================================
1232 //function : SingleLine
1233 //purpose  : Traitement du point de depart ayant pour representation Psurf
1234 //            dans l espace. On le replace sur la ligne d intersection; On a en sortie
1235 //            son parametre et sa tangente sur la ligne d intersection.
1236 //            La fonction renvoie False si le point projete est a une distance
1237 //            superieure a Tol du point a projeter.
1238 //=======================================================================
1239 Standard_Boolean  SingleLine(const gp_Pnt& Psurf,
1240                              const Handle(IntPatch_Line)& lin,
1241                              const Standard_Real Tol,
1242                              Standard_Real& Paraint,
1243                              gp_Vec& Vtgtint)
1244 {
1245   IntPatch_IType typarc = lin->ArcType();
1246
1247   Standard_Real parproj = 0.;
1248   gp_Vec tgint;
1249   gp_Pnt ptproj;
1250   Standard_Boolean retvalue;
1251
1252   switch (typarc) {
1253   case IntPatch_Lin :
1254     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
1255     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Line(),ptproj,tgint);
1256     break;
1257   case IntPatch_Circle :
1258     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1259     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Circle(),ptproj,tgint);
1260     break;
1261   case IntPatch_Ellipse :
1262     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1263     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),ptproj,tgint);
1264     break;
1265   case IntPatch_Parabola :
1266     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1267     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),ptproj,tgint);
1268     break;
1269   case IntPatch_Hyperbola :
1270     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1271     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),ptproj,tgint);
1272     break;
1273   case IntPatch_Analytic :
1274     {
1275       Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1276       TColStd_ListOfReal aLParams;
1277       alin->FindParameter(Psurf, aLParams);
1278       if (!aLParams.IsEmpty())
1279       {
1280         ptproj = Psurf;
1281         parproj = aLParams.Last();
1282         gp_Pnt aPtemp;
1283         if (!alin->D1(parproj, aPtemp, tgint))
1284         {
1285           //Previously (before the fix #29807) this code tried to process case
1286           //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1287           //computed Vtgtint input argument value. Currently, any singularities
1288           //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1289           //Therefore this code has been deleted as deprecated.
1290
1291           tgint.SetCoord(0.0, 0.0, 0.0);
1292         }
1293       }
1294       else
1295       {
1296         //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
1297         //-- cout << "     Find Parameter"<<endl;
1298         return Standard_False;
1299       }
1300     }
1301     break;
1302   case IntPatch_Walking: // impossible . c est pour eviter les warnings
1303     {
1304     }
1305   case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1306     {
1307     }
1308   }
1309
1310   if (Psurf.Distance(ptproj) <= Tol) {
1311     Paraint = parproj;
1312     Vtgtint = tgint;
1313     retvalue = Standard_True;
1314   }
1315   else {
1316     retvalue = Standard_False;
1317   }
1318   return retvalue;
1319 }
1320
1321
1322 void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
1323                       IntPatch_SequenceOfLine& slin,
1324                       const IntSurf_Quadric& Quad1,
1325                       const IntSurf_Quadric& Quad2,
1326                       const Standard_Boolean OnFirst,
1327                       const Standard_Real TolArc) {
1328      
1329   Standard_Integer i,j,k;
1330   Standard_Integer nbedg = listedg.Length();
1331   Standard_Integer Nblines,Nbpts;
1332
1333   Handle(Adaptor2d_HCurve2d) arcRef;
1334   IntPatch_Point ptvtx, newptvtx;
1335
1336   Handle(IntPatch_RLine)  rline; //-- On fait rline = new ... par la suite 
1337
1338   IntPatch_TheSegmentOfTheSOnBounds thesegsol;
1339   IntPatch_ThePathPointOfTheSOnBounds PStartf,PStartl;
1340   Standard_Boolean dofirst,dolast,procf,procl;
1341
1342   Standard_Real paramf =0.,paraml =0.,U1 =0.,V1 =0.,U2 =0.,V2 =0.;
1343
1344   IntPatch_IType typ;
1345   IntSurf_TypeTrans trans1,trans2;
1346   IntSurf_Transition TRest,TArc;
1347   gp_Vec tgline,norm1,norm2,tgarc;
1348   gp_Pnt valpt;
1349
1350   gp_Vec d1u,d1v;
1351   gp_Pnt2d p2d;
1352   gp_Vec2d d2d;
1353
1354
1355   for (i = 1; i <= nbedg; i++) {
1356     Standard_Boolean EdgeDegenere=Standard_False;
1357     thesegsol = listedg.Value(i);
1358     arcRef = thesegsol.Curve();
1359
1360
1361     rline = new IntPatch_RLine(Standard_False);
1362     if(OnFirst) { 
1363       rline->SetArcOnS1(arcRef);
1364     }
1365     else { 
1366       rline->SetArcOnS2(arcRef);
1367     }
1368
1369 // Traitement des points debut/fin du segment solution.
1370
1371     dofirst = Standard_False;
1372     dolast  = Standard_False;
1373     procf = Standard_False;
1374     procl = Standard_False;
1375
1376     if (thesegsol.HasFirstPoint()) {
1377       dofirst = Standard_True;
1378       PStartf = thesegsol.FirstPoint();
1379       paramf = PStartf.Parameter();
1380     }
1381     if (thesegsol.HasLastPoint()) {
1382       dolast = Standard_True;
1383       PStartl = thesegsol.LastPoint();
1384       paraml = PStartl.Parameter();
1385     }
1386
1387     if (dofirst && dolast) { // determination de la transition de la ligne
1388       arcRef->D1(0.5*(paramf+paraml),p2d,d2d);
1389       if (OnFirst) {
1390         Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1391       }
1392       else {
1393         Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1394       }
1395       tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1396
1397       if(d1u.Magnitude()<1e-7) { //-- edge degenere ?
1398          EdgeDegenere=Standard_True;
1399         for(Standard_Integer edg=0;edg<=10;edg++) {
1400           arcRef->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1401           if (OnFirst) {
1402             Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1403           }
1404           else {
1405             Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1406           }
1407           
1408           if(d1u.Magnitude()>1e-7) {
1409             EdgeDegenere=Standard_False;
1410           }
1411         }
1412         rline = new IntPatch_RLine(Standard_False);     
1413         if(OnFirst) { 
1414           rline->SetArcOnS1(arcRef);
1415         }
1416         else { 
1417           rline->SetArcOnS2(arcRef);
1418         }       
1419       }
1420       else { 
1421         norm2 = Quad2.Normale(valpt);
1422         norm1 = Quad1.Normale(valpt);
1423         
1424         if (tgline.DotCross(norm2,norm1) > 0.000000001) {
1425           trans1 = IntSurf_Out;
1426           trans2 = IntSurf_In;
1427         }
1428         else if (tgline.DotCross(norm2,norm1) < -0.000000001){
1429           trans1 = IntSurf_In;
1430           trans2 = IntSurf_Out;
1431         }
1432         else { 
1433           trans1 = trans2 = IntSurf_Undecided;
1434         }
1435         rline = new IntPatch_RLine(Standard_False,trans1,trans2);
1436         if(OnFirst) { 
1437           rline->SetArcOnS1(arcRef);
1438         }
1439         else { 
1440           rline->SetArcOnS2(arcRef);
1441         }       
1442       }
1443     }
1444     else {
1445       rline = new IntPatch_RLine(Standard_False);
1446       if(OnFirst) { 
1447         rline->SetArcOnS1(arcRef);
1448       }
1449       else { 
1450         rline->SetArcOnS2(arcRef);
1451       } 
1452     }
1453
1454     if (dofirst || dolast) {
1455       Nblines = slin.Length();
1456       for (j=1; j<=Nblines; j++) {
1457         const Handle(IntPatch_Line)& slinj = slin(j);
1458         typ = slinj->ArcType();
1459         if (typ == IntPatch_Analytic) {
1460           Nbpts = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1461         }
1462         else if (typ == IntPatch_Restriction) {
1463           Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
1464         }
1465         else {
1466           Nbpts = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1467         }
1468         for (k=1; k<=Nbpts;k++) {
1469           if (typ == IntPatch_Analytic) {
1470             ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1471           }
1472           else if (typ == IntPatch_Restriction) {
1473             ptvtx = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1474           }
1475           else {
1476             ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1477           }
1478           
1479           if (EdgeDegenere==Standard_False && dofirst) {
1480             if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
1481               ptvtx.SetMultiple(Standard_True);
1482               ptvtx.SetTolerance(TolArc);
1483               if (typ == IntPatch_Analytic) {
1484                 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1485               }
1486               else if (typ == IntPatch_Restriction) {
1487                 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1488               }
1489               else {
1490                 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1491               }
1492               newptvtx = ptvtx;
1493               newptvtx.SetParameter(paramf);
1494               //Recalcul des  transitions si point sur restriction
1495
1496               arcRef->D1(paramf,p2d,d2d);
1497               if (OnFirst) {
1498                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1499               }
1500               else {
1501                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1502               }
1503               tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1504               if (ptvtx.IsOnDomS1()) {
1505                 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS1();
1506                 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1507                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1508                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1509                 norm1 = d1u.Crossed(d1v); 
1510                 if(norm1.SquareMagnitude()<1e-16) { 
1511                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1512                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1513                 }
1514                 else {          
1515                   IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1516                 }
1517                 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1518                                 TRest,TArc);
1519               }
1520               if (ptvtx.IsOnDomS2()) {
1521                 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS2();
1522                 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1523                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1524                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1525                 norm2 = d1u.Crossed(d1v);
1526                 if(norm2.SquareMagnitude()<1e-16) { 
1527                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1528                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1529                 }
1530                 else {                            
1531                   IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1532                 }
1533                 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1534                                 TRest,TArc);
1535               }
1536
1537               rline->AddVertex(newptvtx);
1538               if (!procf){
1539                 procf=Standard_True;
1540                 rline->SetFirstPoint(rline->NbVertex());
1541               }
1542             }
1543           }
1544           if (EdgeDegenere==Standard_False && dolast) {
1545             if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
1546               ptvtx.SetMultiple(Standard_True);
1547               ptvtx.SetTolerance(TolArc);
1548               if (typ == IntPatch_Analytic) {
1549                 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1550               }
1551               else if (typ == IntPatch_Restriction) {
1552                 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1553               }
1554               else {
1555                 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1556               }
1557
1558               newptvtx = ptvtx;
1559               newptvtx.SetParameter(paraml);
1560               //Recalcul des  transitions si point sur restriction
1561
1562               arcRef->D1(paraml,p2d,d2d);
1563               if (OnFirst) {
1564                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1565               }
1566               else {
1567                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1568               }
1569               tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1570               if (ptvtx.IsOnDomS1()) {
1571                 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS1();
1572                 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1573                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1574                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1575                 norm1 = d1u.Crossed(d1v);
1576                 if(norm1.SquareMagnitude()<1e-16) { 
1577                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1578                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1579                 }
1580                 else {          
1581                   IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1582                 }
1583                 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1584                                 TRest,TArc);
1585               }
1586               if (ptvtx.IsOnDomS2()) {
1587                 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS2();
1588                 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1589                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1590                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1591                 norm2 = d1u.Crossed(d1v);
1592                 if(norm2.SquareMagnitude()<1e-16) { 
1593                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1594                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1595                 }
1596                 else {                        
1597                   IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1598                 }
1599                 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1600                                 TRest,TArc);
1601               }
1602
1603               rline->AddVertex(newptvtx);
1604               if (!procl){
1605                 procl=Standard_True;
1606                 rline->SetLastPoint(rline->NbVertex());
1607               }
1608             }
1609           }
1610         }
1611 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
1612 // il (ils) correspond(ent) a un point multiple.
1613
1614         if (procf) {
1615           dofirst = Standard_False;
1616         }
1617         if (procl) {
1618           dolast  = Standard_False;
1619         }
1620       }
1621     }
1622 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
1623 // d intersection, il faut quand-meme le placer sur la restriction solution
1624
1625     if (dofirst) {
1626       ptvtx.SetValue(PStartf.Value(),PStartf.Tolerance(),Standard_False);
1627       Quad1.Parameters(PStartf.Value(),U1,V1);
1628       Quad2.Parameters(PStartf.Value(),U2,V2);
1629       ptvtx.SetParameters(U1,V1,U2,V2);
1630       ptvtx.SetParameter(paramf);
1631       if (! PStartf.IsNew()) {
1632         IntSurf_Transition Transline;
1633         IntSurf_Transition Transarc;
1634         ptvtx.SetVertex(OnFirst,PStartf.Vertex());
1635         ptvtx.SetArc(OnFirst,PStartf.Arc(),PStartf.Parameter(),
1636                      Transline,Transarc);
1637       }
1638
1639       rline->AddVertex(ptvtx);
1640       rline->SetFirstPoint(rline->NbVertex());
1641     }
1642     if (dolast) {
1643       ptvtx.SetValue(PStartl.Value(),PStartl.Tolerance(),Standard_False);
1644       Quad1.Parameters(PStartl.Value(),U1,V1);
1645       Quad2.Parameters(PStartl.Value(),U2,V2);
1646       ptvtx.SetParameters(U1,V1,U2,V2);
1647       ptvtx.SetParameter(paraml);
1648       if (! PStartl.IsNew()) {
1649         IntSurf_Transition Transline;
1650         IntSurf_Transition Transarc;
1651
1652         ptvtx.SetVertex(OnFirst,PStartl.Vertex());
1653         ptvtx.SetArc(OnFirst,PStartl.Arc(),PStartl.Parameter(),
1654                      Transline,Transarc);
1655       }
1656
1657       rline->AddVertex(ptvtx);
1658       rline->SetLastPoint(rline->NbVertex());
1659     }
1660     slin.Append(rline);
1661   }
1662 }
1663
1664 inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine,
1665                                 const Standard_Integer theIndex)
1666 {
1667   return theRLine->Point(theIndex).Value();
1668 }
1669
1670 inline const gp_Pnt& VertexValue( const Handle(IntPatch_RLine) theRLine,
1671                                   const Standard_Integer theIndex)
1672 {
1673   return theRLine->Vertex(theIndex).Value();
1674 }
1675
1676 static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine,
1677                                     const gp_Pnt& theP,
1678                                     Extrema_ExtPC& theExtr)
1679 {
1680   Standard_Real aSQDist = RealLast();
1681   switch(theGLine->ArcType())
1682   {
1683   case IntPatch_Lin:
1684     aSQDist = theGLine->Line().SquareDistance(theP);
1685     break;
1686   case IntPatch_Circle:
1687     aSQDist = theGLine->Circle().SquareDistance(theP);
1688     break;
1689   default:
1690     theExtr.Perform(theP);
1691     if(!theExtr.IsDone() || !theExtr.NbExt())
1692     {
1693       //Lines are not overlapped
1694       return aSQDist;
1695     }
1696
1697     aSQDist = theExtr.SquareDistance(1);
1698     const Standard_Integer aNbExtr = theExtr.NbExt();
1699     for ( Standard_Integer i = 2; i <= aNbExtr; i++)
1700     {
1701       const Standard_Real aSQD = theExtr.SquareDistance(i);
1702       if (aSQD < aSQDist)
1703       {
1704         aSQDist = aSQD;
1705       }
1706     }
1707   }
1708
1709   return aSQDist;
1710 }
1711
1712 static Standard_Boolean IsRLineGood(const IntSurf_Quadric& Quad1,
1713                                     const IntSurf_Quadric& Quad2,
1714                                     const Handle(IntPatch_GLine) theGLine,
1715                                     const Handle(IntPatch_RLine) theRLine,
1716                                     const Standard_Real theTol)
1717 {
1718   const Standard_Real aSQTol = theTol*theTol;
1719   const IntPatch_IType aGType = theGLine->ArcType();
1720   Standard_Integer aNbPntsM1 = 0;
1721   
1722   const gp_Pnt& (*Value) (const Handle(IntPatch_RLine), const Standard_Integer);
1723
1724   if(theRLine->HasPolygon())
1725   {
1726     aNbPntsM1 = theRLine->NbPnts()-1;
1727     Value = PointValue;
1728   }
1729   else
1730   {
1731     aNbPntsM1 = theRLine->NbVertex()-1;
1732     Value = VertexValue;
1733   }
1734   
1735   if(aNbPntsM1 < 1)
1736     return Standard_False;
1737
1738   Extrema_ExtPC anExtr;
1739   GeomAdaptor_Curve anAC;
1740   Handle(Geom_Curve) aCurv;
1741
1742   if(aGType == IntPatch_Ellipse)
1743     aCurv = new Geom_Ellipse(theGLine->Ellipse());
1744   else if(aGType == IntPatch_Parabola)
1745     aCurv = new Geom_Parabola(theGLine->Parabola());
1746   else if(aGType == IntPatch_Hyperbola)
1747     aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
1748   
1749   if(!aCurv.IsNull())
1750   {
1751     const Standard_Real anUinf = aCurv->FirstParameter(),
1752                         anUsup = aCurv->LastParameter();
1753     anAC.Load(aCurv, anUinf, anUsup);
1754     anExtr.Initialize(anAC, anUinf, anUsup);
1755   }
1756
1757   if(aNbPntsM1 == 1)
1758   {
1759     gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
1760
1761     if(aP1.SquareDistance(aP2) < aSQTol)
1762     {
1763       //RLine is degenerated
1764       return Standard_False;
1765     }
1766
1767     gp_Pnt aPMid;
1768     if(theRLine->IsArcOnS1())
1769     {
1770       const Handle(Adaptor2d_HCurve2d)& anAC2d = theRLine->ArcOnS1();
1771       const Standard_Real aParF = anAC2d->FirstParameter(),
1772                           aParL = anAC2d->LastParameter();
1773       gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1774       aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
1775     }
1776     else
1777     {
1778       const Handle(Adaptor2d_HCurve2d)& anAC2d = theRLine->ArcOnS2();
1779       const Standard_Real aParF = anAC2d->FirstParameter(),
1780                           aParL = anAC2d->LastParameter();
1781       gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1782       aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
1783     }
1784
1785     const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
1786     return (aSQDist > aSQTol);
1787   }
1788
1789   for(Standard_Integer i = 2; i <= aNbPntsM1; i++)
1790   {
1791     const gp_Pnt aP(Value(theRLine, i));
1792     const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
1793
1794     if(aSQDist > aSQTol)
1795       return Standard_True;
1796   }
1797
1798   return Standard_False;
1799 }
1800                                       
1801
1802 void ProcessRLine (IntPatch_SequenceOfLine& slin,
1803 //                 const Handle(Adaptor3d_HSurface)& Surf1,
1804 //                 const Handle(Adaptor3d_HSurface)& Surf2,
1805                    const IntSurf_Quadric& Quad1,
1806                    const IntSurf_Quadric& Quad2,
1807                    const Standard_Real _TolArc,
1808                    const Standard_Boolean theIsReqToKeepRLine) {
1809
1810 // On cherche a placer sur les restrictions solutions les points "multiples"
1811 // des autres lignes d intersection
1812 // Pas forcemment le plus efficace : on rique de projeter plusieurs fois
1813 // le meme point sur la meme restriction...
1814
1815   Standard_Real TolArc=100.0*_TolArc;
1816   if(TolArc>0.1) TolArc=0.1;
1817   
1818   Standard_Integer i,j,k;
1819   Standard_Integer Nblin,Nbvtx, Nbpt;
1820
1821   Standard_Boolean OnFirst = Standard_False,project = Standard_False,keeppoint = Standard_False;
1822
1823   Handle(Adaptor2d_HCurve2d) arcref;
1824   Standard_Real paramproj,paramf,paraml;
1825
1826   TColgp_SequenceOfPnt seq_Pnt3d;
1827   TColStd_SequenceOfReal seq_Real;
1828
1829   gp_Pnt ptproj,toproj,valpt;
1830
1831   gp_Pnt2d p2d;
1832   gp_Vec2d d2d;
1833   gp_Vec d1u,d1v,tgrest,tgarc,norm;
1834   IntSurf_Transition TRest,TArc;
1835 #ifndef OCCT_DEBUG
1836   Standard_Real U =0.,V =0.;
1837 #else
1838   Standard_Real U,V;
1839 #endif
1840   IntPatch_Point Ptvtx,newptvtx;
1841
1842   IntPatch_IType typ1,typ2;
1843
1844
1845   Nblin = slin.Length();
1846   for (i=1; i<=Nblin; i++) {
1847     const Handle(IntPatch_Line)& slini = slin(i);
1848     typ1 = slini->ArcType();
1849
1850     Standard_Boolean HasToDeleteRLine = Standard_False;
1851     if (typ1 == IntPatch_Restriction) {
1852       seq_Pnt3d.Clear();
1853       seq_Real.Clear();
1854       
1855       for (j=1; j<=Nblin; j++) {
1856         const  Handle(IntPatch_Line)& slinj = slin(j);
1857         Nbpt = seq_Pnt3d.Length();      // important que ce soit ici
1858         typ2 = slinj->ArcType();
1859         if (typ2 != IntPatch_Restriction) {
1860           //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
1861           //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
1862
1863           //-- DES CHOSES A FAIRE ICI 
1864           if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS1()) { 
1865             OnFirst=Standard_True;
1866             arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS1();
1867           }
1868           else if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS2()) { 
1869             arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS2();
1870             OnFirst=Standard_False;
1871           }
1872           if (Handle(IntPatch_RLine)::DownCast (slini)->HasFirstPoint()) {
1873             paramf = Handle(IntPatch_RLine)::DownCast (slini)->FirstPoint().ParameterOnLine();
1874           }
1875           else {
1876             // cout << "Pas de param debut sur rst solution" << endl;
1877             paramf = RealFirst();
1878           }
1879           if (Handle(IntPatch_RLine)::DownCast (slini)->HasLastPoint()) {
1880             paraml = Handle(IntPatch_RLine)::DownCast (slini)->LastPoint().ParameterOnLine();
1881           }
1882           else {
1883             // cout << "Pas de param debut sur rst solution" << endl;
1884             paraml = RealLast();
1885           }
1886
1887           if (typ2 == IntPatch_Analytic) {
1888             Nbvtx = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1889           }
1890           else {
1891             Nbvtx = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1892           }
1893
1894           
1895           Standard_Boolean EdgeDegenere=Standard_True;
1896           for(Standard_Integer edg=0;EdgeDegenere && edg<=10;edg++) {
1897             arcref->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1898             if (OnFirst) {
1899               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1900             }
1901             else {
1902               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1903             }
1904             if(d1u.Magnitude()>1e-7) {
1905               EdgeDegenere=Standard_False;
1906             }
1907           } 
1908
1909           for (k=1; EdgeDegenere==Standard_False && k<=Nbvtx; k++) {
1910             if (typ2 == IntPatch_Analytic) {
1911               Ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1912             }
1913             else {
1914               Ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1915             }
1916             if ((OnFirst && !Ptvtx.IsOnDomS1()) ||
1917                 (!OnFirst && !Ptvtx.IsOnDomS2())) {
1918               // Si OnFirst && OnDomS1, c est qu on est a une extremite
1919               // ca doit etre traite par Process Segment...
1920               project = Standard_True;
1921               keeppoint = Standard_False;
1922               toproj = Ptvtx.Value();
1923               
1924               Standard_Integer jj;
1925               for (jj = 1; jj <= Nbpt; jj++) {
1926               //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
1927                 if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc) {
1928                   project = Standard_False; 
1929                   break;
1930                 }
1931               }
1932               if (project) { //-- il faut projeter pour trouver le point sur la rline. 
1933                 if (OnFirst) {   
1934                   Ptvtx.ParametersOnS1(U,V); 
1935                 }
1936                 else {
1937                   Ptvtx.ParametersOnS2(U,V);
1938                 }
1939
1940                 project = IntPatch_HInterTool::Project(arcref,gp_Pnt2d(U,V),
1941                                                 paramproj,p2d);
1942                 
1943                 if (project) {
1944                   if (OnFirst) {
1945                     ptproj = Quad1.Value(p2d.X(),p2d.Y());
1946                   }
1947                   else {
1948                     ptproj = Quad2.Value(p2d.X(),p2d.Y());
1949                   }
1950                   if ((toproj.Distance(ptproj) <=100*TolArc) &&
1951                       (paramproj >= paramf) && (paramproj <= paraml)){
1952                     newptvtx = Ptvtx;
1953                     newptvtx.SetParameter(paramproj);
1954                     keeppoint = Standard_True;
1955                     seq_Pnt3d.Append(toproj);
1956                     seq_Real.Append(paramproj);
1957                     
1958                     //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
1959                     for (int ri=1; ri<=Nblin; ri++) {
1960                       const Handle(IntPatch_Line)& slinri = slin(ri);
1961                       if (slinri->ArcType() == IntPatch_Restriction) {
1962                         if(OnFirst && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS1()) { 
1963                           if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS1()) { 
1964                             Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1965                             //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
1966                           }
1967                         }
1968                         else if(OnFirst==Standard_False && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS2()) { 
1969                           if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS2()) { 
1970                             Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1971                             //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
1972                           }
1973                         }
1974                       }
1975                     }
1976                     // -- --------------------------------------------------
1977                   }
1978                 }
1979               }
1980               else {
1981                 keeppoint = Standard_True;
1982                 newptvtx = Ptvtx;
1983                 newptvtx.SetParameter(seq_Real(jj));
1984               }
1985               if (keeppoint) {
1986                 Ptvtx.SetMultiple(Standard_True);
1987                 Ptvtx.SetTolerance(_TolArc);
1988                 newptvtx.SetMultiple(Standard_True);
1989                 
1990                 if (typ2 == IntPatch_Analytic) {
1991                   Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,Ptvtx);
1992                 }
1993                 else {
1994                   Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,Ptvtx);
1995                 }
1996
1997                 if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2()) {
1998                 
1999                   arcref->D1(newptvtx.ParameterOnLine(),p2d,d2d);
2000                 
2001                   if (OnFirst) { // donc OnDomS2
2002                     Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2003                     tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2004
2005                     const Handle(Adaptor2d_HCurve2d)& thearc = Ptvtx.ArcOnS2();
2006                     thearc->D1(Ptvtx.ParameterOnArc2(),p2d,d2d);
2007                     Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2008                     tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
2009                     norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
2010                     if(norm.SquareMagnitude()<1e-16) { 
2011                       TRest.SetValue(Standard_True,IntSurf_Undecided);
2012                       TArc.SetValue(Standard_True,IntSurf_Undecided);       
2013                     }
2014                     else {                                    
2015                       IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2016                     }
2017                     newptvtx.SetArc(Standard_False,thearc,
2018                                     Ptvtx.ParameterOnArc2(),TRest,TArc);
2019
2020                   }
2021                   else { // donc OnDomS1
2022                     Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2023                     tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2024
2025                     const Handle(Adaptor2d_HCurve2d)& thearc = Ptvtx.ArcOnS1();
2026                     thearc->D1(Ptvtx.ParameterOnArc1(),p2d,d2d);
2027                     Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2028                     tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
2029                     norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
2030                     if(norm.SquareMagnitude()<1e-16) { 
2031                       TRest.SetValue(Standard_True,IntSurf_Undecided);
2032                       TArc.SetValue(Standard_True,IntSurf_Undecided);       
2033                     }
2034                     else {              
2035                       IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2036                     }
2037                     newptvtx.SetArc(Standard_True,thearc,
2038                                     Ptvtx.ParameterOnArc1(),TRest,TArc);
2039                   }
2040                 } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
2041
2042                 Handle(IntPatch_RLine)::DownCast (slini)->AddVertex(newptvtx);
2043
2044               } //-- if (keeppoint)
2045             } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
2046           } //-- boucle sur les vertex
2047
2048           if(!theIsReqToKeepRLine)
2049           {
2050             Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
2051
2052             if(!aGL.IsNull())
2053             {
2054               HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL, 
2055                                         Handle(IntPatch_RLine)::DownCast(slini), TolArc);
2056             }
2057
2058             if(HasToDeleteRLine)
2059             {
2060               break;
2061             }
2062           }
2063         } //-- if (typ2 != IntPatch_Restriction)
2064       } //-- for (j=1; j<=Nblin; j++) 
2065     } //-- if (typ1 == IntPatch_Restriction)
2066
2067     if(HasToDeleteRLine)
2068     {
2069       slin.Remove(i);
2070       i--;
2071       Nblin = slin.Length();
2072       continue;
2073     }
2074   } //-- for (i=1; i<=Nblin; i++)
2075 }