0024275: Cppcheck warnings on uninitialized class members
[occt.git] / src / Bnd / Bnd_B3x.gxx
1 // Created on: 2005-09-08
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2005-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 inline Standard_Boolean _compareDist  (const RealType aHSize[3],
22                                        const RealType aDist [3])
23 {
24   return (Abs(aDist[0]) > aHSize[0] ||
25           Abs(aDist[1]) > aHSize[1] ||
26           Abs(aDist[2]) > aHSize[2]);
27 }
28
29 inline Standard_Boolean _compareDistD (const gp_XYZ& aHSize,const gp_XYZ& aDist)
30 {
31   return (Abs(aDist.X()) > aHSize.X() ||
32           Abs(aDist.Y()) > aHSize.Y() ||
33           Abs(aDist.Z()) > aHSize.Z());
34 }
35
36 //=======================================================================
37 //function : Add
38 //purpose  : Update the box by a point
39 //=======================================================================
40
41 void Bnd_B3x::Add (const gp_XYZ& thePnt) {
42   if (IsVoid()) {
43     myCenter[0] = RealType(thePnt.X());
44     myCenter[1] = RealType(thePnt.Y());
45     myCenter[2] = RealType(thePnt.Z());
46     myHSize [0] = 0.;
47     myHSize [1] = 0.;
48     myHSize [2] = 0.;
49   } else {
50     const RealType aDiff[3] = {
51       RealType(thePnt.X()) - myCenter[0],
52       RealType(thePnt.Y()) - myCenter[1],
53       RealType(thePnt.Z()) - myCenter[2]
54     };
55     if (aDiff[0] > myHSize[0]) {
56       const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
57       myCenter[0] += aShift;
58       myHSize [0] += aShift;
59     } else if (aDiff[0] < -myHSize[0]) {
60       const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
61       myCenter[0] += aShift;
62       myHSize [0] -= aShift;
63     }
64     if (aDiff[1] > myHSize[1]) {
65       const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
66       myCenter[1] +=aShift;
67       myHSize [1] +=aShift;
68     } else if (aDiff[1] < -myHSize[1]) {
69       const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
70       myCenter[1] += aShift;
71       myHSize [1] -= aShift;
72     }
73     if (aDiff[2] > myHSize[2]) {
74       const RealType aShift = (aDiff[2] - myHSize[2]) / 2;
75       myCenter[2] +=aShift;
76       myHSize [2] +=aShift;
77     } else if (aDiff[2] < -myHSize[2]) {
78       const RealType aShift = (aDiff[2] + myHSize[2]) / 2;
79       myCenter[2] += aShift;
80       myHSize [2] -= aShift;
81     }
82   }
83 }
84
85 //=======================================================================
86 //function : Limit
87 //purpose  : limit the current box with the internals of theBox
88 //=======================================================================
89
90 Standard_Boolean Bnd_B3x::Limit (const Bnd_B3x& theBox)
91 {
92   Standard_Boolean aResult (Standard_False);
93   const RealType diffC[3] = {
94     theBox.myCenter[0] - myCenter[0],
95     theBox.myCenter[1] - myCenter[1],
96     theBox.myCenter[2] - myCenter[2]
97   };
98   const RealType sumH[3] = {
99     theBox.myHSize[0] + myHSize[0],
100     theBox.myHSize[1] + myHSize[1],
101     theBox.myHSize[2] + myHSize[2]
102   };
103   // check the condition IsOut
104   if (_compareDist (sumH, diffC) == Standard_False) {
105     const RealType diffH[3] = {
106       theBox.myHSize[0] - myHSize[0],
107       theBox.myHSize[1] - myHSize[1],
108       theBox.myHSize[2] - myHSize[2]
109     };
110     if (diffC[0] - diffH[0] > 0.) {
111       const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
112       myCenter[0] += aShift;
113       myHSize [0] -= aShift;
114     } else if (diffC[0] + diffH[0] < 0.) {
115       const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
116       myCenter[0] += aShift;
117       myHSize [0] += aShift;
118     }
119     if (diffC[1] - diffH[1] > 0.) {
120       const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
121       myCenter[1] += aShift;
122       myHSize [1] -= aShift;
123     } else if (diffC[1] + diffH[1] < 0.) {
124       const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
125       myCenter[1] += aShift;
126       myHSize [1] += aShift;
127     }
128     if (diffC[2] - diffH[2] > 0.) {
129       const RealType aShift = (diffC[2] - diffH[2]) / 2; // positive
130       myCenter[2] += aShift;
131       myHSize [2] -= aShift;
132     } else if (diffC[2] + diffH[2] < 0.) {
133       const RealType aShift = (diffC[2] + diffH[2]) / 2; // negative
134       myCenter[2] += aShift;
135       myHSize [2] += aShift;
136     }
137     aResult = Standard_True;
138   }
139   return aResult;
140 }
141
142 //=======================================================================
143 //function : Transformed
144 //purpose  : 
145 //=======================================================================
146
147 Bnd_B3x Bnd_B3x::Transformed (const gp_Trsf& theTrsf) const
148 {
149   Bnd_B3x aResult;
150   const gp_TrsfForm aForm = theTrsf.Form();
151   const Standard_Real aScale = theTrsf.ScaleFactor();
152   const Standard_Real aScaleAbs = Abs(aScale);
153   if (aForm == gp_Identity)
154     aResult = * this;
155   else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
156   {
157     aResult.myCenter[0] =
158       (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
159     aResult.myCenter[1] =
160       (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
161     aResult.myCenter[2] =
162       (RealType)(myCenter[2] * aScale + theTrsf.TranslationPart().Z());
163     aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
164     aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
165     aResult.myHSize[2] = (RealType)(myHSize[2] * aScaleAbs);
166   } else {
167     gp_XYZ aCenter ((Standard_Real)myCenter[0],
168                     (Standard_Real)myCenter[1],
169                     (Standard_Real)myCenter[2]);
170     theTrsf.Transforms (aCenter);
171     aResult.myCenter[0] = (RealType)aCenter.X();
172     aResult.myCenter[1] = (RealType)aCenter.Y();
173     aResult.myCenter[2] = (RealType)aCenter.Z();
174
175     const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
176     aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
177                                                  Abs(aMat[1]) * myHSize[1]+
178                                                  Abs(aMat[2]) * myHSize[2]));
179     aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[3]) * myHSize[0]+
180                                                  Abs(aMat[4]) * myHSize[1]+
181                                                  Abs(aMat[5]) * myHSize[2]));
182     aResult.myHSize[2] = (RealType)(aScaleAbs * (Abs(aMat[6]) * myHSize[0]+
183                                                  Abs(aMat[7]) * myHSize[1]+
184                                                  Abs(aMat[8]) * myHSize[2]));
185   }
186   return aResult;
187 }
188
189 //=======================================================================
190 //function : IsOut
191 //purpose  : Intersection Box - Sphere
192 //=======================================================================
193
194 Standard_Boolean Bnd_B3x::IsOut (const gp_XYZ&          theCenter,
195                                  const Standard_Real    theRadius,
196                                  const Standard_Boolean isSphereHollow) const
197 {
198   Standard_Boolean aResult (Standard_True);
199   if (isSphereHollow == Standard_False) {
200     // vector from the center of the sphere to the nearest box face
201     const Standard_Real aDist[3] = {
202       Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
203       Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1]),
204       Abs(theCenter.Z()-Standard_Real(myCenter[2])) - Standard_Real(myHSize[2])
205     };
206     Standard_Real aD (0.);
207     if (aDist[0] > 0.)
208       aD  = aDist[0]*aDist[0];
209     if (aDist[1] > 0.)
210       aD += aDist[1]*aDist[1];
211     if (aDist[2] > 0.)
212       aD += aDist[2]*aDist[2];
213     aResult = (aD > theRadius*theRadius);
214   } else {
215     const Standard_Real aDistC[3] = {
216       Abs(theCenter.X()-Standard_Real(myCenter[0])),
217       Abs(theCenter.Y()-Standard_Real(myCenter[1])),
218       Abs(theCenter.Z()-Standard_Real(myCenter[2]))
219     };
220     // vector from the center of the sphere to the nearest box face
221     Standard_Real aDist[3] = {
222       aDistC[0] - Standard_Real(myHSize[0]),
223       aDistC[1] - Standard_Real(myHSize[1]),
224       aDistC[2] - Standard_Real(myHSize[2])
225     };
226     Standard_Real aD (0.);
227     if (aDist[0] > 0.)
228       aD  = aDist[0]*aDist[0];
229     if (aDist[1] > 0.)
230       aD += aDist[1]*aDist[1];
231     if (aDist[2] > 0.)
232       aD += aDist[2]*aDist[2];
233     if (aD < theRadius*theRadius) {
234       // the box intersects the solid sphere; check if it is completely
235       // inside the circle (in such case return isOut==True)
236       aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
237       aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
238       aDist[2] = aDistC[2] + Standard_Real(myHSize[2]);
239       if (aDist[0]*aDist[0]+aDist[1]*aDist[1]+aDist[2]*aDist[2]
240            > theRadius*theRadius)
241         aResult = Standard_False;
242     }
243   }
244   return aResult;
245 }
246
247 //=======================================================================
248 //function : IsOut
249 //purpose  : Intersection Box - transformed Box
250 //=======================================================================
251
252 Standard_Boolean Bnd_B3x::IsOut (const Bnd_B3x& theBox,
253                                  const gp_Trsf& theTrsf) const
254 {
255   Standard_Boolean aResult (Standard_False);
256   const gp_TrsfForm aForm = theTrsf.Form();
257   const Standard_Real aScale = theTrsf.ScaleFactor();
258   const Standard_Real aScaleAbs = Abs(aScale);
259   if (aForm == gp_Translation || aForm == gp_Identity ||
260       aForm == gp_PntMirror   || aForm == gp_Scale)
261   {
262     aResult =
263       (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
264             - myCenter[0])
265          > RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
266        Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
267             - myCenter[1])
268          > RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1] ||
269        Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
270             - myCenter[2])
271          > RealType (theBox.myHSize[2]*aScaleAbs) + myHSize[2]);
272
273   }
274   else {
275     // theBox is transformed and we check the resulting (enlarged) box against
276     // 'this' box.
277     const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
278
279     gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
280                     (Standard_Real)theBox.myCenter[1],
281                     (Standard_Real)theBox.myCenter[2]);
282     theTrsf.Transforms (aCenter);
283     const Standard_Real aDist[3] = {
284       aCenter.X() - (Standard_Real)myCenter[0],
285       aCenter.Y() - (Standard_Real)myCenter[1],
286       aCenter.Z() - (Standard_Real)myCenter[2]
287     };
288     const Standard_Real aMatAbs[9] = {
289       Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3]), Abs(aMat[4]),
290       Abs(aMat[5]), Abs(aMat[6]), Abs(aMat[7]), Abs(aMat[8])
291     };
292     if (Abs(aDist[0]) > (aScaleAbs*(aMatAbs[0]*theBox.myHSize[0]+
293                                     aMatAbs[1]*theBox.myHSize[1]+
294                                     aMatAbs[2]*theBox.myHSize[2]) +
295                          (Standard_Real)myHSize[0])    ||
296         Abs(aDist[1]) > (aScaleAbs*(aMatAbs[3]*theBox.myHSize[0]+
297                                     aMatAbs[4]*theBox.myHSize[1]+
298                                     aMatAbs[5]*theBox.myHSize[2]) +
299                          (Standard_Real)myHSize[1])    ||
300         Abs(aDist[2]) > (aScaleAbs*(aMatAbs[6]*theBox.myHSize[0]+
301                                     aMatAbs[7]*theBox.myHSize[1]+
302                                     aMatAbs[8]*theBox.myHSize[2]) +
303                          (Standard_Real)myHSize[2]))
304       aResult = Standard_True;
305
306     else {
307     // theBox is rotated, scaled and translated. We apply the reverse
308     // translation and scaling then check against the rotated box 'this'
309     if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
310          > theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
311                                           aMatAbs[3]*myHSize[1] +
312                                           aMatAbs[6]*myHSize[2])) ||
313         (Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
314          > theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
315                                           aMatAbs[4]*myHSize[1] +
316                                           aMatAbs[7]*myHSize[2])) ||
317         (Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
318          > theBox.myHSize[2]*aScaleAbs + (aMatAbs[2]*myHSize[0] +
319                                           aMatAbs[5]*myHSize[1] +
320                                           aMatAbs[8]*myHSize[2])))
321         aResult = Standard_True;
322     }
323   }
324   return aResult;
325 }
326
327 //=======================================================================
328 //function : IsOut
329 //purpose  : 
330 //=======================================================================
331
332 Standard_Boolean Bnd_B3x::IsOut (const gp_Ax3& thePlane) const
333 {
334   if (IsVoid())
335     return Standard_True;
336   const gp_XYZ& anOrigin = thePlane.Location().XYZ();
337   const gp_XYZ& aDir     = thePlane.Direction().XYZ();
338   const gp_XYZ  aBoxCenter ((Standard_Real)myCenter[0],
339                             (Standard_Real)myCenter[1],
340                             (Standard_Real)myCenter[2]);
341   const Standard_Real aDist0 = (aBoxCenter - anOrigin) * aDir;
342   // Find the signed distances from two opposite corners of the box to the plane
343   // If the distances are not the same sign, then the plane crosses the box
344   const Standard_Real aDist1 =   // proj of HSize on aDir
345     Standard_Real(myHSize[0]) * Abs(aDir.X()) +
346     Standard_Real(myHSize[1]) * Abs(aDir.Y()) +
347     Standard_Real(myHSize[2]) * Abs(aDir.Z());
348   return ((aDist0 + aDist1) * (aDist0 - aDist1) > 0.);
349 }
350
351 //=======================================================================
352 //function : IsOut
353 //purpose  : 
354 //=======================================================================
355
356 Standard_Boolean Bnd_B3x::IsOut (const gp_Ax1&          theLine,
357                                  const Standard_Boolean isRay,
358                                  const Standard_Real    theOverthickness) const
359 {
360   const Standard_Real aRes = gp::Resolution() * 100.;
361   if (IsVoid())
362     return Standard_True;
363   Standard_Real
364     anInter0[2] = {-RealLast(), RealLast()},
365     anInter1[2] = {-RealLast(), RealLast()};
366   const gp_XYZ& aDir = theLine.Direction().XYZ();
367   const gp_XYZ  aDiff ((Standard_Real)myCenter[0] - theLine.Location().X(),
368                        (Standard_Real)myCenter[1] - theLine.Location().Y(),
369                        (Standard_Real)myCenter[2] - theLine.Location().Z());
370
371   // Find the parameter interval in X dimention
372   Standard_Real aHSize = (Standard_Real)myHSize[0]+theOverthickness;
373   if (aDir.X() > aRes) {
374     anInter0[0]= (aDiff.X() - aHSize) / aDir.X();
375     anInter0[1]= (aDiff.X() + aHSize) / aDir.X();
376   } else if (aDir.X() < -aRes) {
377     anInter0[0]= (aDiff.X() + aHSize) / aDir.X();
378     anInter0[1]= (aDiff.X() - aHSize) / aDir.X();
379   } else
380     // the line is orthogonal to OX axis. Test for inclusion in box limits
381     if (Abs(aDiff.X()) > aHSize)
382       return Standard_True;
383   
384   // Find the parameter interval in Y dimention
385   aHSize = (Standard_Real)myHSize[1]+theOverthickness;
386   if (aDir.Y() > aRes) {
387     anInter1[0]= (aDiff.Y() - aHSize) / aDir.Y();
388     anInter1[1]= (aDiff.Y() + aHSize) / aDir.Y();
389   } else if (aDir.Y() < -aRes) {
390     anInter1[0]= (aDiff.Y() + aHSize) / aDir.Y();
391     anInter1[1]= (aDiff.Y() - aHSize) / aDir.Y();
392   } else
393     // the line is orthogonal to OY axis. Test for inclusion in box limits
394     if (Abs(aDiff.Y()) > aHSize)
395       return Standard_True;
396
397   // Intersect Y-interval with X-interval 
398   if (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes))
399     return Standard_True;
400   if (anInter1[0] > anInter0[0])
401     anInter0[0] = anInter1[0];
402   if (anInter1[1] < anInter0[1])
403     anInter0[1] = anInter1[1];
404   if (isRay && anInter0[1] < -aRes)
405     return Standard_True;
406
407   // Find the parameter interval in Z dimention
408   aHSize = (Standard_Real)myHSize[2]+theOverthickness;
409   if (aDir.Z() > aRes) {
410     anInter1[0]= (aDiff.Z() - aHSize) / aDir.Z();
411     anInter1[1]= (aDiff.Z() + aHSize) / aDir.Z();
412   } else if (aDir.Z() < -aRes) {
413     anInter1[0]= (aDiff.Z() + aHSize) / aDir.Z();
414     anInter1[1]= (aDiff.Z() - aHSize) / aDir.Z();
415   } else
416     // the line is orthogonal to OZ axis. Test for inclusion in box limits
417     return (Abs(aDiff.Z()) > aHSize);
418   if (isRay && anInter1[1] < -aRes)
419     return Standard_True;
420
421   return (anInter0[0] > (anInter1[1]+aRes) || anInter0[1] < (anInter1[0]-aRes));
422 }
423
424 //=======================================================================
425 //function : IsIn
426 //purpose  : Test the complete inclusion of this box in transformed theOtherBox
427 //=======================================================================
428
429 Standard_Boolean Bnd_B3x::IsIn (const Bnd_B3x& theBox,
430                                 const gp_Trsf& theTrsf) const
431 {
432   Standard_Boolean aResult (Standard_False);
433   const gp_TrsfForm aForm = theTrsf.Form();
434   const Standard_Real aScale = theTrsf.ScaleFactor();
435   const Standard_Real aScaleAbs = Abs(aScale);
436   if (aForm == gp_Translation || aForm == gp_Identity ||
437       aForm == gp_PntMirror   || aForm == gp_Scale)
438   {
439     aResult =
440       (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
441             - myCenter[0])
442          < RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
443        Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
444             - myCenter[1])
445          < RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1] &&
446        Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
447             - myCenter[2])
448          < RealType (theBox.myHSize[2]*aScaleAbs) - myHSize[2]);
449
450   } else {
451     // theBox is rotated, scaled and translated. We apply the reverse
452     // translation and scaling then check against the rotated box 'this'
453     const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
454     gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
455                     (Standard_Real)theBox.myCenter[1],
456                     (Standard_Real)theBox.myCenter[2]);
457     theTrsf.Transforms (aCenter);
458     const Standard_Real aDist[3] = {
459       aCenter.X() - (Standard_Real)myCenter[0],
460       aCenter.Y() - (Standard_Real)myCenter[1],
461       aCenter.Z() - (Standard_Real)myCenter[2]
462     };
463     if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
464          < theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
465                                           Abs(aMat[3])*myHSize[1] +
466                                           Abs(aMat[6])*myHSize[2])) &&
467         (Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
468          < theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
469                                           Abs(aMat[4])*myHSize[1] +
470                                           Abs(aMat[7])*myHSize[2])) &&
471         (Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
472          < theBox.myHSize[2]*aScaleAbs - (Abs(aMat[2])*myHSize[0] +
473                                           Abs(aMat[5])*myHSize[1] +
474                                           Abs(aMat[8])*myHSize[2])))
475       aResult = Standard_True;
476   }
477   return aResult;
478 }
479