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