49b5f0483e5a26a4ac7284276e65f5d7e2a8c866
[occt.git] / src / AppParCurves / AppParCurves_Variational_5.gxx
1 // Created on: 1998-12-10
2 // Created by: Igor FEOKTISTOV
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <SortTools_ShellSortOfReal.hxx>
18 #include <TCollection_CompareOfReal.hxx>
19 #include <PLib_Base.hxx>
20
21 //----------------------------------------------------------//
22 // Standard_Integer NearIndex                               //
23 // Purpose: searching nearest index of TabPar corresponding //
24 // given value T (is similar to fortran routine MSRRE2)     //
25 //----------------------------------------------------------//
26
27 static Standard_Integer NearIndex(const Standard_Real T, 
28                                   const TColStd_Array1OfReal& TabPar,
29                                   const Standard_Real Eps, Standard_Integer& Flag)
30 {
31   Standard_Integer Loi = TabPar.Lower(), Upi = TabPar.Upper();
32
33   Flag = 0;
34
35   if(T < TabPar(Loi)) { Flag = -1; return Loi;}
36   if(T > TabPar(Upi)) { Flag =  1; return Upi;}
37
38   Standard_Integer Ibeg = Loi, Ifin = Upi, Imidl;
39
40   while(Ibeg + 1 != Ifin) {
41     Imidl = (Ibeg + Ifin) / 2;
42     if((T >= TabPar(Ibeg)) && (T <= TabPar(Imidl)))
43       Ifin = Imidl;
44     else
45       Ibeg = Imidl;
46   }
47
48   if(Abs(T - TabPar(Ifin)) < Eps) return Ifin;
49
50   return Ibeg;
51 }
52
53
54 //----------------------------------------------------------//
55 // void GettingKnots                                        //
56 // Purpose: calculating values of new Knots for elements    //
57 // with degree that is equal Deg                            //
58 //----------------------------------------------------------//
59
60 static void GettingKnots(const TColStd_Array1OfReal& TabPar, 
61                          const Handle(FEmTool_Curve)& InCurve,
62                          const Standard_Integer Deg,
63                          Standard_Integer& NbElm,
64                          TColStd_Array1OfReal& NewKnots)
65
66 {
67
68   const Standard_Real Eps = 1.e-12;
69
70   TColStd_Array1OfReal& OldKnots = InCurve->Knots();
71   Standard_Integer NbMaxOld = InCurve->NbElements(); 
72   Standard_Integer NbMax = NewKnots.Upper(), Ipt, Ipt1, Ipt2; 
73   Standard_Integer el = 0, i1 = OldKnots.Lower(), i0 = i1 - 1, Flag;
74   Standard_Real TPar;
75   
76   while((NbElm < NbMax) && (el < NbMaxOld)) {
77
78     el++; i0++; i1++; // i0, i1 are indexes of left and right knots of element el
79
80     if(InCurve->Degree(el) == Deg) {
81
82       NbElm++;
83
84       Ipt1 = NearIndex(OldKnots(i0), TabPar, Eps, Flag);
85       if(Flag != 0) Ipt1 = TabPar.Lower();
86       Ipt2 = NearIndex(OldKnots(i1), TabPar, Eps, Flag);
87       if(Flag != 0) Ipt2 = TabPar.Upper();
88
89       if(Ipt2 - Ipt1 >= 1) {
90         
91         Ipt = (Ipt1 + Ipt2) / 2;
92         if(2 * Ipt == Ipt1 + Ipt2)
93           TPar = 2. * TabPar(Ipt);
94         else
95           TPar = TabPar(Ipt) + TabPar(Ipt + 1);
96
97         NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1) + TPar) / 4.;
98       }
99       else
100         NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1)) / 2.;
101     }
102   }
103 }
104
105 void AppParCurves_Variational::SplitCurve(const Handle(FEmTool_Curve)& InCurve,
106                                           const TColStd_Array1OfReal& Ti,
107                                           const Standard_Real CurveTol,
108                                           Handle(FEmTool_Curve)& OutCurve,
109                                           Standard_Boolean& iscut) const
110 {
111   Standard_Integer NbElmOld = InCurve->NbElements(); 
112
113   if(NbElmOld >= myMaxSegment) {iscut = Standard_False; return;}
114 #ifdef DEB
115   Standard_Integer MaxDegree = 
116 #endif
117     InCurve->Base()->WorkDegree();
118   Standard_Integer NbElm = NbElmOld;
119   TColStd_Array1OfReal NewKnots(NbElm + 1, myMaxSegment);
120 #ifndef DEB 
121   GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree(), NbElm, NewKnots);
122   GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree() - 1, NbElm, NewKnots);
123 #else
124   GettingKnots(Ti, InCurve, MaxDegree, NbElm, NewKnots);
125   GettingKnots(Ti, InCurve, MaxDegree - 1, NbElm, NewKnots);
126
127 #endif
128   if(NbElm > NbElmOld) {
129     
130     iscut = Standard_True;
131
132     OutCurve = new FEmTool_Curve(InCurve->Dimension(), NbElm, InCurve->Base(), CurveTol); 
133     TColStd_Array1OfReal& OutKnots = OutCurve->Knots();
134     TColStd_Array1OfReal& InKnots = InCurve->Knots();
135   
136     Standard_Integer i, i0 = OutKnots.Lower();
137     for(i = InKnots.Lower(); i <= InKnots.Upper(); i++) OutKnots(i) = InKnots(i);
138     for(i = NbElmOld + 1; i <= NbElm; i++) OutKnots(i + i0) = NewKnots(i);
139
140 //    SortTools_ShellSortOfReal Sort;
141     TCollection_CompareOfReal CompReal;
142
143 //    Sort.Sort(OutKnots, CompReal);
144     SortTools_ShellSortOfReal::Sort(OutKnots, CompReal);
145   }
146   else
147     iscut = Standard_False;
148   
149 }
150
151
152