1 // Created on: 1996-07-08
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
21 // Modified: Fri Oct 3 14:58:05 1997
23 // Condition d'extraction corrigee
24 // + positionnement par EvalPoly2Var
27 #include <Convert_GridPolynomialToPoles.ixx>
29 #include <StdFail_NotDone.hxx>
30 #include <Standard_DomainError.hxx>
32 #include <BSplSLib.hxx>
33 #include <BSplCLib.hxx>
36 Convert_GridPolynomialToPoles::
37 Convert_GridPolynomialToPoles(
38 const Standard_Integer MaxUDegree,
39 const Standard_Integer MaxVDegree,
40 const Handle(TColStd_HArray1OfInteger)& NumCoeffPerSurface,
41 const Handle(TColStd_HArray1OfReal)& Coefficients,
42 const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals,
43 const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals) :
44 myDone(Standard_False)
47 if ((NumCoeffPerSurface->Lower()!=1 ) ||
48 (NumCoeffPerSurface->Upper()!= 2) )
50 Standard_DomainError::Raise("Convert : Wrong Coefficients");
52 if ((Coefficients->Lower()!=1 ) ||
53 (Coefficients->Upper()!= 3*(MaxUDegree+1)*(MaxVDegree+1)))
55 Standard_DomainError::Raise("Convert : Wrong Coefficients");
59 myUDegree = NumCoeffPerSurface->Value(1)-1;
60 myVDegree = NumCoeffPerSurface->Value(2)-1;
62 if (myUDegree > MaxUDegree)
63 Standard_DomainError::Raise
64 ("Convert : Incoherence beetween NumCoeffPerSurface and MaxUDegree");
65 if (myVDegree > MaxVDegree)
66 Standard_DomainError::Raise
67 ("Convert : Incoherence beetween NumCoeffPerSurface and MaxVDegree");
69 Handle(TColStd_HArray2OfInteger) NumCoeff =
70 new (TColStd_HArray2OfInteger)(1, 1, 1, 2);
71 NumCoeff->SetValue(1, 1, NumCoeffPerSurface->Value(1));
72 NumCoeff->SetValue(1, 2, NumCoeffPerSurface->Value(2));
75 MaxUDegree, MaxVDegree,
81 PolynomialVIntervals);
84 Convert_GridPolynomialToPoles::
85 Convert_GridPolynomialToPoles(
86 const Standard_Integer NbUSurfaces,
87 const Standard_Integer NbVSurfaces,
88 const Standard_Integer UContinuity,
89 const Standard_Integer VContinuity,
90 const Standard_Integer MaxUDegree,
91 const Standard_Integer MaxVDegree,
92 const Handle(TColStd_HArray2OfInteger)& NumCoeffPerSurface,
93 const Handle(TColStd_HArray1OfReal)& Coefficients,
94 const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals,
95 const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals,
96 const Handle(TColStd_HArray1OfReal)& TrueUIntervals,
97 const Handle(TColStd_HArray1OfReal)& TrueVIntervals) :
98 myDone(Standard_False)
101 Standard_Integer RealUDegree = Max(MaxUDegree, 2*UContinuity + 1);
102 Standard_Integer RealVDegree = Max(MaxVDegree, 2*VContinuity + 1);
107 if((NumCoeffPerSurface->LowerRow()!=1) ||
108 (NumCoeffPerSurface->UpperRow()!=NbUSurfaces*NbVSurfaces) ||
109 (NumCoeffPerSurface->LowerCol()!=1) ||
110 (NumCoeffPerSurface->UpperCol()!=2) )
112 Standard_DomainError::Raise("Convert : Wrong NumCoeffPerSurface");
115 if ((Coefficients->Lower()!=1 ) ||
116 (Coefficients->Upper()!= 3*NbUSurfaces*NbVSurfaces*
117 (RealUDegree + 1) * (RealVDegree + 1)) )
119 Standard_DomainError::Raise("Convert : Wrong Coefficients");
123 for (ii=1; ii<=NbUSurfaces*NbVSurfaces; ii++) {
124 if (NumCoeffPerSurface->Value(ii,1) > myUDegree+1)
125 myUDegree = NumCoeffPerSurface->Value(ii,1)-1;
126 if (NumCoeffPerSurface->Value(ii,2) > myVDegree+1)
127 myVDegree = NumCoeffPerSurface->Value(ii,2)-1;
130 if (myUDegree > RealUDegree)
131 Standard_DomainError::Raise
132 ("Convert : Incoherence beetween NumCoeffPerSurface and MaxUDegree");
133 if (myVDegree > RealVDegree)
134 Standard_DomainError::Raise
135 ("Convert : Incoherence beetween NumCoeffPerSurface and MaxVDegree");
137 Perform (UContinuity, VContinuity,
138 RealUDegree, RealVDegree,
141 PolynomialUIntervals,
142 PolynomialVIntervals,
147 void Convert_GridPolynomialToPoles::Perform(const Standard_Integer UContinuity,
148 const Standard_Integer VContinuity,
149 const Standard_Integer MaxUDegree,
150 const Standard_Integer MaxVDegree,
151 const Handle(TColStd_HArray2OfInteger)& NumCoeffPerSurface,
152 const Handle(TColStd_HArray1OfReal)& Coefficients,
153 const Handle(TColStd_HArray1OfReal)& PolynomialUIntervals,
154 const Handle(TColStd_HArray1OfReal)& PolynomialVIntervals,
155 const Handle(TColStd_HArray1OfReal)& TrueUIntervals,
156 const Handle(TColStd_HArray1OfReal)& TrueVIntervals)
158 // (1) Construction des Tables monodimensionnelles ----------------------------
159 Handle(TColStd_HArray1OfReal) UParameters, VParameters;
160 myUKnots = new (TColStd_HArray1OfReal) (1, TrueUIntervals->Length());
161 myUKnots->ChangeArray1() = TrueUIntervals->Array1();
162 myVKnots = new (TColStd_HArray1OfReal) (1, TrueVIntervals->Length());
163 myVKnots->ChangeArray1() = TrueVIntervals->Array1();
165 BuildArray( myUDegree,
172 BuildArray( myVDegree,
179 // (2) Digitalisation -------------------------------------------------------
181 Standard_Integer ii, jj, Uindex=0, Vindex=0;
182 Standard_Integer Patch_Indice=0;
183 Standard_Real NValue, UValue, VValue;
184 Standard_Integer dimension = 3*( myVDegree+1);
185 Standard_Integer SizPatch = 3 * (MaxUDegree+1) * (MaxVDegree+1);
186 myPoles = new (TColgp_HArray2OfPnt) (1, UParameters->Length(),
187 1, VParameters->Length());
189 TColStd_Array1OfReal Patch(1, (myUDegree+1)*dimension);
190 TColStd_Array1OfReal Point(1, 3);
191 Standard_Real * Coeffs = (Standard_Real *) &Patch.ChangeValue(1);
192 Standard_Real * Digit = (Standard_Real *) &Point.ChangeValue(1);
194 for (ii=1, Uindex=1; ii<=UParameters->Length(); ii++) {
196 while (UParameters->Value(ii) > TrueUIntervals->Value(Uindex+1)
197 && Uindex < myUKnots->Length()-1) { Uindex++; }
199 NValue = (UParameters->Value(ii) - TrueUIntervals->Value(Uindex) )
200 / (TrueUIntervals->Value(Uindex+1) - TrueUIntervals->Value(Uindex));
201 UValue = (1-NValue) * PolynomialUIntervals->Value(1)
202 + NValue * PolynomialUIntervals->Value(2) ;
204 for (jj=1, Vindex=1; jj<=VParameters->Length(); jj++) {
206 while (VParameters->Value(jj) > TrueVIntervals->Value(Vindex+1)
207 && Vindex < myVKnots->Length()-1) { Vindex++; }
209 NValue = (VParameters->Value(jj) - TrueVIntervals->Value(Vindex) )
210 / (TrueVIntervals->Value(Vindex+1) - TrueVIntervals->Value(Vindex));
211 VValue = (1-NValue) * PolynomialVIntervals->Value(1)
212 + NValue * PolynomialVIntervals->Value(2) ;
214 // (2.1) Extraction du bon Patch
215 if (Patch_Indice != Uindex + (myUKnots->Length()-1)*(Vindex-1)) {
216 Standard_Integer k1, k2, pos, ll=1;
217 Patch_Indice = Uindex + (myUKnots->Length()-1)*(Vindex-1);
218 for (k1 = 1; k1 <= NumCoeffPerSurface->Value(Patch_Indice, 1); k1++) {
219 pos = SizPatch*(Patch_Indice-1)+3*(MaxVDegree+1)*(k1-1)+1;
221 k2 <= NumCoeffPerSurface->Value(Patch_Indice, 2);
223 Patch(ll) = Coefficients->Value(pos);
224 Patch(ll+1) = Coefficients->Value(pos+1);
225 Patch(ll+2) = Coefficients->Value(pos+2);
231 // (2.2) Positionnement en UValue,VValue
232 PLib::EvalPoly2Var(UValue,VValue,0,0,
233 NumCoeffPerSurface->Value(Patch_Indice,1)-1,
234 NumCoeffPerSurface->Value(Patch_Indice,2)-1,
239 myPoles->SetValue(ii, jj, gp_Pnt (Digit[0], Digit[1], Digit[2]));
244 // (3)Interpolation --------------------------------------------------------------
246 Standard_Integer InversionProblem;
247 BSplSLib::Interpolate(myUDegree, myVDegree,
248 myUFlatKnots->Array1(),
249 myVFlatKnots->Array1(),
250 UParameters->Array1(),
251 VParameters->Array1(),
252 myPoles->ChangeArray2(),
254 myDone = (InversionProblem == 0);
258 void Convert_GridPolynomialToPoles::BuildArray(const Standard_Integer Degree,
259 const Handle(TColStd_HArray1OfReal)& Knots,
260 const Standard_Integer Continuity,
261 Handle(TColStd_HArray1OfReal)& FlatKnots,
262 Handle(TColStd_HArray1OfInteger)& Mults,
263 Handle(TColStd_HArray1OfReal)& Parameters) const
265 Standard_Integer NumCurves = Knots->Length()-1;
267 // Calcul des Multiplicites
269 Standard_Integer multiplicities = Degree - Continuity;
270 Mults = new (TColStd_HArray1OfInteger)(1, Knots->Length());
272 for (ii = 2 ; ii < Knots->Length() ; ii++) {
273 Mults ->SetValue(ii,multiplicities) ;
275 Mults ->SetValue(1, Degree + 1) ;
276 Mults ->SetValue(NumCurves + 1, Degree + 1) ;
278 // Calcul des Noeuds Plats
279 Standard_Integer num_flat_knots = multiplicities * (NumCurves - 1)
282 new TColStd_HArray1OfReal(1,num_flat_knots) ;
284 BSplCLib::KnotSequence (Knots->Array1(),
288 FlatKnots->ChangeArray1());
290 // Calcul du nombre de Poles
291 Standard_Integer num_poles = num_flat_knots - Degree - 1;
293 // Cacul des parametres d'interpolation
294 Parameters = new (TColStd_HArray1OfReal) (1,num_poles);
295 BSplCLib::BuildSchoenbergPoints(Degree,
297 Parameters->ChangeArray1());
300 Standard_Integer Convert_GridPolynomialToPoles::NbUPoles() const
302 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
303 return myPoles->ColLength();
306 Standard_Integer Convert_GridPolynomialToPoles::NbVPoles() const
308 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
309 return myPoles->RowLength();
313 const Handle(TColgp_HArray2OfPnt)&
314 Convert_GridPolynomialToPoles::Poles() const
316 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
320 Standard_Integer Convert_GridPolynomialToPoles::UDegree() const
322 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
326 Standard_Integer Convert_GridPolynomialToPoles::VDegree() const
328 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
332 Standard_Integer Convert_GridPolynomialToPoles::NbUKnots() const
334 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
335 return myUKnots->Length();
338 Standard_Integer Convert_GridPolynomialToPoles::NbVKnots() const
340 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
341 return myVKnots->Length();
344 const Handle(TColStd_HArray1OfReal)&
345 Convert_GridPolynomialToPoles::UKnots() const
347 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
351 const Handle(TColStd_HArray1OfReal)&
352 Convert_GridPolynomialToPoles::VKnots() const
354 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
358 const Handle(TColStd_HArray1OfInteger)&
359 Convert_GridPolynomialToPoles::UMultiplicities() const
361 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
365 const Handle(TColStd_HArray1OfInteger)&
366 Convert_GridPolynomialToPoles::VMultiplicities() const
368 StdFail_NotDone_Raise_if(!myDone, "GridPolynomialToPoles");
372 Standard_Boolean Convert_GridPolynomialToPoles::IsDone() const