0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BlendFunc / BlendFunc_RuledInv.cxx
1 // Created on: 1993-12-02
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Adaptor3d_HSurface.hxx>
21 #include <BlendFunc_RuledInv.hxx>
22 #include <math_Matrix.hxx>
23 #include <Precision.hxx>
24
25 BlendFunc_RuledInv::BlendFunc_RuledInv(const Handle(Adaptor3d_HSurface)& S1,
26                                        const Handle(Adaptor3d_HSurface)& S2,
27                                        const Handle(Adaptor3d_HCurve)& C)
28 : surf1(S1),
29   surf2(S2),
30   curv(C),
31   first(Standard_False)
32 {
33 }
34
35 void BlendFunc_RuledInv::Set(const Standard_Boolean OnFirst,
36                              const Handle(Adaptor2d_HCurve2d)& C)
37 {
38   first = OnFirst;
39   csurf = C;
40 }
41
42 Standard_Integer BlendFunc_RuledInv::NbEquations () const
43 {
44   return 4;
45 }
46
47 void BlendFunc_RuledInv::GetTolerance(math_Vector& Tolerance,
48                                       const Standard_Real Tol) const
49 {
50   Tolerance(1) = csurf->Resolution(Tol);
51   Tolerance(2) = curv->Resolution(Tol);
52   if (first) {
53     Tolerance(3) = surf2->UResolution(Tol);
54     Tolerance(4) = surf2->VResolution(Tol);
55   }
56   else {
57     Tolerance(3) = surf1->UResolution(Tol);
58     Tolerance(4) = surf1->VResolution(Tol);
59   }
60 }
61
62 void BlendFunc_RuledInv::GetBounds(math_Vector& InfBound,
63                                    math_Vector& SupBound) const
64 {
65   InfBound(1) = csurf->FirstParameter();
66   InfBound(2) = curv->FirstParameter();
67   SupBound(1) = csurf->LastParameter();
68   SupBound(2) = curv->LastParameter();
69
70   if (first) {
71     InfBound(3) = surf2->FirstUParameter();
72     InfBound(4) = surf2->FirstVParameter();
73     SupBound(3) = surf2->LastUParameter();
74     SupBound(4) = surf2->LastVParameter();
75     if(!Precision::IsInfinite(InfBound(3)) &&
76        !Precision::IsInfinite(SupBound(3))) {
77       const Standard_Real range = (SupBound(3) - InfBound(3));
78       InfBound(3) -= range;
79       SupBound(3) += range;
80     }
81     if(!Precision::IsInfinite(InfBound(4)) &&
82        !Precision::IsInfinite(SupBound(4))) {
83       const Standard_Real range = (SupBound(4) - InfBound(4));
84       InfBound(4) -= range;
85       SupBound(4) += range;
86     }
87   }
88   else {
89     InfBound(3) = surf1->FirstUParameter();
90     InfBound(4) = surf1->FirstVParameter();
91     SupBound(3) = surf1->LastUParameter();
92     SupBound(4) = surf1->LastVParameter();
93     if(!Precision::IsInfinite(InfBound(3)) &&
94        !Precision::IsInfinite(SupBound(3))) {
95       const Standard_Real range = (SupBound(3) - InfBound(3));
96       InfBound(3) -= range;
97       SupBound(3) += range;
98     }
99     if(!Precision::IsInfinite(InfBound(4)) &&
100        !Precision::IsInfinite(SupBound(4))) {
101       const Standard_Real range = (SupBound(4) - InfBound(4));
102       InfBound(4) -= range;
103       SupBound(4) += range;
104     }
105   }    
106 }
107
108 Standard_Boolean BlendFunc_RuledInv::IsSolution(const math_Vector& Sol,
109                                                 const Standard_Real Tol)
110 {
111   math_Vector valsol(1,4);
112   Value(Sol,valsol);
113   if (Abs(valsol(1)) <= Tol &&
114       Abs(valsol(2)) <= Tol &&
115       Abs(valsol(3)) <= Tol &&
116       Abs(valsol(4)) <= Tol)
117     return Standard_True;
118
119   return Standard_False;
120 }
121
122
123 Standard_Boolean BlendFunc_RuledInv::Value(const math_Vector& X,
124                                            math_Vector& F)
125 {
126   gp_Pnt ptcur;
127   gp_Vec d1cur;
128   curv->D1(X(2),ptcur,d1cur);
129
130   const gp_XYZ nplan = d1cur.Normalized().XYZ();
131   const Standard_Real theD = -(nplan.Dot(ptcur.XYZ()));
132   const gp_Pnt2d pt2d(csurf->Value(X(1)));
133
134   gp_Pnt pts1,pts2;
135   gp_Vec d1u1,d1v1,d1u2,d1v2;
136   if (first)
137   {
138     surf1->D1(pt2d.X(),pt2d.Y(),pts1,d1u1,d1v1);
139     surf2->D1(X(3),X(4),pts2,d1u2,d1v2);
140   }
141   else
142   {
143     surf1->D1(X(3),X(4),pts1,d1u1,d1v1);
144     surf2->D1(pt2d.X(),pt2d.Y(),pts2,d1u2,d1v2);
145   }
146
147   const gp_XYZ temp(pts2.XYZ()-pts1.XYZ());
148
149   gp_XYZ ns1 = d1u1.Crossed(d1v1).XYZ();
150   gp_XYZ ns2 = d1u2.Crossed(d1v2).XYZ();
151   const Standard_Real norm1 = nplan.Crossed(ns1).Modulus();
152   const Standard_Real norm2 = nplan.Crossed(ns2).Modulus();
153   ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1,ns1);
154   ns2.SetLinearForm(nplan.Dot(ns2)/norm2,nplan, -1./norm2,ns2);
155
156   F(1) = (nplan.Dot(pts1.XYZ())) + theD;
157   F(2) = (nplan.Dot(pts2.XYZ())) + theD;
158   
159   F(3) = temp.Dot(ns1);
160   F(4) = temp.Dot(ns2);
161
162   return Standard_True;
163 }
164
165 Standard_Boolean BlendFunc_RuledInv::Derivatives(const math_Vector& X,
166                                                  math_Matrix& D)
167 {
168   gp_Pnt ptcur;
169   gp_Vec d1cur,d2cur;
170   curv->D2(X(2),ptcur,d1cur,d2cur);
171
172   const Standard_Real normtgcur = d1cur.Magnitude();
173   const gp_Vec nplan = d1cur.Normalized();
174
175   gp_Vec dnplan;
176   dnplan.SetLinearForm(-nplan.Dot(d2cur),nplan,d2cur);
177   dnplan /= normtgcur;
178
179   gp_Pnt2d p2d;
180   gp_Vec2d v2d;
181   csurf->D1(X(1),p2d,v2d);
182
183   gp_Pnt pts1,pts2;
184   gp_Vec d1u1,d1v1,d1u2,d1v2;
185   gp_Vec d2u1,d2v1,d2u2,d2v2,d2uv1,d2uv2;
186   gp_Vec dpdt, p1p2;
187   if (first)
188   {
189     surf1->D2(p2d.X(),p2d.Y(),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
190     surf2->D2(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
191     dpdt.SetLinearForm(v2d.X(),d1u1,v2d.Y(),d1v1);
192     p1p2 = gp_Vec(pts1,pts2);
193     D(1,1) = dpdt.Dot(nplan);
194     D(1,2) = dnplan.XYZ().Dot(pts1.XYZ()-ptcur.XYZ()) - normtgcur;
195     D(1,3) = 0.;
196     D(1,4) = 0.;
197
198     D(2,1) = 0.;
199     D(2,2) = dnplan.XYZ().Dot(pts2.XYZ()-ptcur.XYZ()) - normtgcur;
200     D(2,3) = d1u2.Dot(nplan);
201     D(2,4) = d1v2.Dot(nplan);
202   }
203   else
204   {
205     surf1->D2(X(3),X(4),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
206     surf2->D2(p2d.X(),p2d.Y(),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
207     dpdt.SetLinearForm(v2d.X(),d1u2,v2d.Y(),d1v2);
208     p1p2 = gp_Vec(pts1,pts2);
209     D(1,1) = 0.;
210     D(1,2) = dnplan.XYZ().Dot(pts1.XYZ()-ptcur.XYZ()) - normtgcur;
211     D(1,3) = d1u1.Dot(nplan);
212     D(1,4) = d1v1.Dot(nplan);
213
214     D(2,1) = dpdt.Dot(nplan);
215     D(2,2) = dnplan.XYZ().Dot(pts2.XYZ()-ptcur.XYZ()) - normtgcur;
216     D(2,3) = 0.;
217     D(2,4) = 0.;
218   }
219
220   const gp_Vec ns1 = d1u1.Crossed(d1v1);
221   const gp_Vec ns2 = d1u2.Crossed(d1v2);
222   const gp_Vec ncrossns1 = nplan.Crossed(ns1);
223   const gp_Vec ncrossns2 = nplan.Crossed(ns2);
224   const Standard_Real norm1 = ncrossns1.Magnitude();
225   const Standard_Real norm2 = ncrossns2.Magnitude();
226
227   const Standard_Real ndotns1 = nplan.Dot(ns1);
228   const Standard_Real ndotns2 = nplan.Dot(ns2);
229
230   gp_Vec nor1,nor2;
231   nor1.SetLinearForm(ndotns1/norm1,nplan,-1./norm1,ns1);
232   nor2.SetLinearForm(ndotns2/norm2,nplan,-1./norm2,ns2);
233
234   if (first) {
235     D(3,3) = d1u2.Dot(nor1);
236     D(3,4) = d1v2.Dot(nor1);
237
238     D(4,1) = -(dpdt.Dot(nor2));
239   }
240   else {
241     D(3,1) = dpdt.Dot(nor1);
242
243     D(4,3) = -(d1u1.Dot(nor2));
244     D(4,4) = -(d1v1.Dot(nor2));
245   }
246
247   gp_Vec resul1,resul2,temp;
248   Standard_Real grosterme;
249
250   // Derivee de nor1 par rapport a u1
251
252   temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
253   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
254   resul1.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
255                        grosterme/norm1,ns1,
256                        -1./norm1,temp);
257
258   // Derivee par rapport a v1
259
260   temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
261   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
262   resul2.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
263                        grosterme/norm1,ns1,
264                        -1./norm1,temp);
265
266   if (first) {
267     resul1.SetLinearForm(v2d.X(),resul1,v2d.Y(),resul2);
268     D(3,1) = p1p2.Dot(resul1) - (dpdt.Dot(nor1));
269   }
270   else {
271     D(3,3) = -(d1u1.Dot(nor1)) + p1p2.Dot(resul1);
272     D(3,4) = -(d1v1.Dot(nor1)) + p1p2.Dot(resul2);
273   }
274
275   // Derivee de nor2 par rapport a u2
276   temp = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
277   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
278   resul1.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
279                        grosterme/norm2,ns2,
280                        -1./norm2,temp);
281
282   // Derivee par rapport a v2
283   temp = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
284   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
285   resul2.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
286                        grosterme/norm2,ns2,
287                        -1./norm2,temp);
288
289   if (first) {
290     D(4,3) = d1u2.Dot(nor2) + p1p2.Dot(resul1);
291     D(4,4) = d1v2.Dot(nor2) + p1p2.Dot(resul2);
292   }
293   else {
294     resul1.SetLinearForm(v2d.X(),resul1,v2d.Y(),resul2);
295     D(4,1) = p1p2.Dot(resul1) + dpdt.Dot(nor2) ;
296   }
297
298
299   // derivee par rapport a w (parametre sur ligne guide)
300
301   grosterme = ncrossns1.Dot(dnplan.Crossed(ns1))/norm1/norm1;
302   resul1.SetLinearForm(-(grosterme*ndotns1-dnplan.Dot(ns1))/norm1,nplan,
303                        ndotns1/norm1,dnplan,
304                        grosterme/norm1,ns1);
305
306
307   grosterme = ncrossns2.Dot(dnplan.Crossed(ns2))/norm2/norm2;
308   resul2.SetLinearForm(-(grosterme*ndotns2-dnplan.Dot(ns2))/norm2,nplan,
309                        ndotns2/norm2,dnplan,
310                        grosterme/norm2,ns2);
311
312   D(3,2) = p1p2.Dot(resul1);
313   D(4,2) = p1p2.Dot(resul2);
314
315   return Standard_True;
316 }
317
318
319 Standard_Boolean BlendFunc_RuledInv::Values(const math_Vector& X,
320                                             math_Vector& F,
321                                             math_Matrix& D)
322 {
323   gp_Pnt ptcur;
324   gp_Vec d1cur,d2cur;
325   curv->D2(X(2),ptcur,d1cur,d2cur);
326
327   const Standard_Real normtgcur = d1cur.Magnitude();
328   const gp_Vec nplan = d1cur.Normalized();
329   const Standard_Real theD = -(nplan.XYZ().Dot(ptcur.XYZ()));
330
331   gp_Vec dnplan;
332   dnplan.SetLinearForm(-nplan.Dot(d2cur),nplan,d2cur);
333   dnplan /= normtgcur;
334
335   gp_Pnt2d p2d;
336   gp_Vec2d v2d;
337   csurf->D1(X(1),p2d,v2d);
338
339   gp_Pnt pts1,pts2;
340   gp_Vec d1u1,d1v1,d1u2,d1v2;
341   gp_Vec d2u1,d2v1,d2u2,d2v2,d2uv1,d2uv2;
342   gp_Vec dpdt,p1p2;
343   if (first)
344   {
345     surf1->D2(p2d.X(),p2d.Y(),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
346     surf2->D2(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
347     dpdt.SetLinearForm(v2d.X(),d1u1,v2d.Y(),d1v1);
348     p1p2 = gp_Vec(pts1,pts2);
349     D(1,1) = dpdt.Dot(nplan);
350     D(1,2) = dnplan.XYZ().Dot(pts1.XYZ()-ptcur.XYZ()) - normtgcur;
351     D(1,3) = 0.;
352     D(1,4) = 0.;
353
354     D(2,1) = 0.;
355     D(2,2) = dnplan.XYZ().Dot(pts2.XYZ()-ptcur.XYZ()) - normtgcur;
356     D(2,3) = d1u2.Dot(nplan);
357     D(2,4) = d1v2.Dot(nplan);
358   }
359   else
360   {
361     surf1->D2(X(3),X(4),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
362     surf2->D2(p2d.X(),p2d.Y(),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
363     dpdt.SetLinearForm(v2d.X(),d1u2,v2d.Y(),d1v2);
364     p1p2 = gp_Vec(pts1,pts2);
365     D(1,1) = 0.;
366     D(1,2) = dnplan.XYZ().Dot(pts1.XYZ()-ptcur.XYZ()) - normtgcur;
367     D(1,3) = d1u1.Dot(nplan);
368     D(1,4) = d1v1.Dot(nplan);
369
370     D(2,1) = dpdt.Dot(nplan);
371     D(2,2) = dnplan.XYZ().Dot(pts2.XYZ()-ptcur.XYZ()) - normtgcur;
372     D(2,3) = 0.;
373     D(2,4) = 0.;
374   }
375
376   const gp_Vec ns1 = d1u1.Crossed(d1v1);
377   const gp_Vec ns2 = d1u2.Crossed(d1v2);
378   const gp_Vec ncrossns1 = nplan.Crossed(ns1);
379   const gp_Vec ncrossns2 = nplan.Crossed(ns2);
380   const Standard_Real norm1 = ncrossns1.Magnitude();
381   const Standard_Real norm2 = ncrossns2.Magnitude();
382
383   const Standard_Real ndotns1 = nplan.Dot(ns1);
384   const Standard_Real ndotns2 = nplan.Dot(ns2);
385
386   gp_Vec nor1,nor2;
387   nor1.SetLinearForm(ndotns1/norm1,nplan,-1./norm1,ns1);
388   nor2.SetLinearForm(ndotns2/norm2,nplan,-1./norm2,ns2);
389
390   F(1) = (nplan.Dot(pts1.XYZ())) + theD;
391   F(2) = (nplan.Dot(pts2.XYZ())) + theD;
392   
393   F(3) = p1p2.Dot(nor1);
394   F(4) = p1p2.Dot(nor2);
395
396   if (first) {
397     D(3,3) = d1u2.Dot(nor1);
398     D(3,4) = d1v2.Dot(nor1);
399
400     D(4,1) = -(dpdt.Dot(nor2));
401   }
402   else {
403     D(3,1) = dpdt.Dot(nor1);
404
405     D(4,3) = -(d1u1.Dot(nor2));
406     D(4,4) = -(d1v1.Dot(nor2));
407   }
408
409   gp_Vec resul1,resul2,temp;
410   Standard_Real grosterme;
411
412   // Derivee de nor1 par rapport a u1
413
414   temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
415   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
416   resul1.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
417                        grosterme/norm1,ns1,
418                        -1./norm1,temp);
419
420   // Derivee par rapport a v1
421
422   temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
423   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
424   resul2.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
425                        grosterme/norm1,ns1,
426                        -1./norm1,temp);
427
428   if (first) {
429     resul1.SetLinearForm(v2d.X(),resul1,v2d.Y(),resul2);
430     D(3,1) = p1p2.Dot(resul1) - (dpdt.Dot(nor1));
431   }
432   else {
433     D(3,3) = -(d1u1.Dot(nor1)) + p1p2.Dot(resul1);
434     D(3,4) = -(d1v1.Dot(nor1)) + p1p2.Dot(resul2);
435   }
436
437   // Derivee de nor2 par rapport a u2
438   temp = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
439   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
440   resul1.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
441                        grosterme/norm2,ns2,
442                        -1./norm2,temp);
443
444   // Derivee par rapport a v2
445   temp = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
446   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
447   resul2.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
448                        grosterme/norm2,ns2,
449                        -1./norm2,temp);
450
451   if (first) {
452     D(4,3) = d1u2.Dot(nor2) + p1p2.Dot(resul1);
453     D(4,4) = d1v2.Dot(nor2) + p1p2.Dot(resul2);
454   }
455   else {
456     resul1.SetLinearForm(v2d.X(),resul1,v2d.Y(),resul2);
457     D(4,1) = p1p2.Dot(resul1) + dpdt.Dot(nor2) ;
458   }
459
460
461   // derivee par rapport a w (parametre sur ligne guide)
462
463   grosterme = ncrossns1.Dot(dnplan.Crossed(ns1))/norm1/norm1;
464   resul1.SetLinearForm(-(grosterme*ndotns1-dnplan.Dot(ns1))/norm1,nplan,
465                        ndotns1/norm1,dnplan,
466                        grosterme/norm1,ns1);
467
468
469   grosterme = ncrossns2.Dot(dnplan.Crossed(ns2))/norm2/norm2;
470   resul2.SetLinearForm(-(grosterme*ndotns2-dnplan.Dot(ns2))/norm2,nplan,
471                        ndotns2/norm2,dnplan,
472                        grosterme/norm2,ns2);
473
474   D(3,2) = p1p2.Dot(resul1);
475   D(4,2) = p1p2.Dot(resul2);
476
477   return Standard_True;
478 }