0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / ShapeFix / ShapeFix_EdgeProjAux.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //:r5 abv 06.04.99: ec_turbine-A.stp, #4313: protect against null curve
15 //    abv 09.04.99  S4136: add parameter preci (to eliminate BRepAPI::Precision)
16
17 #include <Adaptor3d_CurveOnSurface.hxx>
18 #include <BRep_Tool.hxx>
19 #include <ElCLib.hxx>
20 #include <Extrema_ExtPC.hxx>
21 #include <Geom2d_BoundedCurve.hxx>
22 #include <Geom2d_BSplineCurve.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2d_Line.hxx>
25 #include <Geom2dAdaptor_Curve.hxx>
26 #include <Geom2dAdaptor_HCurve.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_SphericalSurface.hxx>
29 #include <Geom_Surface.hxx>
30 #include <GeomAdaptor_HSurface.hxx>
31 #include <GeomAdaptor_Surface.hxx>
32 #include <gp_Pnt.hxx>
33 #include <Precision.hxx>
34 #include <ShapeAnalysis.hxx>
35 #include <ShapeAnalysis_Curve.hxx>
36 #include <ShapeAnalysis_Edge.hxx>
37 #include <ShapeAnalysis_Surface.hxx>
38 #include <ShapeFix_EdgeProjAux.hxx>
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_Failure.hxx>
41 #include <Standard_Type.hxx>
42 #include <TopExp.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <Adaptor3d_HCurve.hxx>
47 #include <BSplCLib.hxx>
48
49 IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_EdgeProjAux,Standard_Transient)
50
51 //=======================================================================
52 //function : ShapeFix_EdgeProjAux
53 //purpose  : 
54 //=======================================================================
55 ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux ()
56 : myFirstParam(0.0),
57   myLastParam(0.0),
58   myFirstDone(Standard_False),
59   myLastDone(Standard_False)
60 {
61 }
62
63 //=======================================================================
64 //function : ShapeFix_EdgeProjAux
65 //purpose  : 
66 //=======================================================================
67
68 ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux (const TopoDS_Face& F,
69                                             const TopoDS_Edge& E)
70 {
71   Init (F, E);
72 }
73
74 //=======================================================================
75 //function : Init
76 //purpose  : 
77 //=======================================================================
78
79 void ShapeFix_EdgeProjAux::Init (const TopoDS_Face& F,
80                                  const TopoDS_Edge& E)
81 {
82   myFace = F;
83   myEdge = E;
84   myFirstParam = myLastParam = 0.;
85   myFirstDone = myLastDone = Standard_False;
86 }
87
88 //=======================================================================
89 //function : Compute
90 //purpose  : 
91 //=======================================================================
92
93 void ShapeFix_EdgeProjAux::Compute (const Standard_Real preci) 
94 {
95   myFirstDone = myLastDone = Standard_False;
96     
97   // Project Point3d on Surface
98   // TEMPORARY Call ShapeFix_EdgeProjAux
99   myFirstParam = 0.;
100   myLastParam = 0.;
101   Init2d(preci);
102   if (IsFirstDone() && IsLastDone()) {
103     Standard_Real U1 = FirstParam();
104     Standard_Real U2 = LastParam();
105     if (U1>=U2) {
106 #ifdef OCCT_DEBUG
107       std::cout << "Parametres inverses ... " << std::endl;
108 #endif
109       Standard_Real tmp = U1;
110       U1 = U2; U2 = tmp;
111     }
112     myFirstParam = U1;
113     myFirstDone  = Standard_True;
114     myLastParam  = U2;
115     myLastDone   = Standard_True;
116   }
117 }
118
119 //=======================================================================
120 //function : IsFirstDone
121 //purpose  : 
122 //=======================================================================
123
124 Standard_Boolean ShapeFix_EdgeProjAux::IsFirstDone() const
125 {
126   return myFirstDone;
127 }
128
129 //=======================================================================
130 //function : IsLastDone
131 //purpose  : 
132 //=======================================================================
133
134 Standard_Boolean ShapeFix_EdgeProjAux::IsLastDone() const
135 {
136   return myLastDone;
137 }
138
139 //=======================================================================
140 //function : FirstParam
141 //purpose  : 
142 //=======================================================================
143
144 Standard_Real ShapeFix_EdgeProjAux::FirstParam() const
145 {
146   return myFirstParam;
147 }
148
149 //=======================================================================
150 //function : LastParam
151 //purpose  : 
152 //=======================================================================
153
154 Standard_Real ShapeFix_EdgeProjAux::LastParam() const
155 {
156   return myLastParam;
157 }
158
159 //=======================================================================
160 //function : IsIso
161 //purpose  : 
162 //=======================================================================
163
164 Standard_Boolean ShapeFix_EdgeProjAux::IsIso (const Handle(Geom2d_Curve)& /*theCurve2d*/)
165 {
166   // Until an ISO is recognized by Adaptor3d_Curve
167 /*  
168   if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
169     Handle(Geom2d_Line) theLine2d = Handle(Geom2d_Line)::DownCast(theCurve2d);
170     gp_Dir2d theDir2d = theLine2d->Direction();
171     
172     gp_Dir2d dir1(0.,1.);
173     gp_Dir2d dir2(0.,-1.);
174     
175     return (theDir2d.IsEqual(dir1,Precision::Angular()) ||
176             theDir2d.IsEqual(dir2,Precision::Angular()) ||
177             theDir2d.IsNormal(dir1,Precision::Angular()) ||
178             theDir2d.IsNormal(dir2,Precision::Angular()) );
179   }
180 */
181   return Standard_False;
182 }
183
184 // ----------------------------------------------------------------------------
185 // static  : FindParameterWithExt
186 // Purpose : Computes the trimming parameter of Pt1 on COnS
187 // ----------------------------------------------------------------------------
188
189 static Standard_Boolean FindParameterWithExt (const gp_Pnt& Pt1, 
190                                               const Adaptor3d_CurveOnSurface& COnS,
191                                               const Standard_Real Uinf,
192                                               const Standard_Real Usup, 
193                                               const Standard_Real preci,
194                                               Standard_Real& w1)
195 {
196   try {  // et allez donc !
197     OCC_CATCH_SIGNALS
198     Extrema_ExtPC myExtPC (Pt1, COnS, Uinf, Usup, preci);
199
200     //ShapeFix_ExtPCOnS myExtPCOnS1 = 
201     //ShapeFix_ExtPCOnS(Pt1, COnS, Uinf, Usup, preci);
202   
203     if (myExtPC.IsDone()) {
204       Standard_Integer NbExt1 = myExtPC.NbExt();
205       for (Standard_Integer i=1; i<=NbExt1; i++) {
206         if (myExtPC.IsMin(i)) {
207           //Standard_Real dist = myExtPC.Value(i); //szv#4:S4163:12Mar99 debug mode only
208           w1   = myExtPC.Point(i).Parameter();
209         }
210       }
211       return Standard_True;
212     }
213     else return Standard_False;
214   }  // end try
215   catch(Standard_Failure const& anException) {
216 #ifdef OCCT_DEBUG
217 //:s5
218     std::cout << "Warning: ShapeFix_EdgeProjAux, FindParameterWithExt(): Exception: ";
219     anException.Print(std::cout); std::cout << std::endl;
220 #endif
221     (void)anException;
222     return Standard_False;
223   }
224 }
225
226 //=======================================================================
227 //function : Init2d
228 //purpose  : 
229 //=======================================================================
230
231 void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci) 
232 {
233   Standard_Real cl = 0., cf = 0.;
234     // Extract Geometries
235   myFirstDone = myLastDone = Standard_False;
236   Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
237   Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
238   if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99:  ec_turbine-A.stp, #4313
239   myFirstParam = 0.;
240   myLastParam  = 0.;
241   TopoDS_Vertex V1,V2;
242   TopExp::Vertices(myEdge, V1, V2);
243   gp_Pnt Pt1,Pt2;
244   // pdn 28.12.98: r_39-db.stp #605: use ends of 3d curve instead of vertices 
245   ShapeAnalysis_Edge sae;
246   Standard_Real a,b;
247   Handle(Geom_Curve) C3d;
248   if(sae.Curve3d(myEdge,C3d,a,b,Standard_False)) {
249     Pt1 = C3d->Value(a);
250     Pt2 = C3d->Value(b);
251   } 
252   else {
253     Pt1 = BRep_Tool::Pnt(V1);
254     Pt2 = BRep_Tool::Pnt(V2);
255   }
256   //:S4136  Standard_Real preci = BRepAPI::Precision();
257   //pdn to manage degenerated case
258   if (V1.IsSame(V2)) {
259     Handle(ShapeAnalysis_Surface) stsu = new ShapeAnalysis_Surface (theSurface);
260     gp_Pnt2d aPt1,aPt2;
261     Standard_Real firstpar,lastpar;
262     if (stsu->DegeneratedValues(Pt1,preci,aPt1,aPt2,firstpar,lastpar)){
263
264       if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
265         if (aPt1.IsEqual(theCurve2d->Value(firstpar),preci) && 
266           aPt2.IsEqual(theCurve2d->Value(lastpar),preci)){
267             myFirstParam = firstpar;
268             myLastParam  = lastpar;
269             myFirstDone = myLastDone = Standard_True;
270             return;
271         }
272       } 
273 #ifdef OCCT_DEBUG
274       else std::cout <<"Other type of deg curve"<<std::endl;
275 #endif
276
277     }
278   }
279
280   Standard_Boolean parU = Standard_False, parV = Standard_False;
281   GeomAdaptor_Surface          SA     = GeomAdaptor_Surface(theSurface);
282   Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
283
284   cf = theCurve2d->FirstParameter();
285   cl = theCurve2d->LastParameter();
286   //pdn cutting pcurve by suface bounds
287   if (Precision::IsInfinite(cf)||Precision::IsInfinite(cl)) {
288     if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
289       Standard_Real uf,ul,vf,vl;
290       theSurface->Bounds(uf,ul,vf,vl);
291       //Correct surface limits for extrusion/revolution surfaces based on hyperbola
292       //23 is ln(1.0e+10)
293       if(SA.GetType() == GeomAbs_SurfaceOfExtrusion)
294       {
295         if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola)
296         {
297           uf = Max(uf, -23.);
298           ul = Min(ul,  23.);
299         }
300       }
301       if(SA.GetType() == GeomAbs_SurfaceOfRevolution)
302       {
303         if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola)
304         {
305           vf = Max(vf, -23.);
306           vl = Min(vl,  23.);
307         }
308       }
309       if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)&&
310          !Precision::IsInfinite(vf)&&!Precision::IsInfinite(vl)) {
311           Standard_Real cfi,cli;
312           Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
313           gp_Pnt2d pnt = lin->Location();
314           gp_Dir2d dir = lin->Direction();
315           if (dir.Y()==0) {
316             parU = Standard_True;
317             cfi = (uf-pnt.X())/dir.X();
318             cli = (ul-pnt.X())/dir.X();
319           } 
320           else if (dir.X()==0) {
321             parV = Standard_True;
322             cfi = (vf-pnt.Y())/dir.Y();
323             cli = (vl-pnt.Y())/dir.Y();
324           } 
325           else {//common case
326             Standard_Real xfi, xli, yfi, yli;
327             xfi = (uf-pnt.X())/dir.X();
328             xli = (ul-pnt.X())/dir.X();
329             yfi = (vf-pnt.Y())/dir.Y();
330             yli = (vl-pnt.Y())/dir.Y();
331             if (dir.X()*dir.Y() > 0) {
332               cfi = (Abs(xli-xfi) < Abs(xli-yfi)? xfi : yfi);
333               cli = (Abs(xfi-xli) < Abs(xfi-yli)? xli : yli);
334             } else {
335               cfi = (Abs(xli-xfi) < Abs(xli-yli)? xfi : yli);
336               cli = (Abs(yli-xli) < Abs(yli-yfi)? xli : yfi);
337             }
338           }
339           if (cfi < cli) { cf = cfi; cl = cli; }
340           else { cf = cli; cl = cfi; }
341       } 
342       else if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)){
343         Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
344         gp_Dir2d dir = lin->Direction();
345         if (dir.X()!=0) {
346           if (dir.Y()==0) parU = Standard_True;
347           gp_Pnt2d pnt = lin->Location(); //szv#4:S4163:12Mar99 moved
348           Standard_Real cfi = (uf-pnt.X())/dir.X();
349           Standard_Real cli = (ul-pnt.X())/dir.X();
350           if (cfi < cli) { cf = cfi; cl = cli; }
351           else { cf = cli; cl = cfi; }
352         }
353         else {
354           cf=-10000;
355           cl= 10000;
356         }
357       }
358       else {
359         cf=-10000;
360         cl= 10000;
361         //pdn not cutted by bounds
362 #ifdef OCCT_DEBUG
363         std::cout<<"Infinite Surface"<<std::endl;
364 #endif  
365       }
366     }
367     else {
368       //pdn not linear case not managed
369       cf=-10000;
370       cl= 10000;
371       if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
372       {
373         //Try to reparametrize (CASE dxf read bug25899)
374         Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d->Copy());
375         TColStd_Array1OfReal aNewKnots(1, aBspl->NbKnots());  
376         aBspl->Knots(aNewKnots);
377         BSplCLib::Reparametrize(cf, cl, aNewKnots);
378         aBspl->SetKnots(aNewKnots);
379         theCurve2d = aBspl;
380       }
381
382 #ifdef OCCT_DEBUG
383       std::cout<<"Some infinite curve"<<std::endl;
384 #endif 
385     }
386   }
387
388   Geom2dAdaptor_Curve          CA     = Geom2dAdaptor_Curve(theCurve2d,cf,cl);
389   Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
390
391   Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
392
393   // ----------------------------------------------
394   // --- topological limit == geometric limit ? ---
395   // ----------------------------------------------
396   Standard_Real Uinf = COnS.FirstParameter();
397   Standard_Real Usup = COnS.LastParameter();
398  
399   Standard_Real w1 = 0., w2 = 0.;
400   ShapeAnalysis_Curve sac;
401   gp_Pnt pnt;
402   Standard_Real dist = sac.Project(COnS,Pt1,preci,pnt,w1,Standard_False);
403   //if distance is infinite then projection is not performed
404   if( Precision::IsInfinite(dist))
405     return;
406   
407   myFirstDone = Standard_True;
408   myFirstParam = w1;
409  
410   dist = sac.Project(COnS,Pt2,preci,pnt,w2,Standard_False);
411   
412   if( Precision::IsInfinite(dist))
413     return;
414   
415   myLastDone = Standard_True;
416   myLastParam  = w2;
417     
418   if(fabs(w1 - w2) < Precision::PConfusion())
419   {
420     if(!theSurface->IsUPeriodic() && !theSurface->IsVPeriodic())
421       return;
422   }
423     
424   if ( myFirstParam == Uinf && myLastParam == Usup ) return;
425   if ( myFirstParam == Usup && myLastParam == Uinf ) {
426     myFirstParam = theCurve2d->ReversedParameter(Usup);
427     myLastParam  = theCurve2d->ReversedParameter(Uinf);
428     theCurve2d->Reverse();
429 #ifdef OCCT_DEBUG
430     std::cout << "Warning: ShapeFix_EdgeProjAux: pcurve reversed" << std::endl;
431 #endif
432     return;
433   }
434   //:abv 29.08.01: SAT: fix for closed case
435   if ( COnS.Value(Uinf).Distance ( COnS.Value(Usup) ) < Precision::Confusion() ) {
436     // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
437     if ( Abs(myFirstParam-Uinf) < ::Precision::PConfusion() &&
438       Abs(myLastParam-Uinf) < ::Precision::PConfusion() )
439       myLastParam = w2 = Usup;
440     // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
441     else if ( Abs(myFirstParam-Usup) < ::Precision::PConfusion() && 
442       Abs(myLastParam-Usup) < ::Precision::PConfusion() )
443       myFirstParam = w1 = Uinf;
444   }
445
446   //pdn adjust parameters in periodic case
447   if(parU || parV) {
448     Standard_Real uf,ul,vf,vl;
449     theSurface->Bounds(uf,ul,vf,vl);
450     Standard_Real period = (parU ? ul-uf : vl-vf);
451     w1+=ShapeAnalysis::AdjustToPeriod(w1,0,period);
452     myFirstParam = w1;
453     w2+=ShapeAnalysis::AdjustToPeriod(w2,0,period);
454     myLastParam = w2;
455     Handle(Geom_Curve) C3d1;
456     if(!sae.Curve3d (myEdge, C3d1, cf, cl, Standard_False )) {
457       UpdateParam2d(theCurve2d);
458       return;
459     }
460     gp_Pnt mid = C3d1->Value((cf+cl)/2);
461     Standard_Real wmid;
462     sac.Project(COnS,mid,preci,pnt,wmid,Standard_False);
463     wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period);
464     if(w1>=w2) {
465       if(w2 > wmid) myFirstParam -= period;
466       else if (w1 > wmid)
467         UpdateParam2d(theCurve2d);
468       else {
469         myLastParam+=period;
470 #ifdef OCCT_DEBUG
471         std::cout <<" Added"<<std::endl;
472 #endif  
473       }
474     }
475     else {
476       if(w1 > wmid) {
477         myLastParam -=period;
478         UpdateParam2d(theCurve2d);
479 #ifdef OCCT_DEBUG
480         std::cout <<" Added & Inverted"<<std::endl;
481 #endif  
482       } else if (w2 < wmid) {
483         myFirstParam += period;
484         UpdateParam2d(theCurve2d);
485       }
486     }
487   }
488   UpdateParam2d(theCurve2d);
489   return;
490 }
491
492 //=======================================================================
493 //function : Init3d
494 //purpose  : 
495 //=======================================================================
496
497 void ShapeFix_EdgeProjAux::Init3d (const Standard_Real preci) 
498 {
499   Standard_Real cl, cf;
500
501   // Extract Geometries
502   Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
503   Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
504   if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99:  ec_turbine-A.stp, #4313
505   TopoDS_Vertex V1,V2;
506
507   V1 = TopExp::FirstVertex(myEdge);
508   V2 = TopExp::LastVertex(myEdge);
509   gp_Pnt Pt1 = BRep_Tool::Pnt(V1);
510   gp_Pnt Pt2 = BRep_Tool::Pnt(V2);
511
512
513   GeomAdaptor_Surface          SA     = GeomAdaptor_Surface(theSurface);  
514   Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
515
516   Geom2dAdaptor_Curve          CA     = Geom2dAdaptor_Curve(theCurve2d);
517   Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
518
519   Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
520   
521 //:S4136  Standard_Real preci = BRepAPI::Precision();
522   Standard_Real Uinf = theCurve2d->FirstParameter();
523   Standard_Real Usup = theCurve2d->LastParameter();
524
525   // ----------------------------------------------
526   // --- topological limit == geometric limit ? ---
527   // ----------------------------------------------
528   
529   if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
530     
531     gp_Pnt Pdeb = COnS.Value(Uinf);
532     gp_Pnt Pfin = COnS.Value(Usup);
533     
534     //szv#4:S4163:12Mar99 optimized
535     if ( Pdeb.IsEqual(Pt1, preci) && Pfin.IsEqual(Pt2, preci) ) {
536       myFirstParam = Uinf;
537       myLastParam  = Usup;
538       myFirstDone = myLastDone = Standard_True;
539       return;
540     }
541   }
542
543   // ------------------------------------------
544   // --- The CurveOnSurface is not infinite ---
545   // ---          Try with Extrema          ---
546   // ------------------------------------------
547
548   Standard_Real w1 = COnS.FirstParameter();
549   Standard_Real w2 = COnS.LastParameter();
550
551   if ((!Precision::IsInfinite(w1) &&
552        !Precision::IsInfinite(w2) &&
553        theCurve2d->Continuity() != GeomAbs_C0) ||
554       IsIso(theCurve2d))  {
555
556     //szv#4:S4163:12Mar99 optimized
557     if ( FindParameterWithExt(Pt1, COnS, Uinf, Usup, preci, w1) &&
558          FindParameterWithExt(Pt2, COnS, Uinf, Usup, preci, w2) ) {
559       myFirstParam = w1;
560       myLastParam  = w2;
561       UpdateParam2d(theCurve2d);
562       myFirstDone = myLastDone = Standard_True;
563       return;
564     }
565   }
566   myFirstDone = myLastDone = Standard_True;
567 }
568
569 //=======================================================================
570 //function : UpdateParam2d
571 //purpose  : 
572 //=======================================================================
573
574 void ShapeFix_EdgeProjAux::UpdateParam2d (const Handle(Geom2d_Curve)& theCurve2d)
575 {
576   if (myFirstParam < myLastParam)  return;
577
578   Standard_Real cf = theCurve2d->FirstParameter();
579   Standard_Real cl = theCurve2d->LastParameter();
580 //:S4136  Standard_Real preci = BRepAPI::Precision();
581   Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(preci, 0.01);
582
583   // 15.11.2002 PTV OCC966
584   if (ShapeAnalysis_Curve::IsPeriodic(theCurve2d)) {
585     ElCLib::AdjustPeriodic(cf,cl,preci2d,myFirstParam,myLastParam);
586   }
587   else if (theCurve2d->IsClosed()) {
588     //szv#4:S4163:12Mar99 optimized
589     if      ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
590     else if ( Abs ( myLastParam  - cf ) <= preci2d ) myLastParam  = cl;
591     else {
592 #ifdef OCCT_DEBUG
593       std::cout << "Error : curve 2d range crossing non periodic curve origin";
594       std::cout <<  std::endl;
595 #endif
596       // add fail result;
597       return;
598     }
599   }
600   // the curve is closed within the 'file' 2D tolerance 
601   else if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
602     Handle(Geom2d_BSplineCurve) aBSpline2d =
603       Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
604     if (aBSpline2d->StartPoint().Distance(aBSpline2d->EndPoint()) <= preci2d) {
605       if      ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
606       else if ( Abs ( myLastParam  - cf ) <= preci2d ) myLastParam  = cl;
607     }
608   }
609   else {
610 #ifdef OCCT_DEBUG
611     std::cout << "Warning : non increasing parameters for 2d curve." << std::endl;
612     std::cout << "          update parameter 2d uncertain." << std::endl;
613 #endif
614     Standard_Real tmp1 = myFirstParam, tmp2 = myLastParam;
615     myFirstParam = theCurve2d->ReversedParameter(tmp1);
616     myLastParam = theCurve2d->ReversedParameter(tmp2);
617     theCurve2d->Reverse();
618     //std::cout<<"Reversed case 2"<<std::endl;
619   }
620 }