0022771: An extra vertex produced in result of Boolean section for the cases of close...
[occt.git] / src / IntTools / IntTools_LineConstructor.cxx
1 // File:      IntTools_LineConstructor.cxx
2 // Created:   Tue Feb  7 10:12:45 1995
3 // Author:    Jacques GOUSSARD
4 // Copyright: OPEN CASCADE 1995
5
6 #include <IntTools_LineConstructor.ixx>
7
8 #include <GeomInt_LineTool.hxx>
9 #include <GeomInt_SequenceOfParameterAndOrientation.hxx>
10 #include <GeomInt_ParameterAndOrientation.hxx>
11
12 #include <IntPatch_Point.hxx>
13 #include <IntPatch_GLine.hxx>
14 #include <IntPatch_WLine.hxx>
15 #include <IntPatch_ALine.hxx>
16 #include <IntSurf_Transition.hxx>
17 #include <TopAbs_Orientation.hxx>
18
19
20 #include <Precision.hxx>
21
22 #include <gp_Pnt2d.hxx>
23
24 #include <Adaptor2d_HCurve2d.hxx>
25
26 #include <GeomAdaptor_HSurface.hxx>
27 #include <Standard_ConstructionError.hxx>
28 #include <IntSurf_Quadric.hxx>
29 #include <IntSurf_PntOn2S.hxx>
30 #include <ElCLib.hxx>
31 #include <GeomAbs_SurfaceType.hxx>
32 //
33 #include <TColStd_IndexedMapOfInteger.hxx>
34
35 static
36   void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
37                   const gp_Pnt& Ptref,
38                   Standard_Real& U1,
39                   Standard_Real& V1);
40 static
41   void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
42                   const Handle(GeomAdaptor_HSurface)& myHS2,
43                   const gp_Pnt& Ptref,
44                   Standard_Real& U1,
45                   Standard_Real& V1,
46                   Standard_Real& U2,
47                   Standard_Real& V2);
48
49 static 
50   void GLinePoint(const IntPatch_IType typl,
51                   const Handle(IntPatch_GLine)& GLine,
52                   const Standard_Real aT,
53                   gp_Pnt& aP);
54 static
55   void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
56                const Handle(GeomAdaptor_HSurface)& myHS2,
57                Standard_Real& u1,
58                Standard_Real& v1,
59                Standard_Real& u2,
60                Standard_Real& v2);
61
62 //=======================================================================
63 //function : Perform
64 //purpose  : 
65 //=======================================================================
66 void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
67 {
68   Standard_Integer i,nbvtx;
69   Standard_Real firstp,lastp;
70   const Standard_Real Tol = Precision::PConfusion() * 35.0;
71   
72   const IntPatch_IType typl = L->ArcType();
73   if(typl == IntPatch_Analytic)  {
74     Standard_Real u1,v1,u2,v2;
75     Handle(IntPatch_ALine)& ALine =  *((Handle(IntPatch_ALine) *)&L);
76     seqp.Clear();
77     nbvtx = GeomInt_LineTool::NbVertex(L);
78     for(i=1;i<nbvtx;i++)   {
79       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
80       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
81       if(firstp!=lastp)      {
82         const Standard_Real pmid = (firstp+lastp)*0.5;
83         const gp_Pnt Pmid = ALine->Value(pmid);
84         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
85         Recadre(myHS1,myHS2,u1,v1,u2,v2);
86         const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
87         if(in1 !=  TopAbs_OUT) {
88           const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
89           if(in2 != TopAbs_OUT) { 
90             seqp.Append(firstp);
91             seqp.Append(lastp);
92           }
93         }
94       }
95     }
96     done = Standard_True;
97     return;
98   } // if(typl == IntPatch_Analytic)  {
99   else if(typl == IntPatch_Walking)  {
100     Standard_Real u1,v1,u2,v2;
101     Handle(IntPatch_WLine)& WLine =  *((Handle(IntPatch_WLine) *)&L);
102     seqp.Clear();
103     nbvtx = GeomInt_LineTool::NbVertex(L);
104     for(i=1;i<nbvtx;i++)    { 
105       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
106       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
107       if(firstp!=lastp) { 
108         if(lastp != firstp+1)  {
109           const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
110           const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
111           Pmid.Parameters(u1,v1,u2,v2);
112           Recadre(myHS1,myHS2,u1,v1,u2,v2);
113           const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
114           if(in1 !=  TopAbs_OUT) {   
115             const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
116             if(in2 != TopAbs_OUT) {   
117               seqp.Append(firstp);
118               seqp.Append(lastp);
119             }
120           }
121         }
122         else {
123           const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
124           Pfirst.Parameters(u1,v1,u2,v2);
125           Recadre(myHS1,myHS2,u1,v1,u2,v2);
126           TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
127           if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
128             TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
129             if(in2 != TopAbs_OUT) { //-- !=ON  
130               const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
131               Plast.Parameters(u1,v1,u2,v2);
132               Recadre(myHS1,myHS2,u1,v1,u2,v2);
133               in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
134               if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
135                 in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
136                 if(in2 != TopAbs_OUT) {
137                   seqp.Append(firstp);
138                   seqp.Append(lastp);
139                 }
140               }
141             }
142           }
143         }
144       }
145     }
146     //
147     // The One resulting curve consists of 7 segments that are 
148     // connected between each other.
149     // The aim of the block is to reject these segments and have
150     // one segment instead of 7. 
151     //     The other reason to do that is value of TolReached3D=49.
152     //     Why -? It is not known yet. 
153     //                                             PKV 22.Apr.2002
154     //
155     Standard_Integer aNbParts;
156     //
157     aNbParts = seqp.Length()/2;
158     if (aNbParts > 1) {  
159       Standard_Boolean bCond;
160       GeomAbs_SurfaceType aST1, aST2;
161       aST1 = myHS1->Surface().GetType();
162       aST2 = myHS2->Surface().GetType();
163       //
164       bCond=Standard_False;
165       if (aST1==GeomAbs_Plane) {
166         if (aST2==GeomAbs_SurfaceOfExtrusion || 
167             aST2==GeomAbs_SurfaceOfRevolution) {//+zft
168           bCond=!bCond;
169         }
170       }
171       else if (aST2==GeomAbs_Plane) {
172         if (aST1==GeomAbs_SurfaceOfExtrusion || 
173             aST1==GeomAbs_SurfaceOfRevolution) {//+zft
174           bCond=!bCond;
175         }
176       }
177       //
178       if (bCond) {
179         Standard_Integer aNb, anIndex, aNbTmp, jx;
180         TColStd_IndexedMapOfInteger aMap;
181         TColStd_SequenceOfReal aSeqTmp;
182         //
183         aNb=seqp.Length();
184         for(i=1; i<=aNb; ++i) {
185           lastp =seqp(i);
186           anIndex=(Standard_Integer)lastp;
187           if (!aMap.Contains(anIndex)){
188             aMap.Add(anIndex);
189             aSeqTmp.Append(lastp);
190           }
191           else {
192             aNbTmp=aSeqTmp.Length();
193             aSeqTmp.Remove(aNbTmp);
194           }
195         }
196         //
197         seqp.Clear();
198         //
199         aNb=aSeqTmp.Length()/2;
200         for(i=1; i<=aNb;++i) {
201           jx=2*i;
202           firstp=aSeqTmp(jx-1);
203           lastp =aSeqTmp(jx);
204           seqp.Append(firstp);
205           seqp.Append(lastp);
206         }
207       }//if (bCond) {
208     }
209     done = Standard_True;
210     return;
211   }// else if(typl == IntPatch_Walking)  {
212   //
213   else if (typl != IntPatch_Restriction)  {
214     Standard_Boolean intrvtested;
215     Standard_Real u1,v1,u2,v2;
216     //
217     seqp.Clear();
218     //
219     Handle(IntPatch_GLine)& GLine =  *((Handle(IntPatch_GLine) *)&L);
220     // reject micro circles, ellipses
221     switch (typl) {
222       case IntPatch_Circle: {
223         Standard_Real aR;
224         gp_Circ aCirc;
225         //
226         aCirc=GLine->Circle();
227         aR=aCirc.Radius();
228         if (aR<Tol) {
229           done = Standard_True;
230           return;
231         }
232         break;
233       }
234       case IntPatch_Ellipse: {
235         Standard_Real aR;
236         gp_Elips aEllipse;
237         //
238         aEllipse=GLine->Ellipse();
239         aR=aEllipse.MajorRadius();
240         if (aR<Tol) {
241           done = Standard_True;
242           return;
243         }
244         break;
245       }
246       default:
247         break;
248     }
249     //modified by NIZNHY-PKV Wed Nov 02 11:50:23 2011t
250     //
251     nbvtx = GeomInt_LineTool::NbVertex(L);
252     intrvtested = Standard_False;
253     for(i=1; i<nbvtx; ++i) { 
254       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
255       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
256       if(Abs(firstp-lastp)>Precision::PConfusion()) {
257         intrvtested = Standard_True;
258         const Standard_Real pmid = (firstp+lastp)*0.5;
259         gp_Pnt Pmid;
260         //modified by NIZNHY-PKV Fri Nov 11 10:27:01 2011f
261         GLinePoint(typl, GLine, pmid, Pmid);
262         /*
263         switch (typl) {
264           case IntPatch_Lin:       
265             Pmid = ElCLib::Value(pmid,GLine->Line()); 
266             break;
267           case IntPatch_Circle:    
268             Pmid = ElCLib::Value(pmid,GLine->Circle()); 
269             break;
270           case IntPatch_Ellipse:   
271             Pmid = ElCLib::Value(pmid,GLine->Ellipse()); 
272             break;
273           case IntPatch_Hyperbola: 
274             Pmid = ElCLib::Value(pmid,GLine->Hyperbola()); 
275             break;
276           case IntPatch_Parabola:  
277             Pmid = ElCLib::Value(pmid,GLine->Parabola()); 
278             break;
279           default:
280             break;
281         }
282         */
283         //modified by NIZNHY-PKV Fri Nov 11 12:25:40 2011t
284         //
285         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
286         Recadre(myHS1,myHS2,u1,v1,u2,v2);
287         const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
288         if(in1 !=  TopAbs_OUT) { 
289           const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
290           if(in2 != TopAbs_OUT) { 
291             seqp.Append(firstp);
292             seqp.Append(lastp);
293           }
294         }
295       }
296     }
297     //
298     if(typl == IntPatch_Circle || typl == IntPatch_Ellipse)    { 
299       firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
300       lastp  = M_PI + M_PI + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
301       const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
302       const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
303       Standard_Real acadr = (firstp+lastp)*0.5;
304       while(acadr < cadrinf) { 
305         acadr+=M_PI+M_PI; 
306       }
307       while(acadr > cadrsup) { 
308         acadr-=M_PI+M_PI; 
309       } 
310       if(acadr>=cadrinf && acadr<=cadrsup)      { 
311         if(Abs(firstp-lastp)>Precision::PConfusion())        {
312           intrvtested = Standard_True;
313           const Standard_Real pmid = (firstp+lastp)*0.5;
314           gp_Pnt Pmid;
315           if (typl == IntPatch_Circle) {
316             Pmid = ElCLib::Value(pmid,GLine->Circle());
317           }
318           else {
319             Pmid = ElCLib::Value(pmid,GLine->Ellipse());
320           }
321           Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
322           Recadre(myHS1,myHS2,u1,v1,u2,v2);
323           const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
324           if(in1 !=  TopAbs_OUT) { 
325             const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
326             if(in2 != TopAbs_OUT) { 
327               seqp.Append(firstp);
328               seqp.Append(lastp);
329             }
330           }
331         }
332       }
333     }      
334     if (!intrvtested) {
335       // Keep a priori. A point 2d on each
336       // surface is required to make the decision. Will be done in the caller
337       seqp.Append(GeomInt_LineTool::FirstParameter(L));
338       seqp.Append(GeomInt_LineTool::LastParameter(L));
339     }
340     //
341     // Treatment Circles/Ellipses that are the results of intersection
342     // between Plane / (Cylinder, Sphere).
343     // In these cases the intersection curves can contain 
344     // a lot of 'vertices' on the curve that leads to a lot of parts 
345     // of the curve. Some adjacent parts can be united to the one part.
346     // 
347     Standard_Integer aNbParts;
348     //
349     aNbParts = seqp.Length()/2;
350     if (aNbParts > 1 && (typl == IntPatch_Circle || typl == IntPatch_Ellipse))  {
351       Standard_Boolean bCond, bPCS, bPCS1, bPCS2, bCC;
352       GeomAbs_SurfaceType aST1, aST2;
353       //
354       aST1 = myHS1->Surface().GetType();
355       aST2 = myHS2->Surface().GetType();
356       //
357       bPCS1=((aST1==GeomAbs_Plane) && (aST2==GeomAbs_Cylinder || aST2==GeomAbs_Sphere));
358       bPCS2=((aST2==GeomAbs_Plane) && (aST1==GeomAbs_Cylinder || aST1==GeomAbs_Sphere));
359       bPCS=(bPCS1 || bPCS2);
360       bCC=(aST1==GeomAbs_Cylinder && aST2==GeomAbs_Cylinder);
361       //
362       // ZZ
363       //modified by NIZNHY-PKV Fri Nov 11 10:13:58 2011f
364       Standard_Integer j, i1, i2;
365       Standard_Real aT, aU, aV;
366       Handle(GeomAdaptor_HSurface) aHS;
367       //
368       bCond=Standard_False;
369       //
370       if (bCC) {
371         bCond=Standard_True;
372       }
373       else if (bPCS) {
374         if ((aST1==GeomAbs_Sphere) || (aST2==GeomAbs_Sphere)) {
375           if (aST1==GeomAbs_Sphere) {
376             aHS=myHS1;
377           }
378           else if (aST2==GeomAbs_Sphere){
379             aHS=myHS2;
380           }
381           //
382           Standard_Integer aNbP;
383           Standard_Real aHalfPI, aPPC;
384           //
385           bCond=Standard_True;
386           //
387           aNbP=seqp.Length();
388           aPPC=Precision::PConfusion();
389           aHalfPI=0.5*PI;
390           i1=0;
391           i2=0;
392           //
393           for (i=1; i<=aNbP; ++i) {
394             gp_Pnt aP;
395           //
396             aT=seqp(i);
397             GLinePoint(typl, GLine, aT, aP);
398             Parameters(aHS, aP, aU, aV);
399             if (aV<0.) {
400               if (fabs(aV+aHalfPI) < aPPC) {
401                 ++i2;
402               }
403             }
404             else {
405               if (fabs(aV-aHalfPI) < aPPC) {
406                 ++i1;
407               }
408             }
409           }
410           if (i1==2 || i2==2) {
411             bCond=Standard_False;
412           }
413         } 
414       }// else if (bPCS1 || bPCS2) {
415       //modified by NIZNHY-PKV Fri Nov 11 10:14:00 2011t
416       //
417       if (bCond){
418         Standard_Integer i2, j2;
419         Standard_Real aFi, aLi, aFj, aLj, aF, aL;
420         TColStd_SequenceOfReal aSeq;
421         //
422         aFi=seqp(1);
423         aSeq.Append(aFi);
424         for (i=1; i<aNbParts; ++i) {
425           j=i+1;
426           i2=2*i;
427           j2=2*j;
428           //
429           aFi=seqp(i2-1);
430           aLi=seqp(i2);
431           //
432           aFj=seqp(j2-1);
433           aLj=seqp(j2);
434           //
435           if (fabs (aFj-aLi) < Tol) {
436             aL=aLj;
437           }
438           else {
439             aL=aLi;
440             aSeq.Append(aL);
441             aF=aFj;
442             aSeq.Append(aF);
443           }
444         }
445         aSeq.Append(aLj);
446         //
447         seqp.Clear();
448         aNbParts=aSeq.Length();
449         for (i=1; i<=aNbParts; ++i) {
450           aF=aSeq(i);
451           seqp.Append(aF);
452         }
453       }
454     }
455     //
456     done =Standard_True;
457     return;
458   }// else if (typl != IntPatch_Restriction)  { 
459
460   done = Standard_False;
461   seqp.Clear();
462   nbvtx = GeomInt_LineTool::NbVertex(L);
463   if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
464                     // surface to make the decision. Will be done in the caller
465     seqp.Append(GeomInt_LineTool::FirstParameter(L));
466     seqp.Append(GeomInt_LineTool::LastParameter(L));
467     done = Standard_True;
468     return;
469   }
470
471   GeomInt_SequenceOfParameterAndOrientation seqpss;
472   TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
473
474   for (i=1; i<=nbvtx; i++)  {
475     const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
476     const Standard_Real prm = thevtx.ParameterOnLine();
477     if (thevtx.IsOnDomS1())    {
478       switch (thevtx.TransitionLineArc1().TransitionType())      {
479         case IntSurf_In:        or1 = TopAbs_FORWARD; break;  
480         case IntSurf_Out:       or1 = TopAbs_REVERSED; break;  
481         case IntSurf_Touch:     or1 = TopAbs_INTERNAL; break;  
482         case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;  
483       }
484     }
485     else {
486       or1 = TopAbs_INTERNAL;
487     }
488     
489     if (thevtx.IsOnDomS2())    {
490       switch (thevtx.TransitionLineArc2().TransitionType())      {
491         case IntSurf_In:        or2 = TopAbs_FORWARD; break;
492         case IntSurf_Out:       or2 = TopAbs_REVERSED; break;
493         case IntSurf_Touch:     or2 = TopAbs_INTERNAL; break;
494         case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
495       }
496     }
497     else {
498       or2 = TopAbs_INTERNAL;
499     }
500     //
501     const Standard_Integer nbinserted = seqpss.Length();
502     Standard_Boolean inserted = Standard_False;
503     for (Standard_Integer j=1; j<=nbinserted;j++)    {
504       if (Abs(prm-seqpss(j).Parameter()) <= Tol)      {
505         // accumulate
506         GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
507         if (or1 != TopAbs_INTERNAL) {
508           if (valj.Orientation1() != TopAbs_INTERNAL) {
509             if (or1 != valj.Orientation1()) {
510               valj.SetOrientation1(TopAbs_INTERNAL);
511             }
512           }
513           else {
514             valj.SetOrientation1(or1);
515           }
516         }
517         
518         if (or2 != TopAbs_INTERNAL) {
519           if (valj.Orientation2() != TopAbs_INTERNAL) {
520             if (or2 != valj.Orientation2()) {
521               valj.SetOrientation2(TopAbs_INTERNAL);
522             }
523           }
524           else {
525             valj.SetOrientation2(or2);
526           }
527         }         
528         inserted = Standard_True;
529         break;
530       }
531       
532       if (prm < seqpss(j).Parameter()-Tol ) {
533         // insert before position j
534         seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
535         inserted = Standard_True;
536         break;
537       }
538       
539     }
540     if (!inserted) {
541       seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
542     }
543   }
544
545   // determine the state at the beginning of line
546   Standard_Boolean trim = Standard_False;
547   Standard_Boolean dansS1 = Standard_False;
548   Standard_Boolean dansS2 = Standard_False;
549
550   nbvtx = seqpss.Length();
551   for (i=1; i<= nbvtx; i++)  {
552     or1 = seqpss(i).Orientation1();
553     if (or1 != TopAbs_INTERNAL)    {
554       trim = Standard_True;
555       dansS1 = (or1 != TopAbs_FORWARD);
556       break;
557     }
558   }
559   
560   if (i > nbvtx)  {
561     Standard_Real U,V;
562     for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )    {
563       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() )      {
564         GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
565         gp_Pnt2d PPCC(U,V);
566         if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
567           done = Standard_True;
568           return;
569         }
570         break;
571       }
572     }
573     dansS1 = Standard_True; // Keep in doubt
574   }
575   //
576   for (i=1; i<= nbvtx; i++)  {
577     or2 = seqpss(i).Orientation2();
578     if (or2 != TopAbs_INTERNAL)    {
579       trim = Standard_True;
580       dansS2 = (or2 != TopAbs_FORWARD);
581       break;
582     }
583   }
584   
585   if (i > nbvtx)  {
586     Standard_Real U,V;
587     for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )    {
588       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() )      {
589         GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
590         if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
591           done = Standard_True;
592           return;
593         }
594         break;
595       }
596     }
597     dansS2 = Standard_True; //  Keep in doubt
598   }
599
600   if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
601     seqp.Append(GeomInt_LineTool::FirstParameter(L));
602     seqp.Append(GeomInt_LineTool::LastParameter(L));
603     done = Standard_True;
604     return;
605   }
606
607   // sequence seqpss is peeled to create valid ends 
608   // and store them in seqp(2*i+1) and seqp(2*i+2)
609   Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
610   Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
611   firstp = thefirst;
612
613   for (i=1; i<=nbvtx; i++)  {
614     or1 = seqpss(i).Orientation1(); 
615     or2 = seqpss(i).Orientation2(); 
616     if (dansS1 && dansS2)    {
617       if (or1 == TopAbs_REVERSED){
618         dansS1 = Standard_False;
619       }
620       
621       if (or2 == TopAbs_REVERSED){
622         dansS2 = Standard_False;
623       }
624       if (!dansS1 || !dansS2)      {
625         lastp = seqpss(i).Parameter();
626         Standard_Real stofirst = Max(firstp, thefirst);
627         Standard_Real stolast  = Min(lastp,  thelast) ;
628
629         if (stolast > stofirst) {
630           seqp.Append(stofirst);
631           seqp.Append(stolast);
632         }
633         if (lastp > thelast) {
634           break;
635         }
636       }
637     }
638     else    {
639       if (dansS1)      {
640         if (or1 == TopAbs_REVERSED) {
641           dansS1 = Standard_False;
642         }
643       }
644       else      {
645         if (or1 == TopAbs_FORWARD){
646           dansS1 = Standard_True;
647         }
648       }
649       if (dansS2) {
650         if (or2 == TopAbs_REVERSED) {
651           dansS2 = Standard_False;
652         }
653       }
654       else {
655         if (or2 == TopAbs_FORWARD){
656           dansS2 = Standard_True;
657         }
658       }
659       if (dansS1 && dansS2){
660         firstp = seqpss(i).Parameter();
661       }
662     }
663   }
664   //
665   // finally to add
666   if (dansS1 && dansS2)  {
667     lastp  = thelast;
668     firstp = Max(firstp,thefirst);
669     if (lastp > firstp) {
670       seqp.Append(firstp);
671       seqp.Append(lastp);
672     }
673   }
674   done = Standard_True;
675 }
676
677
678 //=======================================================================
679 //function : PeriodicLine
680 //purpose  : 
681 //=======================================================================
682 void IntTools_LineConstructor::PeriodicLine (const Handle(IntPatch_Line)& L) const
683 {
684   const IntPatch_IType typl = L->ArcType();
685   if (typl != IntPatch_Circle && typl != IntPatch_Ellipse)
686     return;
687
688   const Standard_Real Tol = Precision::PConfusion();
689   Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L);
690   Standard_Integer i,j,nbvtx = glin->NbVertex();
691   for (i=1; i<=nbvtx; i++)
692   {
693     IntPatch_Point thevtx = glin->Vertex(i);
694     const Standard_Real prm = thevtx.ParameterOnLine();
695     Standard_Boolean changevtx = Standard_False;
696     if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2())
697     {
698       for (j=1; j<=nbvtx; j++)
699       {
700         if (j!=i)
701         {
702           const IntPatch_Point& thevtxbis = glin->Vertex(j);
703           const Standard_Real prmbis = thevtxbis.ParameterOnLine();
704           if (Abs(prm-prmbis) <= Tol)
705           {
706             Standard_Real u,v;
707             gp_Pnt2d p2d;
708             if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() &&
709                 thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In)
710             {
711               p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1());
712               u = p2d.X(); v = p2d.Y();
713               p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1());
714               if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
715               {
716                 changevtx = Standard_True;
717                 break;
718               }
719             }
720             if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() &&
721                 thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In)
722             {
723               p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2());
724               u = p2d.X(); v = p2d.Y();
725               p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2());
726               if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
727               {
728                 changevtx = Standard_True;
729                 break;
730               }
731             }
732           }
733         }
734       }
735     }
736     if (changevtx) {
737       thevtx.SetParameter(prm + 2.*M_PI);
738       glin->Replace(i,thevtx);
739     }
740   }
741 }
742 //modified by NIZNHY-PKV Fri Nov 11 10:30:34 2011f
743 //=======================================================================
744 //function : Recadre
745 //purpose  : 
746 //=======================================================================
747 void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
748              const Handle(GeomAdaptor_HSurface)& myHS2,
749              Standard_Real& u1,
750              Standard_Real& v1,
751              Standard_Real& u2,
752              Standard_Real& v2)
753
754   Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
755   const GeomAbs_SurfaceType typs1 = myHS1->GetType();
756   switch (typs1)
757   { 
758     case GeomAbs_Cylinder:
759     case GeomAbs_Cone:
760     case GeomAbs_Sphere: 
761     { 
762       myHS1IsUPeriodic = Standard_True;
763       myHS1IsVPeriodic = Standard_False;
764       break;
765     }
766     case GeomAbs_Torus:
767     {
768       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
769       break;
770     }
771     default:
772     {
773       //-- Case of periodic biparameters is processed upstream
774       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
775       break;
776     }
777   }
778   Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
779   const GeomAbs_SurfaceType typs2 = myHS2->GetType();
780   switch (typs2)
781   { 
782     case GeomAbs_Cylinder:
783     case GeomAbs_Cone:
784     case GeomAbs_Sphere: 
785     { 
786       myHS2IsUPeriodic = Standard_True;
787       myHS2IsVPeriodic = Standard_False;
788       break;
789     }
790     case GeomAbs_Torus:
791     {
792       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
793       break;
794     }
795     default:
796     {
797       //-- Case of periodic biparameters is processed upstream
798       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
799       break;
800     }
801   }
802   if(myHS1IsUPeriodic) {
803     const Standard_Real lmf = PI+PI; //-- myHS1->UPeriod();
804     const Standard_Real f = myHS1->FirstUParameter();
805     const Standard_Real l = myHS1->LastUParameter();
806     while(u1 < f) { u1+=lmf; } 
807     while(u1 > l) { u1-=lmf; }
808   }
809   if(myHS1IsVPeriodic) {
810     const Standard_Real lmf = PI+PI; //-- myHS1->VPeriod(); 
811     const Standard_Real f = myHS1->FirstVParameter();
812     const Standard_Real l = myHS1->LastVParameter();
813     while(v1 < f) { v1+=lmf; } 
814     while(v1 > l) { v1-=lmf; }
815   }
816   if(myHS2IsUPeriodic) { 
817     const Standard_Real lmf = PI+PI; //-- myHS2->UPeriod();
818     const Standard_Real f = myHS2->FirstUParameter();
819     const Standard_Real l = myHS2->LastUParameter();
820     while(u2 < f) { u2+=lmf; } 
821     while(u2 > l) { u2-=lmf; }
822   }
823   if(myHS2IsVPeriodic) { 
824     const Standard_Real lmf = PI+PI; //-- myHS2->VPeriod();
825     const Standard_Real f = myHS2->FirstVParameter();
826     const Standard_Real l = myHS2->LastVParameter();
827     while(v2 < f) { v2+=lmf; } 
828     while(v2 > l) { v2-=lmf; }
829   }
830 }
831 //=======================================================================
832 //function : Parameters
833 //purpose  : 
834 //=======================================================================
835 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
836                 const Handle(GeomAdaptor_HSurface)& myHS2,
837                 const gp_Pnt& Ptref,
838                 Standard_Real& U1,
839                 Standard_Real& V1,
840                 Standard_Real& U2,
841                 Standard_Real& V2)
842 {
843   //modified by NIZNHY-PKV Fri Nov 11 10:07:55 2011f
844   Parameters(myHS1, Ptref, U1, V1);
845   Parameters(myHS2, Ptref, U2, V2);
846   /*
847   IntSurf_Quadric quad1,quad2;
848   switch (myHS1->Surface().GetType())
849   {
850     case GeomAbs_Plane:    quad1.SetValue(myHS1->Surface().Plane()); break;
851     case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break;
852     case GeomAbs_Cone:     quad1.SetValue(myHS1->Surface().Cone()); break;
853     case GeomAbs_Sphere:   quad1.SetValue(myHS1->Surface().Sphere()); break;
854     default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
855   }
856   switch (myHS2->Surface().GetType())
857   {
858     case GeomAbs_Plane:    quad2.SetValue(myHS2->Surface().Plane()); break;
859     case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break;
860     case GeomAbs_Cone:     quad2.SetValue(myHS2->Surface().Cone()); break;
861     case GeomAbs_Sphere:   quad2.SetValue(myHS2->Surface().Sphere()); break;
862     default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
863   }
864   quad1.Parameters(Ptref,U1,V1);
865   quad2.Parameters(Ptref,U2,V2);
866   */
867   //modified by NIZNHY-PKV Fri Nov 11 10:08:38 2011t
868 }
869 //modified by NIZNHY-PKV Fri Nov 11 10:06:02 2011f
870 //=======================================================================
871 //function : Parameter
872 //purpose  : 
873 //=======================================================================
874 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
875                 const gp_Pnt& Ptref,
876                 Standard_Real& U1,
877                 Standard_Real& V1)
878 {
879   IntSurf_Quadric quad1;
880   //
881   switch (myHS1->Surface().GetType())  {
882     case GeomAbs_Plane:    
883       quad1.SetValue(myHS1->Surface().Plane()); 
884       break;
885     case GeomAbs_Cylinder: 
886       quad1.SetValue(myHS1->Surface().Cylinder()); 
887       break;
888     case GeomAbs_Cone:     
889       quad1.SetValue(myHS1->Surface().Cone()); 
890       break;
891     case GeomAbs_Sphere:   
892       quad1.SetValue(myHS1->Surface().Sphere()); 
893       break;
894     default: 
895       Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
896   }
897   quad1.Parameters(Ptref,U1,V1);
898 }
899
900 //=======================================================================
901 //function : GLinePoint
902 //purpose  : 
903 //=======================================================================
904 void GLinePoint(const IntPatch_IType typl,
905                 const Handle(IntPatch_GLine)& GLine,
906                 const Standard_Real aT,
907                 gp_Pnt& aP)
908 {
909   switch (typl) {
910     case IntPatch_Lin:       
911     aP = ElCLib::Value(aT, GLine->Line()); 
912     break;
913   case IntPatch_Circle:    
914     aP = ElCLib::Value(aT, GLine->Circle()); 
915     break;
916   case IntPatch_Ellipse:   
917     aP = ElCLib::Value(aT, GLine->Ellipse()); 
918     break;
919   case IntPatch_Hyperbola: 
920     aP = ElCLib::Value(aT, GLine->Hyperbola()); 
921     break;
922   case IntPatch_Parabola:  
923     aP = ElCLib::Value(aT, GLine->Parabola()); 
924     break;
925   default:
926     Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
927   }
928 }
929 //modified by NIZNHY-PKV Fri Nov 11 10:06:04 2011t