b311480e |
1 | // Created on: 1996-07-08 |
2 | // Created by: Philippe MANGIN |
3 | // Copyright (c) 1996-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // Modified: Fri Oct 3 14:58:05 1997 |
18 | // by: Joelle CHAUVET |
19 | // Condition d'extraction corrigee |
20 | // + positionnement par EvalPoly2Var |
21 | |
7fd59977 |
22 | #include <BSplCLib.hxx> |
42cf5bc1 |
23 | #include <BSplSLib.hxx> |
24 | #include <Convert_GridPolynomialToPoles.hxx> |
25 | #include <PLib.hxx> |
26 | #include <Standard_DomainError.hxx> |
27 | #include <StdFail_NotDone.hxx> |
7fd59977 |
28 | |
29 | Convert_GridPolynomialToPoles:: |
30 | Convert_GridPolynomialToPoles( |
31 | const Standard_Integer MaxUDegree, |
32 | const Standard_Integer MaxVDegree, |
33 | const Handle(TColStd_HArray1OfInteger)& NumCoeffPerSurface, |
34 | const Handle(TColStd_HArray1OfReal)& Coefficients, |
35 | const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals, |
36 | const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals) : |
37 | myDone(Standard_False) |
38 | { |
39 | // Les Controles |
40 | if ((NumCoeffPerSurface->Lower()!=1 ) || |
41 | (NumCoeffPerSurface->Upper()!= 2) ) |
42 | { |
9775fa61 |
43 | throw Standard_DomainError("Convert : Wrong Coefficients"); |
7fd59977 |
44 | } |
45 | if ((Coefficients->Lower()!=1 ) || |
46 | (Coefficients->Upper()!= 3*(MaxUDegree+1)*(MaxVDegree+1))) |
47 | { |
9775fa61 |
48 | throw Standard_DomainError("Convert : Wrong Coefficients"); |
7fd59977 |
49 | } |
50 | |
51 | // Les Degres |
52 | myUDegree = NumCoeffPerSurface->Value(1)-1; |
53 | myVDegree = NumCoeffPerSurface->Value(2)-1; |
54 | |
55 | if (myUDegree > MaxUDegree) |
9775fa61 |
56 | throw Standard_DomainError("Convert : Incoherence beetween NumCoeffPerSurface and MaxUDegree"); |
7fd59977 |
57 | if (myVDegree > MaxVDegree) |
9775fa61 |
58 | throw Standard_DomainError("Convert : Incoherence beetween NumCoeffPerSurface and MaxVDegree"); |
7fd59977 |
59 | |
60 | Handle(TColStd_HArray2OfInteger) NumCoeff = |
61 | new (TColStd_HArray2OfInteger)(1, 1, 1, 2); |
62 | NumCoeff->SetValue(1, 1, NumCoeffPerSurface->Value(1)); |
63 | NumCoeff->SetValue(1, 2, NumCoeffPerSurface->Value(2)); |
64 | |
65 | Perform (0, 0, |
66 | MaxUDegree, MaxVDegree, |
67 | NumCoeff, |
68 | Coefficients, |
69 | PolynomialUIntervals, |
70 | PolynomialVIntervals, |
71 | PolynomialUIntervals, |
72 | PolynomialVIntervals); |
73 | } |
74 | |
75 | Convert_GridPolynomialToPoles:: |
76 | Convert_GridPolynomialToPoles( |
77 | const Standard_Integer NbUSurfaces, |
78 | const Standard_Integer NbVSurfaces, |
79 | const Standard_Integer UContinuity, |
80 | const Standard_Integer VContinuity, |
81 | const Standard_Integer MaxUDegree, |
82 | const Standard_Integer MaxVDegree, |
83 | const Handle(TColStd_HArray2OfInteger)& NumCoeffPerSurface, |
84 | const Handle(TColStd_HArray1OfReal)& Coefficients, |
85 | const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals, |
86 | const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals, |
87 | const Handle(TColStd_HArray1OfReal)& TrueUIntervals, |
88 | const Handle(TColStd_HArray1OfReal)& TrueVIntervals) : |
89 | myDone(Standard_False) |
90 | { |
91 | Standard_Integer ii; |
92 | Standard_Integer RealUDegree = Max(MaxUDegree, 2*UContinuity + 1); |
93 | Standard_Integer RealVDegree = Max(MaxVDegree, 2*VContinuity + 1); |
94 | myUDegree = 0; |
95 | myVDegree = 0; |
96 | |
97 | // Les controles |
98 | if((NumCoeffPerSurface->LowerRow()!=1) || |
99 | (NumCoeffPerSurface->UpperRow()!=NbUSurfaces*NbVSurfaces) || |
100 | (NumCoeffPerSurface->LowerCol()!=1) || |
101 | (NumCoeffPerSurface->UpperCol()!=2) ) |
102 | { |
9775fa61 |
103 | throw Standard_DomainError("Convert : Wrong NumCoeffPerSurface"); |
7fd59977 |
104 | } |
105 | |
106 | if ((Coefficients->Lower()!=1 ) || |
107 | (Coefficients->Upper()!= 3*NbUSurfaces*NbVSurfaces* |
108 | (RealUDegree + 1) * (RealVDegree + 1)) ) |
109 | { |
9775fa61 |
110 | throw Standard_DomainError("Convert : Wrong Coefficients"); |
7fd59977 |
111 | } |
112 | |
113 | // Calcul des degree |
114 | for (ii=1; ii<=NbUSurfaces*NbVSurfaces; ii++) { |
115 | if (NumCoeffPerSurface->Value(ii,1) > myUDegree+1) |
116 | myUDegree = NumCoeffPerSurface->Value(ii,1)-1; |
117 | if (NumCoeffPerSurface->Value(ii,2) > myVDegree+1) |
118 | myVDegree = NumCoeffPerSurface->Value(ii,2)-1; |
119 | } |
120 | |
121 | if (myUDegree > RealUDegree) |
9775fa61 |
122 | throw Standard_DomainError("Convert : Incoherence beetween NumCoeffPerSurface and MaxUDegree"); |
7fd59977 |
123 | if (myVDegree > RealVDegree) |
9775fa61 |
124 | throw Standard_DomainError("Convert : Incoherence beetween NumCoeffPerSurface and MaxVDegree"); |
7fd59977 |
125 | |
126 | Perform (UContinuity, VContinuity, |
127 | RealUDegree, RealVDegree, |
128 | NumCoeffPerSurface, |
129 | Coefficients, |
130 | PolynomialUIntervals, |
131 | PolynomialVIntervals, |
132 | TrueUIntervals, |
133 | TrueVIntervals); |
134 | } |
135 | |
136 | void Convert_GridPolynomialToPoles::Perform(const Standard_Integer UContinuity, |
137 | const Standard_Integer VContinuity, |
138 | const Standard_Integer MaxUDegree, |
139 | const Standard_Integer MaxVDegree, |
140 | const Handle(TColStd_HArray2OfInteger)& NumCoeffPerSurface, |
141 | const Handle(TColStd_HArray1OfReal)& Coefficients, |
142 | const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals, |
143 | const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals, |
144 | const Handle(TColStd_HArray1OfReal)& TrueUIntervals, |
145 | const Handle(TColStd_HArray1OfReal)& TrueVIntervals) |
146 | { |
147 | // (1) Construction des Tables monodimensionnelles ---------------------------- |
148 | Handle(TColStd_HArray1OfReal) UParameters, VParameters; |
149 | myUKnots = new (TColStd_HArray1OfReal) (1, TrueUIntervals->Length()); |
150 | myUKnots->ChangeArray1() = TrueUIntervals->Array1(); |
151 | myVKnots = new (TColStd_HArray1OfReal) (1, TrueVIntervals->Length()); |
152 | myVKnots->ChangeArray1() = TrueVIntervals->Array1(); |
153 | |
154 | BuildArray( myUDegree, |
155 | myUKnots, |
156 | UContinuity, |
157 | myUFlatKnots, |
158 | myUMults, |
159 | UParameters); |
160 | |
161 | BuildArray( myVDegree, |
162 | myVKnots, |
163 | VContinuity, |
164 | myVFlatKnots, |
165 | myVMults, |
166 | VParameters); |
167 | |
168 | // (2) Digitalisation ------------------------------------------------------- |
169 | |
170 | Standard_Integer ii, jj, Uindex=0, Vindex=0; |
171 | Standard_Integer Patch_Indice=0; |
172 | Standard_Real NValue, UValue, VValue; |
173 | Standard_Integer dimension = 3*( myVDegree+1); |
174 | Standard_Integer SizPatch = 3 * (MaxUDegree+1) * (MaxVDegree+1); |
175 | myPoles = new (TColgp_HArray2OfPnt) (1, UParameters->Length(), |
176 | 1, VParameters->Length()); |
177 | |
178 | TColStd_Array1OfReal Patch(1, (myUDegree+1)*dimension); |
179 | TColStd_Array1OfReal Point(1, 3); |
180 | Standard_Real * Coeffs = (Standard_Real *) &Patch.ChangeValue(1); |
181 | Standard_Real * Digit = (Standard_Real *) &Point.ChangeValue(1); |
182 | |
183 | for (ii=1, Uindex=1; ii<=UParameters->Length(); ii++) { |
184 | |
185 | while (UParameters->Value(ii) > TrueUIntervals->Value(Uindex+1) |
186 | && Uindex < myUKnots->Length()-1) { Uindex++; } |
187 | |
188 | NValue = (UParameters->Value(ii) - TrueUIntervals->Value(Uindex) ) |
189 | / (TrueUIntervals->Value(Uindex+1) - TrueUIntervals->Value(Uindex)); |
190 | UValue = (1-NValue) * PolynomialUIntervals->Value(1) |
191 | + NValue * PolynomialUIntervals->Value(2) ; |
192 | |
193 | for (jj=1, Vindex=1; jj<=VParameters->Length(); jj++) { |
194 | |
195 | while (VParameters->Value(jj) > TrueVIntervals->Value(Vindex+1) |
196 | && Vindex < myVKnots->Length()-1) { Vindex++; } |
197 | |
198 | NValue = (VParameters->Value(jj) - TrueVIntervals->Value(Vindex) ) |
199 | / (TrueVIntervals->Value(Vindex+1) - TrueVIntervals->Value(Vindex)); |
200 | VValue = (1-NValue) * PolynomialVIntervals->Value(1) |
201 | + NValue * PolynomialVIntervals->Value(2) ; |
202 | |
203 | // (2.1) Extraction du bon Patch |
204 | if (Patch_Indice != Uindex + (myUKnots->Length()-1)*(Vindex-1)) { |
205 | Standard_Integer k1, k2, pos, ll=1; |
206 | Patch_Indice = Uindex + (myUKnots->Length()-1)*(Vindex-1); |
207 | for (k1 = 1; k1 <= NumCoeffPerSurface->Value(Patch_Indice, 1); k1++) { |
208 | pos = SizPatch*(Patch_Indice-1)+3*(MaxVDegree+1)*(k1-1)+1; |
209 | for (k2 = 1; |
210 | k2 <= NumCoeffPerSurface->Value(Patch_Indice, 2); |
211 | k2++, pos+=3 ) { |
212 | Patch(ll) = Coefficients->Value(pos); |
213 | Patch(ll+1) = Coefficients->Value(pos+1); |
214 | Patch(ll+2) = Coefficients->Value(pos+2); |
215 | ll += 3; |
216 | } |
217 | } |
218 | } |
219 | |
220 | // (2.2) Positionnement en UValue,VValue |
221 | PLib::EvalPoly2Var(UValue,VValue,0,0, |
222 | NumCoeffPerSurface->Value(Patch_Indice,1)-1, |
223 | NumCoeffPerSurface->Value(Patch_Indice,2)-1, |
224 | 3, |
225 | Coeffs[0], |
226 | Digit[0]); |
227 | |
228 | myPoles->SetValue(ii, jj, gp_Pnt (Digit[0], Digit[1], Digit[2])); |
229 | } |
230 | } |
231 | |
232 | |
233 | // (3)Interpolation -------------------------------------------------------------- |
234 | |
235 | Standard_Integer InversionProblem; |
236 | BSplSLib::Interpolate(myUDegree, myVDegree, |
237 | myUFlatKnots->Array1(), |
238 | myVFlatKnots->Array1(), |
239 | UParameters->Array1(), |
240 | VParameters->Array1(), |
241 | myPoles->ChangeArray2(), |
242 | InversionProblem); |
243 | myDone = (InversionProblem == 0); |
244 | } |
245 | |
246 | |
247 | void Convert_GridPolynomialToPoles::BuildArray(const Standard_Integer Degree, |
248 | const Handle(TColStd_HArray1OfReal)& Knots, |
249 | const Standard_Integer Continuity, |
250 | Handle(TColStd_HArray1OfReal)& FlatKnots, |
251 | Handle(TColStd_HArray1OfInteger)& Mults, |
252 | Handle(TColStd_HArray1OfReal)& Parameters) const |
253 | { |
254 | Standard_Integer NumCurves = Knots->Length()-1; |
255 | |
256 | // Calcul des Multiplicites |
257 | Standard_Integer ii; |
258 | Standard_Integer multiplicities = Degree - Continuity; |
259 | Mults = new (TColStd_HArray1OfInteger)(1, Knots->Length()); |
260 | |
261 | for (ii = 2 ; ii < Knots->Length() ; ii++) { |
262 | Mults ->SetValue(ii,multiplicities) ; |
263 | } |
264 | Mults ->SetValue(1, Degree + 1) ; |
265 | Mults ->SetValue(NumCurves + 1, Degree + 1) ; |
266 | |
267 | // Calcul des Noeuds Plats |
268 | Standard_Integer num_flat_knots = multiplicities * (NumCurves - 1) |
269 | + 2 * Degree + 2; |
270 | FlatKnots = |
271 | new TColStd_HArray1OfReal(1,num_flat_knots) ; |
272 | |
273 | BSplCLib::KnotSequence (Knots->Array1(), |
274 | Mults->Array1(), |
275 | Degree, |
276 | Standard_False, |
277 | FlatKnots->ChangeArray1()); |
278 | |
279 | // Calcul du nombre de Poles |
280 | Standard_Integer num_poles = num_flat_knots - Degree - 1; |
281 | |
282 | // Cacul des parametres d'interpolation |
283 | Parameters = new (TColStd_HArray1OfReal) (1,num_poles); |
284 | BSplCLib::BuildSchoenbergPoints(Degree, |
285 | FlatKnots->Array1(), |
286 | Parameters->ChangeArray1()); |
287 | } |
288 | |
289 | Standard_Integer Convert_GridPolynomialToPoles::NbUPoles() const |
290 | { |
291 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
292 | return myPoles->ColLength(); |
293 | } |
294 | |
295 | Standard_Integer Convert_GridPolynomialToPoles::NbVPoles() const |
296 | { |
297 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
298 | return myPoles->RowLength(); |
299 | } |
300 | |
301 | |
302 | const Handle(TColgp_HArray2OfPnt)& |
303 | Convert_GridPolynomialToPoles::Poles() const |
304 | { |
305 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
306 | return myPoles; |
307 | } |
308 | |
309 | Standard_Integer Convert_GridPolynomialToPoles::UDegree() const |
310 | { |
311 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
312 | return myUDegree; |
313 | } |
314 | |
315 | Standard_Integer Convert_GridPolynomialToPoles::VDegree() const |
316 | { |
317 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
318 | return myVDegree; |
319 | } |
320 | |
321 | Standard_Integer Convert_GridPolynomialToPoles::NbUKnots() const |
322 | { |
323 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
324 | return myUKnots->Length(); |
325 | } |
326 | |
327 | Standard_Integer Convert_GridPolynomialToPoles::NbVKnots() const |
328 | { |
329 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
330 | return myVKnots->Length(); |
331 | } |
332 | |
333 | const Handle(TColStd_HArray1OfReal)& |
334 | Convert_GridPolynomialToPoles::UKnots() const |
335 | { |
336 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
337 | return myUKnots; |
338 | } |
339 | |
340 | const Handle(TColStd_HArray1OfReal)& |
341 | Convert_GridPolynomialToPoles::VKnots() const |
342 | { |
343 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
344 | return myVKnots; |
345 | } |
346 | |
347 | const Handle(TColStd_HArray1OfInteger)& |
348 | Convert_GridPolynomialToPoles::UMultiplicities() const |
349 | { |
350 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
351 | return myUMults; |
352 | } |
353 | |
354 | const Handle(TColStd_HArray1OfInteger)& |
355 | Convert_GridPolynomialToPoles::VMultiplicities() const |
356 | { |
357 | StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles"); |
358 | return myVMults; |
359 | } |
360 | |
361 | Standard_Boolean Convert_GridPolynomialToPoles::IsDone() const |
362 | { |
363 | return myDone; |
364 | } |