0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / Convert / Convert_GridPolynomialToPoles.cxx
CommitLineData
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
29Convert_GridPolynomialToPoles::
30Convert_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
75Convert_GridPolynomialToPoles::
76Convert_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
136void 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
247void 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
289Standard_Integer Convert_GridPolynomialToPoles::NbUPoles() const
290{
291 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
292 return myPoles->ColLength();
293}
294
295Standard_Integer Convert_GridPolynomialToPoles::NbVPoles() const
296{
297 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
298 return myPoles->RowLength();
299}
300
301
302const Handle(TColgp_HArray2OfPnt)&
303Convert_GridPolynomialToPoles::Poles() const
304{
305 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
306 return myPoles;
307}
308
309Standard_Integer Convert_GridPolynomialToPoles::UDegree() const
310{
311 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
312 return myUDegree;
313}
314
315Standard_Integer Convert_GridPolynomialToPoles::VDegree() const
316{
317 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
318 return myVDegree;
319}
320
321Standard_Integer Convert_GridPolynomialToPoles::NbUKnots() const
322{
323 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
324 return myUKnots->Length();
325}
326
327Standard_Integer Convert_GridPolynomialToPoles::NbVKnots() const
328{
329 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
330 return myVKnots->Length();
331}
332
333const Handle(TColStd_HArray1OfReal)&
334Convert_GridPolynomialToPoles::UKnots() const
335{
336 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
337 return myUKnots;
338}
339
340const Handle(TColStd_HArray1OfReal)&
341Convert_GridPolynomialToPoles::VKnots() const
342{
343 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
344 return myVKnots;
345}
346
347const Handle(TColStd_HArray1OfInteger)&
348Convert_GridPolynomialToPoles::UMultiplicities() const
349{
350 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
351 return myUMults;
352}
353
354const Handle(TColStd_HArray1OfInteger)&
355Convert_GridPolynomialToPoles::VMultiplicities() const
356{
357 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
358 return myVMults;
359}
360
361Standard_Boolean Convert_GridPolynomialToPoles::IsDone() const
362{
363 return myDone;
364}