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