578dfdd740251432a9283bd80d347b273d011bb9
[occt.git] / src / Approx / Approx_ComputeCSurface.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <Precision.hxx>
20 #include <TColStd_Array2OfReal.hxx>
21
22
23 Approx_ComputeCSurface::Approx_ComputeCSurface(
24                           const Surface&                Surf,
25                           const Standard_Integer        degreemin,
26                           const Standard_Integer        degreemax,
27                           const Standard_Real           Tolerance3d,
28                           const AppParCurves_Constraint FirstCons,
29                           const AppParCurves_Constraint LastUCons,
30                           const AppParCurves_Constraint LastVCons,
31                           const AppParCurves_Constraint LastCons,
32                           const Standard_Boolean        cutting)
33 {
34   mydegremin = degreemin;
35   mydegremax = degreemax;
36   mytol3d = Tolerance3d;
37   myfirstUCons  = FirstCons;
38   mylastUCons   = LastUCons;
39   mylastVCons   = LastVCons;
40   mylastCons    = LastCons;
41   mycut = cutting;
42   
43   Perform(Surf);
44 }
45
46
47
48 Approx_ComputeCSurface::Approx_ComputeCSurface(
49                           const Standard_Integer        degreemin,
50                           const Standard_Integer        degreemax,
51                           const Standard_Real           Tolerance3d,
52                           const AppParCurves_Constraint FirstCons,
53                           const AppParCurves_Constraint LastUCons,
54                           const AppParCurves_Constraint LastVCons,
55                           const AppParCurves_Constraint LastCons,
56                           const Standard_Boolean        cutting)
57 {
58   mydegremin = degreemin;
59   mydegremax = degreemax;
60   mytol3d = Tolerance3d;
61   myfirstUCons  = FirstCons;
62   mylastUCons   = LastUCons;
63   mylastVCons   = LastVCons;
64   mylastCons    = LastCons;
65   mycut = cutting;
66 }
67
68
69
70 void Approx_ComputeCSurface::Perform(const Surface& Surf) 
71 {
72   Standard_Real UFirst, ULast, VFirst, VLast;
73   UFirst = SurfaceTool::FirstUParameter(Surf);
74   ULast  = SurfaceTool::LastUParameter(Surf);
75   VFirst = SurfaceTool::FirstVParameter(Surf);
76   VLast  = SurfaceTool::LastVParameter(Surf);
77   Standard_Boolean Finish = Standard_False, 
78           begin = Standard_True, Ok = Standard_False;
79   Standard_Real thetol3d;
80   Standard_Real myfirstU = UFirst, mylastU = ULast;
81   Standard_Real myfirstV = VFirst, mylastV = VLast;
82   Standard_Integer i;
83
84   TColStd_Array2OfReal Error(1, 50, 1, 50);   // pour l instant
85
86   if (!mycut) {
87     alldone = Compute(Surf, UFirst, ULast, VFirst, VLast, thetol3d);
88     if (!alldone) {
89       tolreached = Standard_False;
90       mySurfaces.Append(TheSurface);
91       Tolers3d.Append(thetol3d);
92       myfirstUparam.Append(UFirst);
93       mylastUparam.Append(ULast);
94       myfirstVparam.Append(VFirst);
95       mylastVparam.Append(VLast);
96     }
97   }
98
99   else {  // gestion du decoupage:
100     TColStd_SequenceOfReal TheU, TheV;
101     TheU.Append(UFirst);
102     TheU.Append(ULast);
103     TheV.Append(VFirst);
104     TheV.Append(VLast);
105
106     while (!Finish) {
107       
108       Ok = Compute(Surf, myfirstU, mylastU, myfirstV, mylastV, thetol3d);
109       if (Ok) {
110         if (Abs(ULast-mylastU) <= Precision::PConfusion() &&
111             Abs(VLast-mylastV) <= Precision::PConfusion()) {
112           Finish = Standard_True;
113           alldone = Standard_True;
114           return;
115         }
116         myfirstU = mylastU;
117         mylastU = ULast;
118       }
119       else {
120         // choix du decoupage en u ou en v:
121         // si debut, en u:
122         if (begin) {
123           begin = Standard_False;
124           mylastU = (myfirstU + mylastU)/2.;
125           TheU.InsertAfter(1, mylastU);
126           Error.SetValue(1, 1, currenttol3d);
127         }
128         else {
129           Standard_Real tolu, tolv;
130           for (i = 1; i <= TheU.Length(); i++) {
131             
132           }
133
134         }
135
136
137       }
138       
139       
140     }      
141
142   }
143
144 }
145
146
147
148 Standard_Boolean Approx_ComputeCSurface::Compute(const Surface&      Surf,
149                                                  const Standard_Real Ufirst,
150                                                  const Standard_Real Ulast,
151                                                  const Standard_Real Vfirst,
152                                                  const Standard_Real Vlast,
153                                                  Standard_Real&      TheTol3d) 
154
155 {
156   Standard_Integer NbPoints = 12;     // 12 * 12 sur la surface.
157   Standard_Integer degu, degv;
158   Standard_Real Fv;
159
160   for (degu = mydegremin; degu <= mydegremax; degu++) {
161     for (degv = mydegremin; degv <= mydegremax; degv++) {
162       Approx_MySLeastSquare LSQ(Surf, Ufirst, Ulast, Vfirst, Vlast,
163                                 myfirstUCons, mylastUCons, 
164                                 mylastVCons, mylastCons,
165                                 degu, degv, NbPoints);
166       LSQ.Error(Fv, TheTol3d);
167       if (TheTol3d <= mytol3d) {
168         TheSurface = LSQ.Value();
169         mySurfaces.Append(TheSurface);
170         tolreached = Standard_True;
171         Tolers3d.Append(TheTol3d);
172         currenttol3d = TheTol3d;
173         myfirstUparam.Append(Ufirst);
174         mylastUparam.Append(Ulast);
175         myfirstVparam.Append(Vfirst);
176         mylastVparam.Append(Vlast);
177         return Standard_True;
178       }
179       
180       if (degu == mydegremax && degv == mydegremax) {
181         TheSurface = LSQ.Value();
182         tolreached = Standard_False;
183         currenttol3d = TheTol3d;
184       }
185     }
186   }
187   return Standard_False;
188 }
189
190
191
192 Standard_Real Approx_ComputeCSurface::Error(const Standard_Integer Index)const
193 {
194   return Tolers3d.Value(Index);
195 }
196                                    
197
198
199 Handle(Geom_BezierSurface) Approx_ComputeCSurface::Value(const Standard_Integer Index)const
200 {
201   return Handle(Geom_BezierSurface)::DownCast(mySurfaces.Value(Index));
202 }
203
204
205 Standard_Integer Approx_ComputeCSurface::NbSurfaces() const
206 {
207   return mySurfaces.Length();
208 }
209
210
211 void Approx_ComputeCSurface::Parameters(const Standard_Integer Index,
212                                         Standard_Real& firstU,
213                                         Standard_Real& lastU,
214                                         Standard_Real& firstV,
215                                         Standard_Real& lastV)const
216 {
217   firstU = myfirstUparam.Value(Index);
218   lastU = mylastUparam.Value(Index);
219   firstV = myfirstVparam.Value(Index);
220   lastV = mylastVparam.Value(Index);
221 }
222
223
224 Standard_Boolean Approx_ComputeCSurface::IsToleranceReached() const
225 {
226   return tolreached;
227 }
228
229 Standard_Boolean Approx_ComputeCSurface::IsAllApproximated() const
230 {
231   return alldone;
232 }
233
234
235 void Approx_ComputeCSurface::SetDegrees(const Standard_Integer degreemin,
236                                         const Standard_Integer degreemax)
237 {
238   mydegremin = degreemin;
239   mydegremax = degreemax;
240 }
241
242
243
244 void Approx_ComputeCSurface::SetTolerance(const Standard_Real Tolerance3d)
245 {
246   mytol3d = Tolerance3d;
247 }
248
249