0024428: Implementation of LGPL license
[occt.git] / src / Approx / Approx_ComputeCSurface.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <Precision.hxx>
16 #include <TColStd_Array2OfReal.hxx>
17
18
19 Approx_ComputeCSurface::Approx_ComputeCSurface(
20                           const Surface&                Surf,
21                           const Standard_Integer        degreemin,
22                           const Standard_Integer        degreemax,
23                           const Standard_Real           Tolerance3d,
24                           const AppParCurves_Constraint FirstCons,
25                           const AppParCurves_Constraint LastUCons,
26                           const AppParCurves_Constraint LastVCons,
27                           const AppParCurves_Constraint LastCons,
28                           const Standard_Boolean        cutting)
29 {
30   mydegremin = degreemin;
31   mydegremax = degreemax;
32   mytol3d = Tolerance3d;
33   myfirstUCons  = FirstCons;
34   mylastUCons   = LastUCons;
35   mylastVCons   = LastVCons;
36   mylastCons    = LastCons;
37   mycut = cutting;
38   
39   Perform(Surf);
40 }
41
42
43
44 Approx_ComputeCSurface::Approx_ComputeCSurface(
45                           const Standard_Integer        degreemin,
46                           const Standard_Integer        degreemax,
47                           const Standard_Real           Tolerance3d,
48                           const AppParCurves_Constraint FirstCons,
49                           const AppParCurves_Constraint LastUCons,
50                           const AppParCurves_Constraint LastVCons,
51                           const AppParCurves_Constraint LastCons,
52                           const Standard_Boolean        cutting)
53 {
54   mydegremin = degreemin;
55   mydegremax = degreemax;
56   mytol3d = Tolerance3d;
57   myfirstUCons  = FirstCons;
58   mylastUCons   = LastUCons;
59   mylastVCons   = LastVCons;
60   mylastCons    = LastCons;
61   mycut = cutting;
62 }
63
64
65
66 void Approx_ComputeCSurface::Perform(const Surface& Surf) 
67 {
68   Standard_Real UFirst, ULast, VFirst, VLast;
69   UFirst = SurfaceTool::FirstUParameter(Surf);
70   ULast  = SurfaceTool::LastUParameter(Surf);
71   VFirst = SurfaceTool::FirstVParameter(Surf);
72   VLast  = SurfaceTool::LastVParameter(Surf);
73   Standard_Boolean Finish = Standard_False, 
74           begin = Standard_True, Ok = Standard_False;
75   Standard_Real thetol3d;
76   Standard_Real myfirstU = UFirst, mylastU = ULast;
77   Standard_Real myfirstV = VFirst, mylastV = VLast;
78   Standard_Integer i;
79
80   TColStd_Array2OfReal Error(1, 50, 1, 50);   // pour l instant
81
82   if (!mycut) {
83     alldone = Compute(Surf, UFirst, ULast, VFirst, VLast, thetol3d);
84     if (!alldone) {
85       tolreached = Standard_False;
86       mySurfaces.Append(TheSurface);
87       Tolers3d.Append(thetol3d);
88       myfirstUparam.Append(UFirst);
89       mylastUparam.Append(ULast);
90       myfirstVparam.Append(VFirst);
91       mylastVparam.Append(VLast);
92     }
93   }
94
95   else {  // gestion du decoupage:
96     TColStd_SequenceOfReal TheU, TheV;
97     TheU.Append(UFirst);
98     TheU.Append(ULast);
99     TheV.Append(VFirst);
100     TheV.Append(VLast);
101
102     while (!Finish) {
103       
104       Ok = Compute(Surf, myfirstU, mylastU, myfirstV, mylastV, thetol3d);
105       if (Ok) {
106         if (Abs(ULast-mylastU) <= Precision::PConfusion() &&
107             Abs(VLast-mylastV) <= Precision::PConfusion()) {
108           Finish = Standard_True;
109           alldone = Standard_True;
110           return;
111         }
112         myfirstU = mylastU;
113         mylastU = ULast;
114       }
115       else {
116         // choix du decoupage en u ou en v:
117         // si debut, en u:
118         if (begin) {
119           begin = Standard_False;
120           mylastU = (myfirstU + mylastU)/2.;
121           TheU.InsertAfter(1, mylastU);
122           Error.SetValue(1, 1, currenttol3d);
123         }
124         else {
125           Standard_Real tolu, tolv;
126           for (i = 1; i <= TheU.Length(); i++) {
127             
128           }
129
130         }
131
132
133       }
134       
135       
136     }      
137
138   }
139
140 }
141
142
143
144 Standard_Boolean Approx_ComputeCSurface::Compute(const Surface&      Surf,
145                                                  const Standard_Real Ufirst,
146                                                  const Standard_Real Ulast,
147                                                  const Standard_Real Vfirst,
148                                                  const Standard_Real Vlast,
149                                                  Standard_Real&      TheTol3d) 
150
151 {
152   Standard_Integer NbPoints = 12;     // 12 * 12 sur la surface.
153   Standard_Integer degu, degv;
154   Standard_Real Fv;
155
156   for (degu = mydegremin; degu <= mydegremax; degu++) {
157     for (degv = mydegremin; degv <= mydegremax; degv++) {
158       Approx_MySLeastSquare LSQ(Surf, Ufirst, Ulast, Vfirst, Vlast,
159                                 myfirstUCons, mylastUCons, 
160                                 mylastVCons, mylastCons,
161                                 degu, degv, NbPoints);
162       LSQ.Error(Fv, TheTol3d);
163       if (TheTol3d <= mytol3d) {
164         TheSurface = LSQ.Value();
165         mySurfaces.Append(TheSurface);
166         tolreached = Standard_True;
167         Tolers3d.Append(TheTol3d);
168         currenttol3d = TheTol3d;
169         myfirstUparam.Append(Ufirst);
170         mylastUparam.Append(Ulast);
171         myfirstVparam.Append(Vfirst);
172         mylastVparam.Append(Vlast);
173         return Standard_True;
174       }
175       
176       if (degu == mydegremax && degv == mydegremax) {
177         TheSurface = LSQ.Value();
178         tolreached = Standard_False;
179         currenttol3d = TheTol3d;
180       }
181     }
182   }
183   return Standard_False;
184 }
185
186
187
188 Standard_Real Approx_ComputeCSurface::Error(const Standard_Integer Index)const
189 {
190   return Tolers3d.Value(Index);
191 }
192                                    
193
194
195 Handle(Geom_BezierSurface) Approx_ComputeCSurface::Value(const Standard_Integer Index)const
196 {
197   return Handle(Geom_BezierSurface)::DownCast(mySurfaces.Value(Index));
198 }
199
200
201 Standard_Integer Approx_ComputeCSurface::NbSurfaces() const
202 {
203   return mySurfaces.Length();
204 }
205
206
207 void Approx_ComputeCSurface::Parameters(const Standard_Integer Index,
208                                         Standard_Real& firstU,
209                                         Standard_Real& lastU,
210                                         Standard_Real& firstV,
211                                         Standard_Real& lastV)const
212 {
213   firstU = myfirstUparam.Value(Index);
214   lastU = mylastUparam.Value(Index);
215   firstV = myfirstVparam.Value(Index);
216   lastV = mylastVparam.Value(Index);
217 }
218
219
220 Standard_Boolean Approx_ComputeCSurface::IsToleranceReached() const
221 {
222   return tolreached;
223 }
224
225 Standard_Boolean Approx_ComputeCSurface::IsAllApproximated() const
226 {
227   return alldone;
228 }
229
230
231 void Approx_ComputeCSurface::SetDegrees(const Standard_Integer degreemin,
232                                         const Standard_Integer degreemax)
233 {
234   mydegremin = degreemin;
235   mydegremax = degreemax;
236 }
237
238
239
240 void Approx_ComputeCSurface::SetTolerance(const Standard_Real Tolerance3d)
241 {
242   mytol3d = Tolerance3d;
243 }
244
245