7ea9d588516eaa592ca787e324d60de24471bf34
[occt.git] / src / IntPatch / IntPatch_ALineToWLine.cxx
1 // Created on: 1993-11-26
2 // Created by: Modelistation
3 // Copyright (c) 1993-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
9 // under the terms of the GNU Lesser General Public 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 #include <IntPatch_ALineToWLine.ixx>
18
19 #include <IntSurf_LineOn2S.hxx>
20 #include <IntSurf_PntOn2S.hxx>
21 #include <IntSurf_TypeTrans.hxx>
22 #include <IntSurf_Situation.hxx>
23
24 #include <TColStd_Array1OfReal.hxx>
25 #include <TColStd_Array1OfInteger.hxx>
26
27 #include <Precision.hxx>
28
29 #include <gp_Pnt.hxx>
30 #include <gp_Vec.hxx>
31
32 #include <Adaptor2d_HCurve2d.hxx> 
33 #include <GeomAbs_SurfaceType.hxx>
34 #include <gp_Pnt2d.hxx>
35 #include <gp_Vec2d.hxx>
36 #include <IntAna2d_AnaIntersection.hxx>
37 #include <gp_Lin2d.hxx>
38 #include <IntAna2d_IntPoint.hxx>
39 #include <gp_Cone.hxx>
40
41
42 static 
43   gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline, 
44                   const Standard_Real U, 
45                   Standard_Real& DU,
46                   const Standard_Real CurvDef, 
47                   const Standard_Real AngDef);
48
49 static 
50   Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,
51                              const Handle_Adaptor2d_HCurve2d& C2);
52
53 static 
54   void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
55                           const IntSurf_Quadric aQuad2,
56                           Standard_Real& u1,
57                           Standard_Real& u2,
58                           const Standard_Real anu1,
59                           const Standard_Real anu2);
60
61 static
62   void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
63                               const IntSurf_Quadric aQuad1,
64                               const IntSurf_Quadric aQuad2,
65                               const Standard_Real ref_u1,
66                               const Standard_Real ref_u2,
67                               Standard_Real& new_u1,
68                               Standard_Real& new_u2);
69
70 //
71 static
72   void RefineParameters(const Handle(IntPatch_ALine)& aALine,
73                       const Standard_Real aTb,
74                       const Standard_Real aTe,
75                       const Standard_Real aTx,
76                       const Standard_Integer iDir,
77                       const IntSurf_Quadric& aQuadric,
78                       const Standard_Real aTol3D,
79                       Standard_Real& aUx,
80                       Standard_Real& aVx);
81 static
82   Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
83                                      const Standard_Real aTx,
84                                      const Standard_Integer iDir,
85                                      const Standard_Real aTol3D,
86                                      Standard_Real& aT1);
87 static
88   Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
89                           const Standard_Real aVx,
90                           const Standard_Real aTol3D);
91 //
92
93 //--  Je ne sais pas faire mieux et ca m'ennerve.  lbr. 
94 //=======================================================================
95 //function : IntPatch_ALineToWLine
96 //purpose  : 
97 //=======================================================================
98   IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
99                                                const IntSurf_Quadric& Quad2) 
100
101   quad1(Quad1),
102   quad2(Quad2),
103   deflectionmax(0.01),
104   nbpointsmax(200),
105   type(0),
106   myTolParam(1.e-12),
107   myTolOpenDomain(1.e-9),
108   myTolTransition(1.e-8)
109
110   myTol3D=Precision::Confusion();
111 }
112 //=======================================================================
113 //function : IntPatch_ALineToWLine
114 //purpose  : 
115 //=======================================================================
116   IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
117                                                const IntSurf_Quadric& Quad2,
118                                                const Standard_Real    Deflection,
119                                                const Standard_Real    ,
120                                                const Standard_Integer NbMaxPoints) 
121 :
122   quad1(Quad1),
123   quad2(Quad2),
124   deflectionmax(Deflection),
125   nbpointsmax(NbMaxPoints),
126   myTolParam(1.e-12),
127   myTolOpenDomain(1.e-9),
128   myTolTransition(1.e-8)
129
130   myTol3D=Precision::Confusion();
131   type = 0;
132 }
133 //=======================================================================
134 //function : SetTol3D
135 //purpose  : 
136 //=======================================================================
137   void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
138 {
139   myTol3D = aTol;
140 }
141 //=======================================================================
142 //function : Tol3D
143 //purpose  : 
144 //=======================================================================
145   Standard_Real IntPatch_ALineToWLine::Tol3D()const
146 {
147   return myTol3D;
148 }
149 //=======================================================================
150 //function : SetTolTransition
151 //purpose  : 
152 //=======================================================================
153   void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
154 {
155   myTolTransition = aTol;
156 }
157 //=======================================================================
158 //function : TolTransition
159 //purpose  : 
160 //=======================================================================
161   Standard_Real IntPatch_ALineToWLine::TolTransition()const
162 {
163   return myTolTransition;
164 }
165 //=======================================================================
166 //function : SetTolParam
167 //purpose  : 
168 //=======================================================================
169   void IntPatch_ALineToWLine::SetTolParam(const Standard_Real aTolParam)
170 {
171   myTolParam = aTolParam;
172 }
173 //=======================================================================
174 //function : TolParam
175 //purpose  : 
176 //=======================================================================
177   Standard_Real IntPatch_ALineToWLine::TolParam()const
178 {
179   return myTolParam;
180 }
181 //=======================================================================
182 //function : SetTolOpenDomain
183 //purpose  : 
184 //=======================================================================
185   void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
186 {
187   myTolOpenDomain = aTol;
188 }
189 //=======================================================================
190 //function : TolOpenDomain
191 //purpose  : 
192 //=======================================================================
193   Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
194 {
195   return myTolOpenDomain;
196 }
197 //=======================================================================
198 //function : SetConstantParameter
199 //purpose  : 
200 //=======================================================================
201   void IntPatch_ALineToWLine::SetConstantParameter() const 
202
203 }
204 //=======================================================================
205 //function : SetUniformAbscissa
206 //purpose  : 
207 //=======================================================================
208   void IntPatch_ALineToWLine::SetUniformAbscissa() const 
209
210 }
211 //=======================================================================
212 //function : SetUniformDeflection
213 //purpose  : 
214 //=======================================================================
215   void IntPatch_ALineToWLine::SetUniformDeflection() const 
216
217 }
218 //=======================================================================
219 //function : MakeWLine
220 //purpose  : 
221 //=======================================================================
222   Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline) const 
223
224   Standard_Boolean included;
225   Standard_Real f = aline->FirstParameter(included); 
226   if(!included) {
227     f+=myTolOpenDomain;
228   }
229   Standard_Real l = aline->LastParameter(included); 
230   if(!included) { 
231     l-=myTolOpenDomain;
232   }
233   return(MakeWLine(aline,f,l));
234 }
235
236 //=======================================================================
237 //function : MakeWLine
238 //purpose  : 
239 //=======================================================================
240   Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline,
241                                                     const Standard_Real _firstparam,
242                                                     const Standard_Real _lastparam) const 
243 {
244   //
245   Standard_Real dl, dumin, dumax, U, pv, pu1, pv1, pu2, pv2; 
246   Standard_Real firstparam, lastparam;
247   Standard_Integer v, nbvtx;
248   Standard_Boolean TriOk;
249   //
250   firstparam = _firstparam;
251   lastparam  = _lastparam;
252   // Pas Bon ... 
253   // nbpointsmax It is the field. ( =200. by default)
254   dl = (lastparam - firstparam)/(Standard_Real)(nbpointsmax-1);
255   dumin = 0.1*dl;
256   dumax = 10 * dl;
257   //
258   nbvtx = aline->NbVertex();
259   //
260   TColStd_Array1OfReal paramvertex(1,Max(nbvtx,1)), newparamvertex(1,Max(nbvtx,1));
261   //
262   for(v = 1; v<=nbvtx; v++) { 
263     const IntPatch_Point& aVtx = aline->Vertex(v);
264     pv=aVtx.ParameterOnLine();
265     paramvertex(v)=pv;
266     newparamvertex(v)=-1.;
267   }
268   //
269   //-- Tri et Confusion des vertex proches 
270   do { 
271     TriOk = Standard_True;
272     for(v=2; v<=nbvtx;v++) { 
273       if(paramvertex(v) < paramvertex(v-1)) { 
274         pv=paramvertex(v);
275         paramvertex(v-1)=paramvertex(v);
276         paramvertex(v)=pv;
277         TriOk = Standard_False;
278       }
279     }
280   }
281   while(!TriOk);
282   //
283   for(v=2; v<=nbvtx;v++) { 
284     pv=paramvertex(v);
285     pv1=paramvertex(v-1);
286     if(pv-pv1 < myTolParam) { 
287       paramvertex(v)=pv1;
288     }
289   }
290   //
291   Standard_Integer t, nbpwline;
292   Standard_Real u1,v1,u2,v2, anu1, anv1, anu2, anv2;
293   Standard_Real aL, dl_sur_2;
294   gp_Pnt Pnt3d, aPnt3d1;
295   IntSurf_PntOn2S POn2S;
296   Handle(IntSurf_LineOn2S) LinOn2S;
297   //
298   LinOn2S = new IntSurf_LineOn2S;
299
300   //// Modified by jgv, 17.09.09 for OCC21255 ////
301   Standard_Real refpar = RealLast(), ref_u1 = 0., ref_u2 = 0.;
302   if (nbvtx)
303     {
304       const IntPatch_Point& FirstVertex = aline->Vertex(1);
305       refpar = FirstVertex.ParameterOnLine();
306       FirstVertex.Parameters(ref_u1, v1, ref_u2, v2);
307     }
308   ////////////////////////////////////////////////
309
310   //-----------------------------------------------------
311   //-- Estimation Grossiere de la longueur de la courbe
312   //-- 
313   aL=0.;
314   dl_sur_2=0.5*dl; 
315   Pnt3d = aline->Value(firstparam); 
316   for(t=0, U=firstparam+dumin; U<lastparam; t++,U+=dl_sur_2) {
317     aPnt3d1 = aline->Value(U);
318     aL+=Pnt3d.Distance(aPnt3d1);
319     Pnt3d=aPnt3d1;
320   }
321   //------------------------------------------------------
322   aL/=t;
323   aL*=2;
324   //------------------------------------------------------
325   //-- Calcul du premier point 
326   //--
327   //------------------------------------------------------
328   //-- On reajuste firstparam et lastparam au cas ou ces 
329   //-- valeurs sont tres proches des parametres de vertex
330   if(nbvtx) { 
331     Standard_Real pvtxmin, pvtxmax;
332     //
333     pvtxmin = aline->Vertex(1).ParameterOnLine();
334     pvtxmax = pvtxmin;
335     //
336     for(v=2; v<=nbvtx; v++) { 
337       pv=aline->Vertex(v).ParameterOnLine();
338       if(pvtxmin>pv){
339         pvtxmin = pv;
340       }
341       if(pvtxmax<pv){
342         pvtxmax =pv;
343       }
344     }
345     if(Abs(pvtxmin-firstparam)<myTolOpenDomain) {
346       firstparam=pvtxmin;
347     }
348     if(Abs(pvtxmax-lastparam)<myTolOpenDomain) {
349       lastparam=pvtxmax;
350     }
351   }
352   //
353   // First Point
354   Pnt3d = aline->Value(firstparam);
355   quad1.Parameters(Pnt3d,u1,v1);
356   //
357   RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad1, 10.*myTol3D, u1,v1);
358   //
359   //
360   quad2.Parameters(Pnt3d,u2,v2);
361   //
362   RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad2, 10.*myTol3D, u2,v2);
363   //
364
365   POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
366   anu1 = u1;
367   anu2 = u2;
368   LinOn2S->Add(POn2S);
369   nbpwline = 1;
370   U = firstparam;
371   //-------------------------------------------------------
372   //-- On detecte le cas : Point de debut == vertex
373   //-- On affecte un parametre bidon qui sera recadre
374   //-- dans l insertion des vertex dans la ligne
375   //--
376   for(v=1;v<=nbvtx;v++) {
377     if(newparamvertex(v)<0.) { 
378       pv=paramvertex(v);
379       if((pv>=U-2.0*myTolOpenDomain) && (pv<=U+2.0*myTolOpenDomain)) { 
380         if(pv-U > myTolParam) {
381           newparamvertex(v) = 1.000001;
382         }
383         else if(U-pv>myTolParam) {
384           newparamvertex(v) = 0.999999;
385         }
386       }
387     }
388   }
389   //
390   Standard_Real DeltaU;
391   //
392   // the loop
393   DeltaU=0.;
394   //// Modified by jgv, 17.09.09 for OCC21255 ////
395   Standard_Boolean Corrected = Standard_False;
396   ////////////////////////////////////////////////
397   while(U<lastparam) { 
398     Standard_Integer NbCalculD1;
399     Standard_Real UPourCalculD1, pvavant, pvapres;
400     gp_Vec VPourCalculD1;
401     gp_Pnt PPourCalculD1;
402     //
403     DeltaU=0.;
404     NbCalculD1=0;
405     UPourCalculD1=U;
406     do { 
407       if(aline->D1(UPourCalculD1,PPourCalculD1,VPourCalculD1)) { 
408         Standard_Real NormV = VPourCalculD1.Magnitude();
409         if(NormV > 1.0e-16) {
410           DeltaU = aL/NormV;
411         }
412       }
413       if(DeltaU < dumin) 
414         DeltaU = dumin;
415       else if (DeltaU > dumax) 
416         DeltaU = dumax;
417       UPourCalculD1+=dumin;
418     }
419     while((++NbCalculD1<10)&&(DeltaU==0.));
420     //
421     //OCC541(apo)->
422     // static  //xft 
423     Standard_Real CurvDef = deflectionmax, AngDef = CurvDef; 
424     if(U+DeltaU < lastparam) {
425       DefineDU(aline,U,DeltaU,CurvDef,AngDef); 
426     }
427     //<-OCC451(apo)
428     //
429     if(DeltaU==0.){ 
430       DeltaU = (dumin+dumax)*0.5;
431     }
432     //--------------------------------------------------------
433     //-- On cherche a placer un minimum de ??? Points entre 
434     //-- 2 vertex 
435     //--------------------------------------------------------
436     pvavant = firstparam;
437     pvapres = lastparam;
438     for(v=1;v<=nbvtx;v++) {
439       pv=paramvertex(v);
440       if(pv-U > myTolParam) { 
441         if(pvapres>pv) { 
442           pvapres = pv;
443         }
444       }
445       else { 
446         if(U-pv > myTolParam) { 
447           if(pvavant<pv) { 
448             pvavant = pv;
449           }
450         }
451       }
452     }
453     pvapres-=pvavant;
454     if(pvapres < (10.*DeltaU)) { 
455       if(pvapres > (10.*dumin)) { 
456         DeltaU = pvapres*0.1;
457       }
458       else { 
459         DeltaU = dumin;
460       }
461     }
462     //xf
463     if (nbpwline==1 && nbvtx) {
464       Standard_Real aUnext;
465       //
466       aUnext=U+DeltaU;
467       pv=paramvertex(1);
468       if (aUnext>pv){
469         DeltaU=0.5*(pv-firstparam);
470       }
471     }
472     //xt
473     //--------------------------------------------------------
474     //-- Calcul des nouveaux parametres sur les vertex
475     //--
476     for(v=1;v<=nbvtx;v++) {
477       if(newparamvertex(v)<0.) { 
478         pv=paramvertex(v);
479         if(pv>=U  && pv<(U+DeltaU) && (U+DeltaU<lastparam) ) {
480           newparamvertex(v) = (Standard_Real)nbpwline + (pv-U)/DeltaU;
481         }
482       }
483     }
484
485     //// Modified by jgv, 17.09.09 for OCC21255 ////
486     if (!Corrected && U >= refpar)
487       {
488         CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
489         Corrected = Standard_True;
490       }
491     ////////////////////////////////////////////////
492     U+=DeltaU;
493     if(U < lastparam) { 
494       nbpwline++;
495       Pnt3d = aline->Value(U);
496       quad1.Parameters(Pnt3d,u1,v1);
497       quad2.Parameters(Pnt3d,u2,v2);
498       RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
499       anu1 = u1;
500       anu2 = u2;
501       POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
502       LinOn2S->Add(POn2S);
503     }
504   }//while(U<lastparam) 
505   
506   U-=DeltaU;
507   for(v=1;v<=nbvtx;v++) {
508     if(newparamvertex(v)<0.) { 
509       pv=paramvertex(v);
510       if(pv <= lastparam+myTolOpenDomain) {
511         if(lastparam-U) { 
512           newparamvertex(v) = (Standard_Real)nbpwline+(pv-U)/(lastparam-U);
513         }
514         else { 
515           newparamvertex(v) = nbpwline+1;
516         }
517       }
518     }
519   }
520   //
521   Pnt3d = aline->Value(lastparam);
522   quad1.Parameters(Pnt3d,u1,v1);
523   //
524   RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad1, 10.*myTol3D, u1,v1);
525   //
526   quad2.Parameters(Pnt3d,u2,v2);
527   //
528   RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad2, 10.*myTol3D, u2,v2);
529   //
530   RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
531   POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
532   LinOn2S->Add(POn2S);
533   nbpwline++;
534
535   //// Modified by jgv, 17.09.09 for OCC21255 ////
536   if (!Corrected && 
537       (lastparam >= refpar || refpar-lastparam < Precision::Confusion()))
538     CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
539   ////////////////////////////////////////////////
540
541   //
542   //-----------------------------------------------------------------
543   //--  Calcul de la transition de la ligne sur les surfaces      ---
544   //-----------------------------------------------------------------
545   IntSurf_TypeTrans trans1,trans2;
546   Standard_Integer indice1;
547   Standard_Real dotcross;
548   gp_Pnt aPP0, aPP1;
549   //
550   trans1=IntSurf_Undecided;
551   trans2=IntSurf_Undecided;
552   //
553   indice1 = nbpwline/3;
554   if(indice1<=2) {
555     indice1 = 2;
556   }
557   //
558   aPP1=LinOn2S->Value(indice1).Value();
559   aPP0=LinOn2S->Value(indice1-1).Value();
560   //
561   gp_Vec tgvalid(aPP0, aPP1);
562   gp_Vec aNQ1=quad1.Normale(aPP0);
563   gp_Vec aNQ2=quad2.Normale(aPP0);
564   //
565   dotcross = tgvalid.DotCross(aNQ2, aNQ1);
566   if (dotcross > myTolTransition) {
567     trans1 = IntSurf_Out;
568     trans2 = IntSurf_In;
569   }
570   else if(dotcross < -myTolTransition) { 
571     trans1 = IntSurf_In;
572     trans2 = IntSurf_Out;
573   } 
574   //-----------------------------------------------------------------
575   //--              C r e a t i o n  d  e   la   W L i n e        ---
576   //-----------------------------------------------------------------
577   Handle(IntPatch_WLine) wline;
578   //
579   if(aline->TransitionOnS1() == IntSurf_Touch)  { 
580     Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
581                                               aline->IsTangent(),
582                                               aline->SituationS1(),
583                                               aline->SituationS2());
584     wline = wlinetemp;
585   }
586   if(aline->TransitionOnS1() == IntSurf_Undecided)  { 
587     Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
588                                               aline->IsTangent());
589     wline = wlinetemp;
590   }
591   else { 
592     Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
593                                               aline->IsTangent(),
594                                               trans1, // aline->TransitionOnS1(),
595                                               trans2);  //aline->TransitionOnS2());
596     wline = wlinetemp; 
597   }
598
599   //-----------------------------------------------------------------
600   //--         I n s e r t i o n   d  e s  v e r t e x            ---
601   //-----------------------------------------------------------------
602   TColStd_Array1OfInteger Redir(1,Max(nbvtx,1));
603   //
604   for(v=1;v<=nbvtx;v++) { 
605     Redir(v) = v;
606   }
607   //
608   TriOk=Standard_True;
609   Standard_Integer tamp;
610   do { 
611     TriOk = Standard_True;
612     for(v=2; v<=nbvtx;v++) { 
613       if(newparamvertex(Redir(v))<newparamvertex(Redir(v-1))) { 
614         tamp = Redir(v-1);
615         Redir(v-1) = Redir(v);
616         Redir(v) = tamp;
617         TriOk = Standard_False;
618       }
619     }
620   }
621   while(!TriOk);
622  
623   //-----------------------------------------------------------------
624   //-- On detecte le cas ou un Vtx de param 1 ou nbpwline OnArc est double
625   //-- Dans ce cas on supprime le vertex qui reference un arc deja reference 
626   //-- par un autre vertex 
627   //nbvtx = aline->NbVertex();
628   Standard_Boolean APointHasBeenRemoved;
629   //
630   do { 
631     Standard_Boolean RemoveVtxo, RemoveVtx;
632     Standard_Integer vo, voo;
633     Standard_Real ponl, ponlo, ponloo, aDist13, aDist23;
634     //
635     APointHasBeenRemoved = Standard_False;
636     RemoveVtxo = Standard_False;
637     RemoveVtx  = Standard_False;
638     //
639     for(v=1; v<=nbvtx   && !APointHasBeenRemoved; v++) { 
640       //
641       if(newparamvertex(v)>=0.) { 
642         const IntPatch_Point& Vtx = aline->Vertex(v);
643         ponl = Vtx.ParameterOnLine();
644         const gp_Pnt& aP=Vtx.Value();
645         //
646         for(vo=1; vo<=nbvtx && !APointHasBeenRemoved; vo++) { 
647           if(v!=vo) { 
648             if(newparamvertex(vo)>=0.) { 
649               const IntPatch_Point& Vtxo = aline->Vertex(vo);
650               ponlo = Vtxo.ParameterOnLine();
651               const gp_Pnt& aPo=Vtxo.Value();
652               //
653               if(ponl-ponlo<myTolParam && ponlo-ponl<myTolParam) { 
654                 //
655                 for(voo=1; voo<=nbvtx && !APointHasBeenRemoved; voo++) { 
656                   if(voo!=v && voo!=vo) {
657                     if(newparamvertex(voo)>=0.) { 
658                       const IntPatch_Point& Vtxoo = aline->Vertex(voo);
659                       ponloo = Vtxoo.ParameterOnLine();
660                       const gp_Pnt& aPoo=Vtxoo.Value();
661                       //
662                       aDist13=aP.Distance(aPoo);
663                       //
664                       if(aDist13<=myTol3D) { 
665                         //-- 2 vertex de meme param  + un confondu geometriquement
666                         if((Vtx.IsOnDomS1() == Vtxoo.IsOnDomS1()) &&
667                            (Vtx.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) { 
668                           
669                           if(Vtx.IsOnDomS1()) { 
670                             if(Vtx.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) { 
671                               if(SameCurve(Vtxoo.ArcOnS1(),Vtx.ArcOnS1())) { //-- param on s1 ?
672                                 RemoveVtx = Standard_True;
673                               }
674                             }
675                           }
676                           if(Vtx.IsOnDomS2()) { 
677                             if(Vtx.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) { 
678                               if(SameCurve(Vtxoo.ArcOnS2(),Vtx.ArcOnS2())) { 
679                                 RemoveVtx = Standard_True;
680                               }
681                             }
682                             else { 
683                               RemoveVtx = Standard_False;
684                             }
685                           }
686                         }
687                         //
688                         if(RemoveVtx==Standard_False) { 
689                           //
690                           aDist23=aPo.Distance(aPoo);
691                           //
692                           if(aDist23<=myTol3D) { 
693                             //-- 2 vertex de meme param  + un confondu geometriquement
694                             if((Vtxo.IsOnDomS1() == Vtxoo.IsOnDomS1())&&
695                                (Vtxo.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) { 
696                               if(Vtxo.IsOnDomS1()) { 
697                                 if(Vtxo.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) { 
698                                   if(SameCurve(Vtxoo.ArcOnS1(),Vtxo.ArcOnS1())) { //-- param on s1 ?
699                                     RemoveVtxo = Standard_True;
700                                   }
701                                 }
702                               }
703                               if(Vtxo.IsOnDomS2()) { 
704                                 if(Vtxo.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) { 
705                                   if(SameCurve(Vtxoo.ArcOnS2(),Vtxo.ArcOnS2())) { 
706                                     RemoveVtxo = Standard_True;
707                                   }
708                                 }
709                                 else { 
710                                   RemoveVtxo = Standard_False;
711                                 }
712                               }
713                             }
714                           }
715                         } //-- 
716                         if(RemoveVtx) { 
717                           newparamvertex(v) = -1.;
718                           APointHasBeenRemoved = Standard_True;
719                         }
720                         else if(RemoveVtxo) { 
721                           newparamvertex(vo) = -1.;
722                           APointHasBeenRemoved = Standard_True;
723                         }
724                       } //-- Pnt = Pntoo 
725                     } //-- voo!=v && voo!=vo
726                   } //-- Fin boucle sur voo 
727                 }
728               }
729             }  
730           }
731         }
732       }
733     }//for(v=1; v<=nbvtx   && !APointHasBeenRemoved; v++) 
734   }
735   while(APointHasBeenRemoved);
736   //
737   Standard_Integer ParamVtxPrecedent, refpointonwline, aIndV;
738   Standard_Real pvtx, approxparamonwline, aDst;
739   Standard_Boolean bIsApex1, bIsApex2;
740   //
741   ParamVtxPrecedent = 0;
742   //
743   for(v=1; v<=nbvtx; v++) { 
744     aIndV=Redir(v);
745     pv=paramvertex(v);// parameter from ALine
746     pvtx = newparamvertex(aIndV);
747     if(pvtx>=0. && (pvtx <= nbpwline+1)) {
748       approxparamonwline=newparamvertex(aIndV);
749       refpointonwline=1;
750       //
751       IntPatch_Point NewPoint = aline->Vertex(aIndV);
752       //
753       Pnt3d = NewPoint.Value();
754       quad1.Parameters(Pnt3d, u1, v1);
755       quad2.Parameters(Pnt3d, u2, v2);
756       //-------------------------------------------------------
757       //-- On recadre les parametres des vertex dans la bonne -
758       //-- periode en recadrant avec le point le plus proche  -
759       //-------------------------------------------------------
760       if(approxparamonwline > nbpwline) { 
761         refpointonwline = nbpwline-1;
762       }
763       else if(approxparamonwline < 1) { 
764         refpointonwline = 1;
765       }
766       else { 
767         refpointonwline = (Standard_Integer)approxparamonwline;
768       }
769       //
770       //
771       const IntSurf_PntOn2S& aP2Sx=LinOn2S->Value(refpointonwline);
772       aP2Sx.ParametersOnS1(anu1, anv1);
773       aP2Sx.ParametersOnS2(anu2, anv2);
774       //
775       bIsApex1=IsApex(quad1, v1, myTol3D);
776       bIsApex2=IsApex(quad2, v2, myTol3D);
777       //
778       //if (refpointonwline==1 || refpointonwline==nbpwline) {
779       if (bIsApex1 || bIsApex2) {
780         if (fabs(pv-firstparam)<myTolParam || fabs(pv-lastparam)<myTolParam) {
781           // aline starts(ends) on vertex 
782           const gp_Pnt& aP1x=aP2Sx.Value();
783           //
784           aDst=aP1x.Distance(Pnt3d);
785           if (aDst<10.*myTol3D) {
786             u1=anu1;
787             v1=anv1;
788             u2=anu2;
789             v2=anv2;
790           }
791         }
792         //
793         else {
794           // aline goes through vertex 
795           if (bIsApex1) {
796             u1=0.;
797           }
798           if (bIsApex2) {
799             u2=0.;
800           }
801         }
802       }
803       //
804       //
805       if(v==1) { 
806         ParamVtxPrecedent=refpointonwline;
807         RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
808         NewPoint.SetParameter(refpointonwline);
809         //
810         NewPoint.SetParameters(u1,v1,u2,v2);
811         wline->AddVertex(NewPoint);
812       }
813       //
814       else { 
815         if(ParamVtxPrecedent==refpointonwline) { 
816           //-- 2 vertex renseignent le meme point de la LineOn2S
817           //-- On insere un nv point  =  vtx
818           //-- On decale tous les vtx apres de 1 
819           RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
820           POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
821           LinOn2S->InsertBefore(refpointonwline+1, POn2S);
822           nbpwline++;
823           NewPoint.SetParameter(refpointonwline+1);
824           NewPoint.SetParameters(u1,v1,u2,v2);
825           wline->AddVertex(NewPoint);
826           ParamVtxPrecedent = refpointonwline+1;
827           //
828           Standard_Integer vv=v+1;
829           for(; vv<=nbvtx; vv++) { 
830             if(newparamvertex(Redir(vv))!=-1.) { 
831               newparamvertex(Redir(vv))=newparamvertex(Redir(vv))+1.;
832             }
833           }
834         }
835         //
836         else { 
837           RecadreMemePeriode(quad1, quad2, u1,u2, anu1, anu2);
838           NewPoint.SetParameter(refpointonwline);
839           //
840           NewPoint.SetParameters(u1, v1, u2, v2);
841           wline->AddVertex(NewPoint);
842           ParamVtxPrecedent = refpointonwline;
843         }
844       }
845     }
846   }
847   //
848   pu1=0.;
849   pv1=0.;
850   pu2=0.;
851   pv2=0.;
852   //
853   switch(quad1.TypeQuadric()) { 
854   case GeomAbs_Cylinder:
855   case GeomAbs_Cone:
856   case GeomAbs_Sphere:
857     pu1=M_PI+M_PI;
858     break;
859   case GeomAbs_Torus:
860     pu1=pv1=M_PI+M_PI;
861     break;
862   default:
863     break;
864   }
865   switch(quad2.TypeQuadric()) { 
866   case GeomAbs_Cylinder:
867   case GeomAbs_Cone:
868   case GeomAbs_Sphere:
869     pu2=M_PI+M_PI;
870     break;
871   case GeomAbs_Torus:
872     pu2=pv2=M_PI+M_PI;
873     break;
874   default:
875     break;
876   }
877   wline->SetPeriod(pu1,pv1,pu2,pv2);
878   
879   wline->ComputeVertexParameters(myTol3D);
880   return(wline);
881 }
882 //=======================================================================
883 //function : DefineDU
884 //purpose  : 
885 //=======================================================================
886 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline, 
887                 const Standard_Real U, 
888                 Standard_Real& DU,
889                 const Standard_Real CurvDef, 
890                 const Standard_Real AngDef)
891 {
892   gp_Pnt P1 = aline->Value(U), P2, P3;
893   gp_Vec V13, V12, V23;
894   Standard_Real dU = DU/2.0, curvDef, angDef, m1, m2, m3;
895   for(;;) { //According to class TangentialDeflection from GCPnts
896     P2=aline->Value(U+dU);  P3=aline->Value(U+DU);
897     V13 = P3.XYZ().Subtracted(P1.XYZ());  m1 = V13.Magnitude();
898     V12 = P2.XYZ().Subtracted(P1.XYZ());  m2 = V12.Magnitude();
899     V23 = P3.XYZ().Subtracted(P2.XYZ());  m3 = V23.Magnitude();
900     if(m1 < CurvDef || m2 < CurvDef || m3 < CurvDef) break;
901     curvDef = Abs(V13.Angle(V12));
902     angDef = Abs(V13.Angle(V23));
903     if(curvDef < CurvDef && angDef < AngDef) break;
904     DU = dU;  dU /= 2.0;  
905   }
906   return P3;
907 }
908 //=======================================================================
909 //function : SameCurve
910 //purpose  : 
911 //=======================================================================
912 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,const Handle_Adaptor2d_HCurve2d& C2) 
913
914   Standard_Real C1f = C1->FirstParameter();
915   Standard_Real C2f = C2->FirstParameter();
916   if(C1f!=C2f) return(Standard_False);
917   Standard_Real C1l = C1->LastParameter();
918   Standard_Real C2l = C2->LastParameter();
919   if(C1l!=C2l) return(Standard_False);
920   Standard_Real u=0.3*C1f+0.7*C1l;
921   gp_Pnt2d P1 = C1->Value(u);
922   gp_Pnt2d P2 = C2->Value(u);
923   if(P1.X()!=P2.X()) return(Standard_False);
924   if(P1.Y()!=P2.Y()) return(Standard_False);
925   return(Standard_True);
926 }
927 //=======================================================================
928 //function : RecadreMemePeriode
929 //purpose  : 
930 //=======================================================================
931 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
932                         const IntSurf_Quadric aQuad2,
933                         Standard_Real& u1,
934                         Standard_Real& u2,
935                         const Standard_Real anu1,
936                         const Standard_Real anu2) 
937
938   Standard_Boolean bBothCylinders;
939   GeomAbs_SurfaceType aType1, aType2;
940   //
941   aType1=aQuad1.TypeQuadric();
942   aType2=aQuad2.TypeQuadric();
943   bBothCylinders=(aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder);
944   //
945   while(anu1-u1 > 5.0) {
946     u1+=M_PI+M_PI;
947   }
948   while(u1-anu1 > 5.0) { 
949     //
950     /*
951     if (!bBothCylinders) {//cfe900/H6
952       // this check on Cylinder/Cylinder intersection is probably 
953       // because of pbs with ALine on it.
954       // For other Quadrics there was no pbs found during 
955       // grid tests.
956       // (it is necessary to see ...IntCyCy(...) for details).
957       //
958       // In any case the pb does not deal with apex problem. 
959       //
960       if (u1-M_PI-M_PI<0.) {
961         break;
962       }
963     }
964     */
965     //
966     u1-=M_PI+M_PI;
967   }
968   while(anu2-u2 > 5.0) { 
969     u2+=M_PI+M_PI;
970   }
971   while(u2-anu2 > 5.0) {
972     //
973     /*
974     if (!bBothCylinders) {//cfe900/H6
975       if (u2-M_PI-M_PI<0.) {
976         break;
977       }
978     }
979     */
980     //
981     u2-=M_PI+M_PI;
982   }
983 }
984
985 //=======================================================================
986 //function : CorrectFirstPartOfLine
987 //purpose  : 
988 //=======================================================================
989 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
990                             const IntSurf_Quadric aQuad1,
991                             const IntSurf_Quadric aQuad2,
992                             const Standard_Real ref_u1,
993                             const Standard_Real ref_u2,
994                             Standard_Real& new_u1,
995                             Standard_Real& new_u2)
996 {
997   Standard_Integer nbp = LinOn2S->NbPoints();
998   Standard_Real u1, v1, u2, v2, OffsetOnS1, OffsetOnS2;
999
1000   IntSurf_PntOn2S aPoint = LinOn2S->Value(nbp);
1001   aPoint.Parameters(u1, v1, u2, v2);
1002
1003   new_u1 = u1;
1004   new_u2 = u2;
1005   RecadreMemePeriode(aQuad1, aQuad2, new_u1, new_u2, ref_u1, ref_u2);
1006   OffsetOnS1 = new_u1 - u1;
1007   OffsetOnS2 = new_u2 - u2;
1008   if (Abs(OffsetOnS1) > 1. || Abs(OffsetOnS2) > 1.) //recadre on n*2*PI is done
1009     {
1010       Standard_Integer i;
1011       for (i = 1; i <= nbp; i++)
1012         {
1013           aPoint = LinOn2S->Value(i);
1014           aPoint.Parameters(u1, v1, u2, v2);
1015           LinOn2S->SetUV( i, Standard_True,  u1 + OffsetOnS1, v1 );
1016           LinOn2S->SetUV( i, Standard_False, u2 + OffsetOnS2, v2 );
1017         }
1018     }
1019 }
1020
1021 //
1022 //=======================================================================
1023 //function : IsApex
1024 //purpose  : 
1025 //=======================================================================
1026 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
1027                         const Standard_Real aVx,
1028                         const Standard_Real aTol3D)
1029                         
1030 {
1031   Standard_Boolean bFlag;
1032   Standard_Real aHalfPi, aEpsilon;
1033   GeomAbs_SurfaceType aType;
1034   //
1035   bFlag=Standard_False;
1036   //
1037   aType=aQuadric.TypeQuadric();
1038   if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1039     return bFlag;
1040   }
1041   //
1042   aEpsilon=Epsilon(10.);//1.77e-15
1043   //
1044   // apex on the Sphere
1045   if(aType==GeomAbs_Sphere) {
1046     aHalfPi=0.5*M_PI;
1047     if (fabs(aVx-aHalfPi)<aEpsilon) {
1048       bFlag=!bFlag;
1049     }
1050     else if (fabs(aVx+aHalfPi)<aEpsilon){
1051       bFlag=!bFlag;
1052     }
1053   }
1054   //
1055   // apex on the Cone
1056   else if(aType==GeomAbs_Cone) {
1057     Standard_Real aDst;
1058     gp_Pnt aPap, aPx;
1059     gp_Cone aCone;
1060     //
1061     aCone=aQuadric.Cone();
1062     aPap=aCone.Apex();
1063     aPx=aQuadric.Value(0.,aVx);
1064     //
1065     aDst=aPx.Distance(aPap);
1066     if(aDst<aTol3D) {
1067       bFlag=!bFlag;
1068     }
1069   }
1070   return bFlag;
1071 }   
1072 //=======================================================================
1073 //function : RefineParameters
1074 //purpose  : 
1075 //=======================================================================
1076 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
1077                       const Standard_Real aTb,
1078                       const Standard_Real aTe,
1079                       const Standard_Real aTx,
1080                       const Standard_Integer iDir,
1081                       const IntSurf_Quadric& aQuadric,
1082                       const Standard_Real aTol3D,
1083                       Standard_Real& aUx,
1084                       Standard_Real& aVx)
1085 {
1086   GeomAbs_SurfaceType aType;
1087   //
1088   aType=aQuadric.TypeQuadric();
1089   if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1090     return;
1091   }
1092   //
1093   Standard_Boolean bIsDone, bIsEmpty, bParallel, bFound;
1094   Standard_Integer aNbPoints = 0;
1095   Standard_Real aHalfPi, aEpsilon, aLimV, dT, aT1, aT2 = 0., aEpsT;
1096   Standard_Real aU1, aV1, aU2, aV2;
1097   gp_Pnt aP1, aP2, aPx;
1098   gp_Pnt2d  aP2D1, aP2D2, aPLim(0., 0.);
1099   gp_Vec2d aVLim(1., 0.);
1100   gp_Lin2d aLLim;
1101   IntAna2d_AnaIntersection aAI;
1102   //
1103   aEpsilon=Epsilon(10.);//1.77e-15
1104   aEpsT=0.0001;
1105   aLLim.SetDirection(aVLim);
1106   //
1107   // apex on the Cone
1108   if(aType==GeomAbs_Cone) {
1109     Standard_Real aDst;
1110     gp_Pnt aPap;
1111     gp_Cone aCone;
1112     //
1113     aCone=aQuadric.Cone();
1114     aPap=aCone.Apex();
1115     //aPx=aQuadric.Value(0.,aVx);
1116     aPx=aALine->Value(aTx);
1117     //
1118     aDst=aPx.Distance(aPap);
1119     if(aDst>aTol3D) {// nothing to do
1120       return;
1121     }
1122     //
1123     aPLim.SetY(aVx);
1124     aLLim.SetLocation(aPLim);
1125     //
1126   }
1127   //
1128   // apex on the Sphere
1129   if(aType==GeomAbs_Sphere) {
1130     aHalfPi=0.5*M_PI;
1131     //
1132     if (fabs(aVx-aHalfPi)<aEpsilon) {
1133       aLimV=aHalfPi;
1134     }
1135     else if (fabs(aVx+aHalfPi)<aEpsilon){
1136       aLimV=-aHalfPi;
1137     }
1138     else {
1139       //Check: aUx must be 0 or 2*pi
1140       if(fabs(aUx) < aEpsilon || fabs(aUx - 2.*M_PI) < aEpsilon) {
1141         //aUx = 0 or 2*pi, but may be it must be 2*pi or 0?
1142         bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1143         if(!bFound) {
1144           dT=aEpsT*(aTe-aTb);
1145           if (iDir<0) {
1146             dT=-dT;
1147           }
1148           aT1=aTx+dT;
1149         }
1150
1151         aP1=aALine->Value(aT1);
1152         aQuadric.Parameters(aP1, aU1, aV1);
1153
1154         if(fabs(aU1) > fabs(aU1 - 2.*M_PI)) {
1155           aUx = 2.*M_PI;
1156         }
1157         else {
1158           aUx = 0.;
1159         }
1160       }
1161         
1162       return;
1163     }
1164     //
1165     aPLim.SetY(aLimV);
1166     aLLim.SetLocation(aPLim);
1167   }
1168   //
1169   // aT1, aT2
1170   //
1171   // Try to find aT1, aT2 taking into acc 3D Tolerance
1172   bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1173   if (bFound) {
1174     bFound=FindNearParameter(aALine, aT1, iDir, aTol3D, aT2);
1175   }
1176   if (!bFound) {
1177     // Assign aT1, aT2 by some values
1178     dT=aEpsT*(aTe-aTb);
1179     if (iDir<0) {
1180       dT=-dT;
1181     }
1182     aT1=aTx+dT;
1183     aT2=aT1+dT;
1184   }
1185   //
1186   aP1=aALine->Value(aT1);
1187   aQuadric.Parameters(aP1, aU1, aV1);
1188   aP2D1.SetCoord(aU1, aV1);
1189   //
1190   aP2=aALine->Value(aT2);
1191   aQuadric.Parameters(aP2, aU2, aV2);
1192   aP2D2.SetCoord(aU2, aV2);
1193   //
1194   gp_Vec2d aV12(aP2D1, aP2D2);
1195
1196   if(aV12.SquareMagnitude() <= aEpsilon) {
1197     return;
1198   }
1199   gp_Lin2d aL12(aP2D1, aV12);
1200   //
1201   aAI.Perform(aLLim, aL12);
1202   bIsDone=aAI.IsDone();
1203   if (!bIsDone) {
1204     return;
1205   }
1206   bIsEmpty=aAI.IsEmpty();
1207   if (bIsEmpty) {
1208     return;
1209   }
1210   aNbPoints=aAI.NbPoints();
1211   if (!aNbPoints) {
1212     return;
1213   }
1214   bParallel=aAI.ParallelElements();
1215   if (bParallel) {
1216     return;
1217   }
1218   const IntAna2d_IntPoint& aIAPnt=aAI.Point(1);
1219   const gp_Pnt2d& aP2D=aIAPnt.Value();
1220   aUx=aP2D.X();
1221 }
1222 //=======================================================================
1223 //function : FindNearParameter
1224 //purpose  : 
1225 //=======================================================================
1226 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
1227                                    const Standard_Real aTx,
1228                                    const Standard_Integer iDir,
1229                                    const Standard_Real aTol3D,
1230                                    Standard_Real& aT1)
1231 {
1232   Standard_Boolean bFound;
1233   Standard_Real aX, aY, aZ;
1234   gp_Pnt aPx, aP1;
1235   gp_Vec aVx;
1236   //
1237   aT1=0.;
1238   //
1239   bFound=aALine->D1(aTx, aPx, aVx);
1240   if(!bFound){
1241     return bFound;
1242   }
1243   gp_Dir aDx(aVx);
1244   if (iDir<0) {
1245     aDx.Reverse();
1246   }
1247   aX=aPx.X()+aDx.X()*aTol3D;
1248   aY=aPx.Y()+aDx.Y()*aTol3D;
1249   aZ=aPx.Z()+aDx.Z()*aTol3D;
1250   aP1.SetCoord(aX, aY, aZ);
1251   //
1252   bFound=aALine->FindParameter(aP1, aT1);
1253   //
1254   return bFound;
1255 }
1256