1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
23 #define No_Standard_OutOfRange
24 #define No_Standard_RangeError
27 #include <math_GaussPoints.hxx>
28 #include <math_Vector.hxx>
29 #include <math_Matrix.hxx>
32 #include <AppParCurves_MultiPoint.hxx>
33 #include <AppCont_ContMatrices.hxx>
34 #include <Standard_ConstructionError.hxx>
35 #include <Standard_NotImplemented.hxx>
36 #include <StdFail_NotDone.hxx>
42 static void InvMSurfMatrix(const Standard_Integer classeU,
43 const Standard_Integer classeV,
46 math_Matrix Inv1(1, classeU);
47 InvMMatrix(classeU, Inv1);
48 math_Matrix Inv2(1, classeV);
49 InvMMatrix(classeV, Inv2);
51 // math_Matrix InvM(1, classeU*classeV, 1, classeU*classeV);
52 Standard_Integer i, j, k, l;
54 for (i = 1; i <= classeU; i++) {
55 for (j= 1; j <= classeU; j++) {
56 for (k =1; k<= classeV; k++) {
57 for (l = 1; l<= classeV; l++) {
58 InvM(k+(i-1)*classeV,l+(j-1)*classeV) = Inv1(i,j)*Inv2(k,l);
66 static void MSurfMatrix(const Standard_Integer classeU,
67 const Standard_Integer classeV,
70 math_Matrix M1(1, classeU, 1, classeU);
72 math_Matrix M2(1, classeV, 1, classeV);
75 // math_Matrix M(1, classeU*classeV, 1, classeU*classeV);
76 Standard_Integer i, j, k, l;
78 for (i = 1; i <= classeU; i++) {
79 for (j= 1; j <= classeU; j++) {
80 for (k =1; k<= classeV; k++) {
81 for (l = 1; l<= classeV; l++) {
82 M(k+(i-1)*classeV,l+(j-1)*classeV) = M1(i,j)*M2(k,l);
94 AppCont_SurfLeastSquare::
95 AppCont_SurfLeastSquare(const Surface& Surf,
96 const Standard_Real U0,
97 const Standard_Real U1,
98 const Standard_Real V0,
99 const Standard_Real V1,
100 const AppParCurves_Constraint FirstCons,
101 const AppParCurves_Constraint LastUCons,
102 const AppParCurves_Constraint LastVCons,
103 const AppParCurves_Constraint LastCons,
104 const Standard_Integer DegU,
105 const Standard_Integer DegV,
106 const Standard_Integer NbPoints):
107 PointsX(1, NbPoints, 1 , NbPoints),
108 PointsY(1, NbPoints, 1 , NbPoints),
109 PointsZ(1, NbPoints, 1 , NbPoints),
110 PolesX(1, (DegU+1)*(DegV+1), 0.0),
111 PolesY(1, (DegU+1)*(DegV+1), 0.0),
112 PolesZ(1, (DegU+1)*(DegV+1), 0.0),
113 myUParam(1, NbPoints),
114 myVParam(1, NbPoints),
115 VBU(1, DegU+1, 1, NbPoints),
116 VBV(1, DegV+1, 1, NbPoints)
120 Nbdiscret = NbPoints;
121 Standard_Integer c, c1, c2, classeU = DegU+1, classeV = DegV+1;
122 Standard_Integer cla = classeU*classeV;
123 Standard_Integer bdeb = 1, bfin = cla, clav = cla-classeV+1;
124 Standard_Integer bint = 0, bint1 = 0, bint2 = 0, bintfin = 0;
125 Standard_Integer bint3 = 0, bint4 = 0, bint5 = 0, bint6 = 0;
126 Standard_Integer bint7 = 0, bint8 = 0;
127 math_Vector GaussP(1, NbPoints), GaussW(1, NbPoints);
128 Standard_Integer i, j, FirstP = 1, LastP = NbPoints;
129 Standard_Real U, dU, V, dV, ISS, Coeff, Coeff2;
130 Done = Standard_False;
133 math_Vector BX(1, cla, 0.0),
137 GaussP = GPoints(NbPoints);
138 GaussW = GWeights(NbPoints);
139 math_Vector TheWeights(1, NbPoints), VBParam(1, NbPoints);
144 // calcul et mise en ordre des parametres et des poids:
145 for (i = FirstP; i <= LastP; i++) {
146 U = 0.5*(U1+U0) + dU*GaussP(i);
147 V = 0.5*(V1+V0) + dV*GaussP(i);
148 if (i <= (NbPoints+1)/2) {
149 myUParam(LastP-i+1) = U;
150 myVParam(LastP-i+1) = V;
151 VBParam(LastP-i+1) = 0.5*(1 + GaussP(i));
152 TheWeights(LastP-i+1) = 0.5*GaussW(i);
155 myUParam(i-(NbPoints+1)/2) = U;
156 myVParam(i-(NbPoints+1)/2) = V;
157 VBParam(i-(NbPoints+1)/2) = 0.5*(1 + GaussP(i));
158 TheWeights(i-(NbPoints+1)/2) = 0.5*GaussW(i);
164 // Stockage des Points de Gauss:
165 for (i = FirstP; i <= LastP; i++) {
167 for (j = FirstP; j <= LastP; j++) {
169 SurfTool::D0(Surf, U, V, Pt);
170 Pt.Coord(PointsX(i, j), PointsY(i, j), PointsZ(i, j));
175 // Calcul des VB ( fonctions de Bernstein):
176 for (i = 1; i <= classeU; i++) {
177 for (j = 1; j <= NbPoints; j++) {
178 VBU(i,j) = PLib::Binomial(classeU-1,i-1)*
179 Pow((1-VBParam(j)),classeU-i)*Pow(VBParam(j),i-1);
183 for (i = 1; i <= classeV; i++) {
184 for (j = 1; j <= NbPoints; j++) {
185 VBV(i,j) = PLib::Binomial(classeV-1,i-1)*
186 Pow((1-VBParam(j)),classeV-i)*Pow(VBParam(j),i-1);
190 // Traitement du second membre:
192 for (c1 = 1; c1 <= classeU; c1++) {
193 for (c2 = 1; c2 <= classeV; c2++) {
195 for (i = 1; i <= NbPoints; i++) {
196 for (j = 1; j <= NbPoints; j++) {
197 Coeff = TheWeights(i)*TheWeights(j)*VBU(c1, i)*VBV(c2, j);
198 BX(c) += PointsX(i, j)*Coeff;
199 BY(c) += PointsY(i, j)*Coeff;
200 BZ(c) += PointsZ(i, j)*Coeff;
206 math_Matrix InvM(1, classeU*classeV, 1, classeU*classeV);
207 InvMSurfMatrix(classeU, classeV, InvM);
208 TColgp_Array2OfPnt Poles(1, classeU, 1, classeV);
212 if (FirstCons == AppParCurves_NoConstraint &&
213 LastCons == AppParCurves_NoConstraint &&
214 LastUCons == AppParCurves_NoConstraint &&
215 LastVCons == AppParCurves_NoConstraint) {
217 for (i = 1; i <= cla; i++) {
218 for (j = 1; j <= cla; j++) {
220 PolesX(i) += ISS * BX(j);
221 PolesY(i) += ISS * BY(j);
222 PolesZ(i) += ISS * BZ(j);
228 // Traitement du second membre:
229 math_Matrix M(1, classeU*classeV, 1, classeU*classeV);
230 MSurfMatrix(classeU, classeV, M);
233 if (FirstCons == AppParCurves_PassPoint ||
234 FirstCons == AppParCurves_TangencyPoint) {
236 SurfTool::D0(Surf, U0, V0, Pt);
237 Pt.Coord(PolesX(1), PolesY(1), PolesZ(1));
239 for (c = 1; c <= cla; c++) {
241 BX(c) = BX(c) - PolesX(1)*Coeff;
242 BY(c) = BY(c) - PolesY(1)*Coeff;
243 BZ(c) = BZ(c) - PolesZ(1)*Coeff;
247 if (LastCons == AppParCurves_PassPoint ||
248 LastCons == AppParCurves_TangencyPoint) {
250 SurfTool::D0(Surf, U1, V1, Pt);
251 Pt.Coord(PolesX(cla), PolesY(cla), PolesZ(cla));
253 for (c = 1; c <= cla; c++) {
255 BX(c) = BX(c) - PolesX(cla)*Coeff;
256 BY(c) = BY(c) - PolesY(cla)*Coeff;
257 BZ(c) = BZ(c) - PolesZ(cla)*Coeff;
261 if (LastUCons == AppParCurves_PassPoint ||
262 LastUCons == AppParCurves_TangencyPoint) {
263 bint++; bint1 = clav;
264 SurfTool::D0(Surf, U1, V0, Pt);
265 Pt.Coord(PolesX(clav), PolesY(clav), PolesZ(clav));
267 for (c = 1; c <= cla; c++) {
269 BX(c) = BX(c) - PolesX(clav)*Coeff;
270 BY(c) = BY(c) - PolesY(clav)*Coeff;
271 BZ(c) = BZ(c) - PolesZ(clav)*Coeff;
275 if (LastVCons == AppParCurves_PassPoint ||
276 LastVCons == AppParCurves_TangencyPoint) {
277 bint++; bint2 = classeV;
278 SurfTool::D0(Surf, U0, V1, Pt);
279 Pt.Coord(PolesX(classeV), PolesY(classeV), PolesZ(classeV));
281 for (c = 1; c <= cla; c++) {
282 Coeff = M(c, classeV);
283 BX(c) = BX(c) - PolesX(classeV)*Coeff;
284 BY(c) = BY(c) - PolesY(classeV)*Coeff;
285 BZ(c) = BZ(c) - PolesZ(classeV)*Coeff;
293 if (FirstCons == AppParCurves_TangencyPoint) {
294 SurfTool::D1(Surf, U0, V0, Pt, VU, VV);
295 bdeb = 3; bint++; bint3 = classeV+1;
297 PolesX(bint3) = PolesX(1) + VU.X()/DegU*(U1-U0);
298 PolesY(bint3) = PolesY(1) + VU.Y()/DegU*(U1-U0);
299 PolesZ(bint3) = PolesZ(1) + VU.Z()/DegU*(U1-U0);
301 PolesX(2) = PolesX(1) + VV.X()/DegV*(V1-V0);
302 PolesY(2) = PolesY(1) + VV.Y()/DegV*(V1-V0);
303 PolesZ(2) = PolesZ(1) + VV.Z()/DegV*(V1-V0);
305 for (c = 1; c <= cla; c++) {
306 Coeff = M(c, 2); Coeff2 = M(c, bint3);
307 BX(c) = BX(c) - PolesX(2)*Coeff - PolesX(bint3)*Coeff2;
308 BY(c) = BY(c) - PolesY(2)*Coeff - PolesY(bint3)*Coeff2;
309 BZ(c) = BZ(c) - PolesZ(2)*Coeff - PolesZ(bint3)*Coeff2;
314 if (LastCons == AppParCurves_TangencyPoint) {
315 SurfTool::D1(Surf, U1, V1, Pt, VU, VV);
316 bfin = cla-2; bint++; bint4 = cla-classeV;
318 PolesX(bint4) = PolesX(cla) - VU.X()/DegU*(U1-U0);
319 PolesY(bint4) = PolesY(cla) - VU.Y()/DegU*(U1-U0);
320 PolesZ(bint4) = PolesZ(cla) - VU.Z()/DegU*(U1-U0);
322 PolesX(cla-1) = PolesX(cla) - VV.X()/DegV*(V1-V0);
323 PolesY(cla-1) = PolesY(cla) - VV.Y()/DegV*(V1-V0);
324 PolesZ(cla-1) = PolesZ(cla) - VV.Z()/DegV*(V1-V0);
326 for (c = 1; c <= cla; c++) {
327 Coeff = M(c, cla-1); Coeff2 = M(c, bint4);
328 BX(c) = BX(c) - PolesX(cla-1)*Coeff - PolesX(bint4)*Coeff2;
329 BY(c) = BY(c) - PolesY(cla-1)*Coeff - PolesY(bint4)*Coeff2;
330 BZ(c) = BZ(c) - PolesZ(cla-1)*Coeff - PolesZ(bint4)*Coeff2;
335 if (LastVCons == AppParCurves_TangencyPoint) {
336 SurfTool::D1(Surf, U0, V1, Pt, VU, VV);
337 bint += 2; bint5 = classeV-1; bint6 = 2*classeV;
339 PolesX(bint5) = PolesX(classeV) - VV.X()/DegV*(V1-V0);
340 PolesY(bint5) = PolesY(classeV) - VV.Y()/DegV*(V1-V0);
341 PolesZ(bint5) = PolesZ(classeV) - VV.Z()/DegV*(V1-V0);
343 PolesX(bint6) = PolesX(classeV) + VU.X()/DegU*(U1-U0);
344 PolesY(bint6) = PolesY(classeV) + VU.Y()/DegU*(U1-U0);
345 PolesZ(bint6) = PolesZ(classeV) + VU.Z()/DegU*(U1-U0);
347 for (c = 1; c <= cla; c++) {
348 Coeff = M(c, bint5); Coeff2 = M(c, bint6);
349 BX(c) = BX(c) - PolesX(bint5)*Coeff - PolesX(bint6)*Coeff2;
350 BY(c) = BY(c) - PolesY(bint5)*Coeff - PolesY(bint6)*Coeff2;
351 BZ(c) = BZ(c) - PolesZ(bint5)*Coeff - PolesZ(bint6)*Coeff2;
356 if (LastUCons == AppParCurves_TangencyPoint) {
357 SurfTool::D1(Surf, U1, V0, Pt, VU, VV);
358 bint += 2; bint7 = clav-classeV; bint8 = clav+1;
360 PolesX(bint8) = PolesX(clav) + VV.X()/DegV*(V1-V0);
361 PolesY(bint8) = PolesY(clav) + VV.Y()/DegV*(V1-V0);
362 PolesZ(bint8) = PolesZ(clav) + VV.Z()/DegV*(V1-V0);
364 PolesX(bint7) = PolesX(clav) - VU.X()/DegU*(U1-U0);
365 PolesY(bint7) = PolesY(clav) - VU.Y()/DegU*(U1-U0);
366 PolesZ(bint7) = PolesZ(clav) - VU.Z()/DegU*(U1-U0);
368 for (c = 1; c <= cla; c++) {
369 Coeff = M(c, bint8); Coeff2 = M(c, bint7);
370 BX(c) = BX(c)- PolesX(bint8)*Coeff - PolesX(bint7)*Coeff2;
371 BY(c) = BY(c)- PolesY(bint8)*Coeff - PolesY(bint7)*Coeff2;
372 BZ(c) = BZ(c)- PolesZ(bint8)*Coeff - PolesZ(bint7)*Coeff2;
377 math_Vector B2X(bdeb, bfin-bint, 0.0);
378 math_Vector B2Y(bdeb, bfin-bint, 0.0);
379 math_Vector B2Z(bdeb, bfin-bint, 0.0);
381 Standard_Integer i2 = bdeb;
382 for (i = bdeb; i <= bfin; i++) {
383 if (i != bint1 && i != bint2 && i != bint3 && i != bint4 &&
384 i != bint5 && i != bint6 && i != bint7 && i != bint8) {
385 for (j = 1; j <= cla; j++) {
387 B2X(i2) = B2X(i2) + BX(j)*Coeff;
388 B2Y(i2) = B2Y(i2) + BY(j)*Coeff;
389 B2Z(i2) = B2Z(i2) + BZ(j)*Coeff;
395 math_Matrix MP(1, cla, bdeb, bfin-bint);
396 math_Matrix IBP(bdeb, bfin-bint, bdeb, bfin-bint);
398 Standard_Integer j2 = bdeb;
399 for (i = 1; i <= cla; i++) {
401 for (j = bdeb; j <= bfin; j++) {
402 if (j != bint1 && j != bint2 && j != bint3 && j != bint4 &&
403 j != bint5 && j != bint6 && j != bint7 && j != bint8) {
409 math_Matrix IBP1 = MP.Transposed()*MP;
410 IBP = IBP1.Inverse();
413 for (i = bdeb; i <= bfin; i++) {
414 if (i != bint1 && i != bint2 && i != bint3 && i != bint4 &&
415 i != bint5 && i != bint6 && i != bint7 && i != bint8) {
416 for (j = bdeb; j <= bfin-bint; j++) {
418 PolesX(i) += ISS * B2X(j);
419 PolesY(i) += ISS * B2Y(j);
420 PolesZ(i) += ISS * B2Z(j);
427 for (j = 1; j <= classeV; j++) {
428 for (i = 1; i <= classeU; i++) {
429 Poles(i, j).SetCoord(PolesX(j+ (i-1)*classeV),
430 PolesY(j+ (i-1)*classeV),
431 PolesZ(j+ (i-1)*classeV));
435 SCU = new Geom_BezierSurface(Poles);
436 Done = Standard_True;
441 Standard_Boolean AppCont_SurfLeastSquare::IsDone() const
447 const Handle(Geom_BezierSurface)& AppCont_SurfLeastSquare::Value()
454 void AppCont_SurfLeastSquare::Error(Standard_Real& F,
455 Standard_Real& MaxE3d) const
458 Standard_Integer i, j, c, cu, cv, classeU = DegreU+1, classeV = DegreV+1;
459 Standard_Real Coeff, err3d = 0.0;
460 math_Matrix MyPointsX(1, Nbdiscret, 1, Nbdiscret);
461 math_Matrix MyPointsY(1, Nbdiscret, 1, Nbdiscret);
462 math_Matrix MyPointsZ(1, Nbdiscret, 1, Nbdiscret);
470 for (cu = 1; cu <= classeU; cu++) {
471 for (cv = 1; cv <= classeV; cv++) {
473 for (i = 1; i <= Nbdiscret; i++) {
474 for (j = 1; j <= Nbdiscret; j++) {
475 Coeff = VBU(cu, i)*VBV(cv, j);
476 MyPointsX(i, j) = MyPointsX(i, j) - PolesX(c)*Coeff;
477 MyPointsY(i, j) = MyPointsY(i, j) - PolesY(c)*Coeff;
478 MyPointsZ(i, j) = MyPointsZ(i, j) - PolesZ(c)*Coeff;
485 for (i = 1; i <= Nbdiscret; i++) {
486 for (j = 1; j <= Nbdiscret; j++) {
487 err3d = MyPointsX(i, j) * MyPointsX(i, j) +
488 MyPointsY(i, j) * MyPointsY(i, j) +
489 MyPointsZ(i, j) * MyPointsZ(i, j);
490 MaxE3d = Max(MaxE3d, err3d);
495 MaxE3d = Sqrt(MaxE3d);