1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

102
src/Bnd/Bnd.cdl Executable file
View File

@@ -0,0 +1,102 @@
-- File: Bnd.cdl
-- Created: Tue Jan 8 09:53:22 1991
-- Author: Didier Piffault
-- <rle@topsn3>
---Copyright: Matra Datavision 1991, 1992
--- Modified by hl1 (juillet 96) : ajout de SeqOfBox
--------------------------------------------------------
--- I n f o r m a t i o n ---
--- ---
--- The Bnd_Tool class is now in the package Intf. ---
--------------------------------------------------------
package Bnd
---Purpose: Supports the Boundings Volumes. A Bounding Volume
-- is used to bound a shape to optimising algorithms.
-- If a point is outside the Bounding Volume of a
-- shape it is also outside the shape. The contrary
-- is not necessarily true.
--
-- Various classes are then implemented to describe
-- the usual Bounding volumes. Not all classes are
-- implemented.
--
-- in 3D :
-- Box -- Implemented
-- BoundSortBox -- Implemented
--
-- in 2D :
-- Box2d -- Implemented
-- BoundSortBox2d -- Implemented
--
--
---Level : Public.
-- All methods of all classes will be public.
uses Standard,
TCollection,
TColStd,
gp
is class Box;
---Purpose: A box parallel to the main axes.
-- A 3D Bounding.
class Array1OfBox instantiates Array1 from TCollection
(Box from Bnd);
class HArray1OfBox instantiates HArray1 from TCollection
(Box from Bnd,
Array1OfBox from Bnd);
class Box2d;
---Purpose: A rectangle parallel to the main axes.
-- A 2D Bounding.
class Array1OfBox2d instantiates Array1 from TCollection
(Box2d from Bnd);
class HArray1OfBox2d instantiates HArray1 from TCollection
(Box2d from Bnd,
Array1OfBox2d from Bnd);
class BoundSortBox2d;
---Purpose: A tool to sort a set of Box2d and compare with an
-- other Box2d to find the list of touched items.
class BoundSortBox;
---Purpose: A tool to sort a set of Box and compare with an
-- other Box to find the list of touched items.
class SeqOfBox instantiates Sequence from TCollection (Box from Bnd);
---Purpose: This sequence used to store the bounding boxes of sub-Shapes.
--- Optimized boxes (no Gap, no infinity supported)
generic class B2x;
generic class B3x;
class B2d instantiates B2x from Bnd (Real from Standard);
-- 2D box with double-precision coordinates
class B2f instantiates B2x from Bnd (ShortReal from Standard);
-- 2D box with single-precision coordinates
class B3d instantiates B3x from Bnd (Real from Standard);
-- 3D box with double-precision coordinates
class B3f instantiates B3x from Bnd (ShortReal from Standard);
-- 3D box with single-precision coordinates
end Bnd;

142
src/Bnd/Bnd_B2x.cdl Executable file
View File

@@ -0,0 +1,142 @@
-- File: Bnd_B2x.cdl
-- Created: Thu Sep 8 17:39:16 2005
-- Author: Alexander GRIGORIEV
-- <agv@opencascade.com>
---Copyright: Open Cascade 2005
generic class B2x from Bnd (RealType as any)
uses XY from gp,
Ax2d from gp,
Pnt2d from gp,
Trsf2d from gp
is
Create returns B2x from Bnd;
---Purpose: Empty constructor.
---C++: inline
Create (theCenter: XY from gp; theHSize : XY from gp)
returns B2x from Bnd;
---Purpose: Constructor.
---C++: inline
IsVoid (me)
returns Boolean from Standard;
---Purpose: Returns True if the box is void (non-initialized).
---C++: inline
Clear (me:in out);
---Purpose: Reset the box data.
---C++: inline
Add (me:in out; thePnt: XY from gp);
---Purpose: Update the box by a point.
Add (me:in out; thePnt: Pnt2d from gp);
---Purpose: Update the box by a point.
Add (me:in out; theBox: B2x from Bnd);
---Purpose: Update the box by another box.
---C++: inline
CornerMin (me)
returns XY from gp;
---Purpose: Query a box corner: (Center - HSize). You must make sure that
-- the box is NOT VOID (see IsVoid()), otherwise the method returns
-- irrelevant result.
---C++: inline
CornerMax (me)
returns XY from gp;
---Purpose: Query a box corner: (Center + HSize). You must make sure that
-- the box is NOT VOID (see IsVoid()), otherwise the method returns
-- irrelevant result.
---C++: inline
SquareExtent(me)
returns Real from Standard;
---Purpose: Query the square diagonal. If the box is VOID (see method IsVoid())
-- then a very big real value is returned.
---C++: inline
Enlarge (me:in out; theDiff: Real from Standard);
---Purpose: Extend the Box by the absolute value of theDiff.
---C++: inline
Limit (me:in out; theOtherBox: B2x from Bnd)
returns Boolean from Standard;
---Purpose: Limit the Box by the internals of theOtherBox.
-- Returns True if the limitation takes place, otherwise False
-- indicating that the boxes do not intersect.
Transformed (me; theTrsf: Trsf2d from gp)
returns B2x from Bnd;
---Purpose: Transform the bounding box with the given transformation.
-- The resulting box will be larger if theTrsf contains rotation.
IsOut (me; thePnt: XY from gp)
returns Boolean from Standard;
---Purpose: Check the given point for the inclusion in the Box.
-- Returns True if the point is outside.
---C++: inline
IsOut (me; theCenter : XY from gp;
theRadius : Real from Standard;
isCircleHollow: Boolean from Standard = Standard_False)
returns Boolean from Standard;
---Purpose: Check a circle for the intersection with the current box.
-- Returns True if there is no intersection between boxes.
IsOut (me; theOtherBox: B2x from Bnd)
returns Boolean from Standard;
---Purpose: Check the given box for the intersection with the current box.
-- Returns True if there is no intersection between boxes.
---C++: inline
IsOut (me; theOtherBox: B2x from Bnd; theTrsf: Trsf2d from gp)
returns Boolean from Standard;
---Purpose: Check the given box oriented by the given transformation
-- for the intersection with the current box.
-- Returns True if there is no intersection between boxes.
IsOut (me; theLine: Ax2d from gp)
returns Boolean from Standard;
---Purpose: Check the given Line for the intersection with the current box.
-- Returns True if there is no intersection.
IsOut (me; theP0, theP1: XY from gp)
returns Boolean from Standard;
---Purpose: Check the Segment defined by the couple of input points
-- for the intersection with the current box.
-- Returns True if there is no intersection.
IsIn (me; theBox: B2x from Bnd)
returns Boolean from Standard;
---Purpose: Check that the box 'this' is inside the given box 'theBox'. Returns
-- True if 'this' box is fully inside 'theBox'.
---C++: inline
IsIn (me; theBox: B2x from Bnd; theTrsf: Trsf2d from gp)
returns Boolean from Standard;
---Purpose: Check that the box 'this' is inside the given box 'theBox'
-- transformed by 'theTrsf'. Returns True if 'this' box is fully
-- inside the transformed 'theBox'.
SetCenter (me: in out; theCenter: XY from gp);
---Purpose: Set the Center coordinates
---C++: inline
SetHSize (me: in out; theHSize: XY from gp);
---Purpose: Set the HSize (half-diagonal) coordinates.
-- All components of theHSize must be non-negative.
---C++: inline
fields
myCenter : RealType[2] is protected;
myHSize : RealType[2] is protected;
end B2x from Bnd;

340
src/Bnd/Bnd_B2x.gxx Executable file
View File

@@ -0,0 +1,340 @@
// File: Bnd_B2x.gxx
// Created: 08.09.05 19:37:06
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2005
inline Standard_Boolean _compareDist (const RealType aHSize[2],
const RealType aDist[2])
{
return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
}
inline Standard_Boolean _compareDistD (const gp_XY& aHSize, const gp_XY& aDist)
{
return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
}
//=======================================================================
//function : Add
//purpose : Update the box by a point
//=======================================================================
void Bnd_B2x::Add (const gp_XY& thePnt) {
if (IsVoid()) {
myCenter[0] = RealType(thePnt.X());
myCenter[1] = RealType(thePnt.Y());
myHSize [0] = 0.;
myHSize [1] = 0.;
} else {
const RealType aDiff[2] = {
RealType(thePnt.X()) - myCenter[0],
RealType(thePnt.Y()) - myCenter[1]
};
if (aDiff[0] > myHSize[0]) {
const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
myCenter[0] += aShift;
myHSize [0] += aShift;
} else if (aDiff[0] < -myHSize[0]) {
const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
myCenter[0] += aShift;
myHSize [0] -= aShift;
}
if (aDiff[1] > myHSize[1]) {
const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
myCenter[1] += aShift;
myHSize [1] += aShift;
} else if (aDiff[1] < -myHSize[1]) {
const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
myCenter[1] += aShift;
myHSize [1] -= aShift;
}
}
}
//=======================================================================
//function : Limit
//purpose : limit the current box with the internals of theBox
//=======================================================================
Standard_Boolean Bnd_B2x::Limit (const Bnd_B2x& theBox)
{
Standard_Boolean aResult (Standard_False);
const RealType diffC[2] = {
theBox.myCenter[0] - myCenter[0],
theBox.myCenter[1] - myCenter[1]
};
const RealType sumH[2] = {
theBox.myHSize[0] + myHSize[0],
theBox.myHSize[1] + myHSize[1]
};
// check the condition IsOut
if (_compareDist (sumH, diffC) == Standard_False) {
const RealType diffH[2] = {
theBox.myHSize[0] - myHSize[0],
theBox.myHSize[1] - myHSize[1]
};
if (diffC[0] - diffH[0] > 0.) {
const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
myCenter[0] += aShift;
myHSize [0] -= aShift;
} else if (diffC[0] + diffH[0] < 0.) {
const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
myCenter[0] += aShift;
myHSize [0] += aShift;
}
if (diffC[1] - diffH[1] > 0.) {
const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
myCenter[1] += aShift;
myHSize [1] -= aShift;
} else if (diffC[1] + diffH[1] < 0.) {
const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
myCenter[1] += aShift;
myHSize [1] += aShift;
}
aResult = Standard_True;
}
return aResult;
}
//=======================================================================
//function : Transformed
//purpose :
//=======================================================================
Bnd_B2x Bnd_B2x::Transformed (const gp_Trsf2d& theTrsf) const
{
Bnd_B2x aResult;
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Identity)
aResult = * this;
else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
{
aResult.myCenter[0] =
(RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
aResult.myCenter[1] =
(RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
} else {
gp_XY aCenter ((Standard_Real)myCenter[0],
(Standard_Real)myCenter[1]);
theTrsf.Transforms (aCenter);
aResult.myCenter[0] = (RealType)aCenter.X();
aResult.myCenter[1] = (RealType)aCenter.Y();
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
Abs(aMat[1]) * myHSize[1]));
aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0]+
Abs(aMat[3]) * myHSize[1]));
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - Circle
//=======================================================================
Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theCenter,
const Standard_Real theRadius,
const Standard_Boolean isCircleHollow) const
{
Standard_Boolean aResult (Standard_True);
if (isCircleHollow == Standard_False) {
// vector from the center of the circle to the nearest box face
const Standard_Real aDist[2] = {
Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])
};
Standard_Real aD (0.);
if (aDist[0] > 0.)
aD = aDist[0]*aDist[0];
if (aDist[1] > 0.)
aD += aDist[1]*aDist[1];
aResult = (aD > theRadius*theRadius);
} else {
const Standard_Real aDistC[2] = {
Abs(theCenter.X()-Standard_Real(myCenter[0])),
Abs(theCenter.Y()-Standard_Real(myCenter[1]))
};
// vector from the center of the circle to the nearest box face
Standard_Real aDist[2] = {
aDistC[0] - Standard_Real(myHSize[0]),
aDistC[1] - Standard_Real(myHSize[1])
};
Standard_Real aD (0.);
if (aDist[0] > 0.)
aD = aDist[0]*aDist[0];
if (aDist[1] > 0.)
aD += aDist[1]*aDist[1];
if (aD < theRadius*theRadius) {
// the box intersects the solid circle; check if it is completely
// inside the circle (in such case return isOut==True)
aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
if (aDist[0]*aDist[0]+aDist[1]*aDist[1] > theRadius*theRadius)
aResult = Standard_False;
}
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - transformed Box
//=======================================================================
Standard_Boolean Bnd_B2x::IsOut (const Bnd_B2x& theBox,
const gp_Trsf2d& theTrsf) const
{
Standard_Boolean aResult (Standard_False);
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Translation || aForm == gp_Identity ||
aForm == gp_PntMirror || aForm == gp_Scale)
{
aResult =
(Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
- myCenter[0])
> RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
- myCenter[1])
> RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1]);
}
else {
// theBox is transformed and we check the resulting (enlarged) box against
// 'this' box.
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
(Standard_Real)theBox.myCenter[1]);
theTrsf.Transforms (aCenter);
const Standard_Real aDist[2] = {
aCenter.X() - (Standard_Real)myCenter[0],
aCenter.Y() - (Standard_Real)myCenter[1]
};
const Standard_Real aMatAbs[4] = {
Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])
};
if (Abs(aDist[0]) > (aScaleAbs * (aMatAbs[0]*theBox.myHSize[0]+
aMatAbs[1]*theBox.myHSize[1]) +
(Standard_Real)myHSize[0]) ||
Abs(aDist[1]) > (aScaleAbs * (aMatAbs[2]*theBox.myHSize[0]+
aMatAbs[3]*theBox.myHSize[1]) +
(Standard_Real)myHSize[1]))
aResult = Standard_True;
else {
// theBox is rotated, scaled and translated. We apply the reverse
// translation and scaling then check against the rotated box 'this'
if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
> theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
aMatAbs[2]*myHSize[1])) ||
(Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
> theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
aMatAbs[3]*myHSize[1])))
aResult = Standard_True;
}
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - Line
//=======================================================================
Standard_Boolean Bnd_B2x::IsOut (const gp_Ax2d& theLine) const
{
if (IsVoid())
return Standard_True;
// Intersect the line containing the segment.
const Standard_Real aProd[3] = {
theLine.Direction().XY() ^ (gp_XY (myCenter[0] - theLine.Location().X(),
myCenter[1] - theLine.Location().Y())),
theLine.Direction().X() * Standard_Real(myHSize[1]),
theLine.Direction().Y() * Standard_Real(myHSize[0])
};
return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - Segment
//=======================================================================
Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theP0, const gp_XY& theP1) const
{
Standard_Boolean aResult (Standard_True);
if (IsVoid() == Standard_False)
{
// Intersect the line containing the segment.
const gp_XY aSegDelta (theP1 - theP0);
const Standard_Real aProd[3] = {
aSegDelta ^ (gp_XY (myCenter[0], myCenter[1]) - theP0),
aSegDelta.X() * Standard_Real(myHSize[1]),
aSegDelta.Y() * Standard_Real(myHSize[0])
};
if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
{
// Intersection with line detected; check the segment as bounding box
const gp_XY aHSeg (0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
const gp_XY aHSegAbs (Abs(aHSeg.X()), Abs(aHSeg.Y()));
aResult = _compareDistD (gp_XY((Standard_Real)myHSize[0],
(Standard_Real)myHSize[1]) + aHSegAbs,
theP0 + aHSeg-gp_XY((Standard_Real)myCenter[0],
(Standard_Real)myCenter[1]));
}
}
return aResult;
}
//=======================================================================
//function : IsIn
//purpose : Test the complete inclusion of this box in transformed theOtherBox
//=======================================================================
Standard_Boolean Bnd_B2x::IsIn (const Bnd_B2x& theBox,
const gp_Trsf2d& theTrsf) const
{
Standard_Boolean aResult (Standard_False);
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Translation || aForm == gp_Identity ||
aForm == gp_PntMirror || aForm == gp_Scale)
{
aResult =
(Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
- myCenter[0])
< RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
- myCenter[1])
< RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1]);
} else {
// theBox is rotated, scaled and translated. We apply the reverse
// translation and scaling then check against the rotated box 'this'
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
(Standard_Real)theBox.myCenter[1]);
theTrsf.Transforms (aCenter);
const Standard_Real aDist[2] = {
aCenter.X() - (Standard_Real)myCenter[0],
aCenter.Y() - (Standard_Real)myCenter[1]
};
if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
< theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
Abs(aMat[2])*myHSize[1])) &&
(Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
< theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
Abs(aMat[3])*myHSize[1])))
aResult = Standard_True;
}
return aResult;
}

154
src/Bnd/Bnd_B2x.lxx Executable file
View File

@@ -0,0 +1,154 @@
// File: Bnd_B2x.lxx
// Created: 08.09.05 20:13:23
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2005
#include <gp_Pnt2d.hxx>
#ifndef Bnd_B2x_RealLast
#define Bnd_B2x_RealLast RealType(1e30);
#endif
/**
* Empty constructor
*/
inline Bnd_B2x::Bnd_B2x ()
{
Clear();
}
/**
* Constructor.
* @param theCenter
* Center of the created box
* @param theHSize
* Half-diagonal of the box, both X and Y should be non-negative
*/
inline Bnd_B2x::Bnd_B2x (const gp_XY& theCenter,
const gp_XY& theHSize)
{
myCenter[0] = RealType(theCenter.X());
myCenter[1] = RealType(theCenter.Y());
myHSize[0] = RealType(theHSize.X());
myHSize[1] = RealType(theHSize.Y());
}
/**
* Reset the box data.
*/
inline void Bnd_B2x::Clear ()
{
myCenter[0] = Bnd_B2x_RealLast;
myCenter[1] = Bnd_B2x_RealLast;
myHSize[0] = -Bnd_B2x_RealLast;
myHSize[1] = -Bnd_B2x_RealLast;
}
/**
* Check if the box is empty.
*/
inline Standard_Boolean Bnd_B2x::IsVoid () const
{
return (myHSize[0] < -1e-5);
}
/**
* Update the box by point.
*/
inline void Bnd_B2x::Add (const gp_Pnt2d& thePnt)
{
Add (thePnt.XY());
}
/**
* Update the box by another box.
*/
inline void Bnd_B2x::Add (const Bnd_B2x& theBox)
{
if (theBox.IsVoid() == Standard_False) {
Add (theBox.CornerMin());
Add (theBox.CornerMax());
}
}
/**
* Query a box corner.
*/
inline gp_XY Bnd_B2x::CornerMin () const
{
return gp_XY (myCenter[0] - myHSize[0], myCenter[1] - myHSize[1]);
}
/**
* Query a box corner.
*/
inline gp_XY Bnd_B2x::CornerMax () const
{
return gp_XY (myCenter[0] + myHSize[0], myCenter[1] + myHSize[1]);
}
/**
* Query the square diagonal.
*/
inline Standard_Real Bnd_B2x::SquareExtent () const
{
return 4 * (myHSize[0] * myHSize[0] + myHSize[1] * myHSize[1]);
}
/**
* Set the Center coordinates.
*/
inline void Bnd_B2x::SetCenter (const gp_XY& theCenter)
{
myCenter[0] = RealType(theCenter.X());
myCenter[1] = RealType(theCenter.Y());
}
/**
* Set the HSize coordinates.
*/
inline void Bnd_B2x::SetHSize (const gp_XY& theHSize)
{
myHSize[0] = RealType(theHSize.X());
myHSize[1] = RealType(theHSize.Y());
}
/**
* Increase the box.
* @param aDiff
* absolute value of this parameter is added to the box size in all dimensions.
*/
inline void Bnd_B2x::Enlarge (const Standard_Real aDiff)
{
const RealType aD = RealType(Abs(aDiff));
myHSize[0] += aD;
myHSize[1] += aD;
}
/**
* Intersection Box - Point
*/
inline Standard_Boolean Bnd_B2x::IsOut (const gp_XY& thePnt) const
{
return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0] ||
Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1]);
}
/**
* Intersection Box-Box.
*/
inline Standard_Boolean Bnd_B2x::IsOut (const Bnd_B2x& theBox) const
{
return (Abs(theBox.myCenter[0]-myCenter[0]) > theBox.myHSize[0]+myHSize[0] ||
Abs(theBox.myCenter[1]-myCenter[1]) > theBox.myHSize[1]+myHSize[1]);
}
/**
* Test the complete inclusion of this box in theBox.
*/
inline Standard_Boolean Bnd_B2x::IsIn (const Bnd_B2x& theBox) const
{
return (Abs(theBox.myCenter[0]-myCenter[0]) < theBox.myHSize[0]-myHSize[0] &&
Abs(theBox.myCenter[1]-myCenter[1]) < theBox.myHSize[1]-myHSize[1]);
}

151
src/Bnd/Bnd_B3x.cdl Executable file
View File

@@ -0,0 +1,151 @@
-- File: Bnd_B3x.cdl
-- Created: Thu Sep 8 18:12:21 2005
-- Author: Alexander GRIGORIEV
-- <agv@opencascade.com>
---Copyright: Open Cascade 2005
generic class B3x from Bnd (RealType as any)
uses XYZ from gp,
Pnt from gp,
Ax1 from gp,
Ax3 from gp,
Trsf from gp
is
Create returns B3x from Bnd;
---Purpose: Empty constructor.
---C++: inline
Create (theCenter: XYZ from gp; theHSize : XYZ from gp)
returns B3x from Bnd;
---Purpose: Constructor.
---C++: inline
IsVoid (me)
returns Boolean from Standard;
---Purpose: Returns True if the box is void (non-initialized).
---C++: inline
Clear (me:in out);
---Purpose: Reset the box data.
---C++: inline
Add (me:in out; thePnt: XYZ from gp);
---Purpose: Update the box by a point.
Add (me: in out; thePnt: Pnt from gp);
---Purpose: Update the box by a point.
---C++: inline
Add (me:in out; theBox: B3x from Bnd);
---Purpose: Update the box by another box.
---C++: inline
CornerMin (me)
returns XYZ from gp;
---Purpose: Query the lower corner: (Center - HSize). You must make sure that
-- the box is NOT VOID (see IsVoid()), otherwise the method returns
-- irrelevant result.
---C++: inline
CornerMax (me)
returns XYZ from gp;
---Purpose: Query the upper corner: (Center + HSize). You must make sure that
-- the box is NOT VOID (see IsVoid()), otherwise the method returns
-- irrelevant result.
---C++: inline
SquareExtent(me)
returns Real from Standard;
---Purpose: Query the square diagonal. If the box is VOID (see method IsVoid())
-- then a very big real value is returned.
---C++: inline
Enlarge (me:in out; theDiff: Real from Standard);
---Purpose: Extend the Box by the absolute value of theDiff.
---C++: inline
Limit (me:in out; theOtherBox: B3x from Bnd)
returns Boolean from Standard;
---Purpose: Limit the Box by the internals of theOtherBox.
-- Returns True if the limitation takes place, otherwise False
-- indicating that the boxes do not intersect.
Transformed (me; theTrsf: Trsf from gp)
returns B3x from Bnd;
---Purpose: Transform the bounding box with the given transformation.
-- The resulting box will be larger if theTrsf contains rotation.
IsOut (me; thePnt: XYZ from gp)
returns Boolean from Standard;
---Purpose: Check the given point for the inclusion in the Box.
-- Returns True if the point is outside.
---C++: inline
IsOut (me; theCenter : XYZ from gp;
theRadius : Real from Standard;
isSphereHollow: Boolean from Standard = Standard_False)
returns Boolean from Standard;
---Purpose: Check a sphere for the intersection with the current box.
-- Returns True if there is no intersection between boxes. If the
-- parameter 'IsSphereHollow' is True, then the intersection is not
-- reported for a box that is completely inside the sphere (otherwise
-- this method would report an intersection).
IsOut (me; theOtherBox: B3x from Bnd)
returns Boolean from Standard;
---Purpose: Check the given box for the intersection with the current box.
-- Returns True if there is no intersection between boxes.
---C++: inline
IsOut (me; theOtherBox: B3x from Bnd; theTrsf: Trsf from gp)
returns Boolean from Standard;
---Purpose: Check the given box oriented by the given transformation
-- for the intersection with the current box.
-- Returns True if there is no intersection between boxes.
IsOut (me; theLine : Ax1 from gp;
isRay : Boolean from Standard = Standard_False;
theOverthickness : Real from Standard = 0.0)
returns Boolean from Standard;
---Purpose: Check the given Line for the intersection with the current box.
-- Returns True if there is no intersection.
-- isRay==True means intersection check with the positive half-line
-- theOverthickness is the addition to the size of the current box
-- (may be negative). If positive, it can be treated as the thickness
-- of the line 'theLine' or the radius of the cylinder along 'theLine'
IsOut (me; thePlane: Ax3 from gp)
returns Boolean from Standard;
---Purpose: Check the given Plane for the intersection with the current box.
-- Returns True if there is no intersection.
IsIn (me; theBox: B3x from Bnd)
returns Boolean from Standard;
---Purpose: Check that the box 'this' is inside the given box 'theBox'. Returns
-- True if 'this' box is fully inside 'theBox'.
---C++: inline
IsIn (me; theBox: B3x from Bnd; theTrsf: Trsf from gp)
returns Boolean from Standard;
---Purpose: Check that the box 'this' is inside the given box 'theBox'
-- transformed by 'theTrsf'. Returns True if 'this' box is fully
-- inside the transformed 'theBox'.
SetCenter (me: in out; theCenter: XYZ from gp);
---Purpose: Set the Center coordinates
---C++: inline
SetHSize (me: in out; theHSize: XYZ from gp);
---Purpose: Set the HSize (half-diagonal) coordinates.
-- All components of theHSize must be non-negative.
---C++: inline
fields
myCenter : RealType[3] is protected;
myHSize : RealType[3] is protected;
end B3x from Bnd;

464
src/Bnd/Bnd_B3x.gxx Executable file
View File

@@ -0,0 +1,464 @@
// File: Bnd_B3x.gxx
// Created: 08.09.05 20:32:39
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2005
inline Standard_Boolean _compareDist (const RealType aHSize[3],
const RealType aDist [3])
{
return (Abs(aDist[0]) > aHSize[0] ||
Abs(aDist[1]) > aHSize[1] ||
Abs(aDist[2]) > aHSize[2]);
}
inline Standard_Boolean _compareDistD (const gp_XYZ& aHSize,const gp_XYZ& aDist)
{
return (Abs(aDist.X()) > aHSize.X() ||
Abs(aDist.Y()) > aHSize.Y() ||
Abs(aDist.Z()) > aHSize.Z());
}
//=======================================================================
//function : Add
//purpose : Update the box by a point
//=======================================================================
void Bnd_B3x::Add (const gp_XYZ& thePnt) {
if (IsVoid()) {
myCenter[0] = RealType(thePnt.X());
myCenter[1] = RealType(thePnt.Y());
myCenter[2] = RealType(thePnt.Z());
myHSize [0] = 0.;
myHSize [1] = 0.;
myHSize [2] = 0.;
} else {
const RealType aDiff[3] = {
RealType(thePnt.X()) - myCenter[0],
RealType(thePnt.Y()) - myCenter[1],
RealType(thePnt.Z()) - myCenter[2]
};
if (aDiff[0] > myHSize[0]) {
const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
myCenter[0] += aShift;
myHSize [0] += aShift;
} else if (aDiff[0] < -myHSize[0]) {
const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
myCenter[0] += aShift;
myHSize [0] -= aShift;
}
if (aDiff[1] > myHSize[1]) {
const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
myCenter[1] +=aShift;
myHSize [1] +=aShift;
} else if (aDiff[1] < -myHSize[1]) {
const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
myCenter[1] += aShift;
myHSize [1] -= aShift;
}
if (aDiff[2] > myHSize[2]) {
const RealType aShift = (aDiff[2] - myHSize[2]) / 2;
myCenter[2] +=aShift;
myHSize [2] +=aShift;
} else if (aDiff[2] < -myHSize[2]) {
const RealType aShift = (aDiff[2] + myHSize[2]) / 2;
myCenter[2] += aShift;
myHSize [2] -= aShift;
}
}
}
//=======================================================================
//function : Limit
//purpose : limit the current box with the internals of theBox
//=======================================================================
Standard_Boolean Bnd_B3x::Limit (const Bnd_B3x& theBox)
{
Standard_Boolean aResult (Standard_False);
const RealType diffC[3] = {
theBox.myCenter[0] - myCenter[0],
theBox.myCenter[1] - myCenter[1],
theBox.myCenter[2] - myCenter[2]
};
const RealType sumH[3] = {
theBox.myHSize[0] + myHSize[0],
theBox.myHSize[1] + myHSize[1],
theBox.myHSize[2] + myHSize[2]
};
// check the condition IsOut
if (_compareDist (sumH, diffC) == Standard_False) {
const RealType diffH[3] = {
theBox.myHSize[0] - myHSize[0],
theBox.myHSize[1] - myHSize[1],
theBox.myHSize[2] - myHSize[2]
};
if (diffC[0] - diffH[0] > 0.) {
const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
myCenter[0] += aShift;
myHSize [0] -= aShift;
} else if (diffC[0] + diffH[0] < 0.) {
const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
myCenter[0] += aShift;
myHSize [0] += aShift;
}
if (diffC[1] - diffH[1] > 0.) {
const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
myCenter[1] += aShift;
myHSize [1] -= aShift;
} else if (diffC[1] + diffH[1] < 0.) {
const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
myCenter[1] += aShift;
myHSize [1] += aShift;
}
if (diffC[2] - diffH[2] > 0.) {
const RealType aShift = (diffC[2] - diffH[2]) / 2; // positive
myCenter[2] += aShift;
myHSize [2] -= aShift;
} else if (diffC[2] + diffH[2] < 0.) {
const RealType aShift = (diffC[2] + diffH[2]) / 2; // negative
myCenter[2] += aShift;
myHSize [2] += aShift;
}
aResult = Standard_True;
}
return aResult;
}
//=======================================================================
//function : Transformed
//purpose :
//=======================================================================
Bnd_B3x Bnd_B3x::Transformed (const gp_Trsf& theTrsf) const
{
Bnd_B3x aResult;
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Identity)
aResult = * this;
else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
{
aResult.myCenter[0] =
(RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
aResult.myCenter[1] =
(RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
aResult.myCenter[2] =
(RealType)(myCenter[2] * aScale + theTrsf.TranslationPart().Z());
aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
aResult.myHSize[2] = (RealType)(myHSize[2] * aScaleAbs);
} else {
gp_XYZ aCenter ((Standard_Real)myCenter[0],
(Standard_Real)myCenter[1],
(Standard_Real)myCenter[2]);
theTrsf.Transforms (aCenter);
aResult.myCenter[0] = (RealType)aCenter.X();
aResult.myCenter[1] = (RealType)aCenter.Y();
aResult.myCenter[2] = (RealType)aCenter.Z();
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
Abs(aMat[1]) * myHSize[1]+
Abs(aMat[2]) * myHSize[2]));
aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[3]) * myHSize[0]+
Abs(aMat[4]) * myHSize[1]+
Abs(aMat[5]) * myHSize[2]));
aResult.myHSize[2] = (RealType)(aScaleAbs * (Abs(aMat[6]) * myHSize[0]+
Abs(aMat[7]) * myHSize[1]+
Abs(aMat[8]) * myHSize[2]));
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - Sphere
//=======================================================================
Standard_Boolean Bnd_B3x::IsOut (const gp_XYZ& theCenter,
const Standard_Real theRadius,
const Standard_Boolean isSphereHollow) const
{
Standard_Boolean aResult (Standard_True);
if (isSphereHollow == Standard_False) {
// vector from the center of the sphere to the nearest box face
const Standard_Real aDist[3] = {
Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1]),
Abs(theCenter.Z()-Standard_Real(myCenter[2])) - Standard_Real(myHSize[2])
};
Standard_Real aD (0.);
if (aDist[0] > 0.)
aD = aDist[0]*aDist[0];
if (aDist[1] > 0.)
aD += aDist[1]*aDist[1];
if (aDist[2] > 0.)
aD += aDist[2]*aDist[2];
aResult = (aD > theRadius*theRadius);
} else {
const Standard_Real aDistC[3] = {
Abs(theCenter.X()-Standard_Real(myCenter[0])),
Abs(theCenter.Y()-Standard_Real(myCenter[1])),
Abs(theCenter.Z()-Standard_Real(myCenter[2]))
};
// vector from the center of the sphere to the nearest box face
Standard_Real aDist[3] = {
aDistC[0] - Standard_Real(myHSize[0]),
aDistC[1] - Standard_Real(myHSize[1]),
aDistC[2] - Standard_Real(myHSize[2])
};
Standard_Real aD (0.);
if (aDist[0] > 0.)
aD = aDist[0]*aDist[0];
if (aDist[1] > 0.)
aD += aDist[1]*aDist[1];
if (aDist[2] > 0.)
aD += aDist[2]*aDist[2];
if (aD < theRadius*theRadius) {
// the box intersects the solid sphere; check if it is completely
// inside the circle (in such case return isOut==True)
aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
aDist[2] = aDistC[2] + Standard_Real(myHSize[2]);
if (aDist[0]*aDist[0]+aDist[1]*aDist[1]+aDist[2]*aDist[2]
> theRadius*theRadius)
aResult = Standard_False;
}
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose : Intersection Box - transformed Box
//=======================================================================
Standard_Boolean Bnd_B3x::IsOut (const Bnd_B3x& theBox,
const gp_Trsf& theTrsf) const
{
Standard_Boolean aResult (Standard_False);
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Translation || aForm == gp_Identity ||
aForm == gp_PntMirror || aForm == gp_Scale)
{
aResult =
(Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
- myCenter[0])
> RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
- myCenter[1])
> RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1] ||
Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
- myCenter[2])
> RealType (theBox.myHSize[2]*aScaleAbs) + myHSize[2]);
}
else {
// theBox is transformed and we check the resulting (enlarged) box against
// 'this' box.
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
(Standard_Real)theBox.myCenter[1],
(Standard_Real)theBox.myCenter[2]);
theTrsf.Transforms (aCenter);
const Standard_Real aDist[3] = {
aCenter.X() - (Standard_Real)myCenter[0],
aCenter.Y() - (Standard_Real)myCenter[1],
aCenter.Z() - (Standard_Real)myCenter[2]
};
const Standard_Real aMatAbs[9] = {
Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3]), Abs(aMat[4]),
Abs(aMat[5]), Abs(aMat[6]), Abs(aMat[7]), Abs(aMat[8])
};
if (Abs(aDist[0]) > (aScaleAbs*(aMatAbs[0]*theBox.myHSize[0]+
aMatAbs[1]*theBox.myHSize[1]+
aMatAbs[2]*theBox.myHSize[2]) +
(Standard_Real)myHSize[0]) ||
Abs(aDist[1]) > (aScaleAbs*(aMatAbs[3]*theBox.myHSize[0]+
aMatAbs[4]*theBox.myHSize[1]+
aMatAbs[5]*theBox.myHSize[2]) +
(Standard_Real)myHSize[1]) ||
Abs(aDist[2]) > (aScaleAbs*(aMatAbs[6]*theBox.myHSize[0]+
aMatAbs[7]*theBox.myHSize[1]+
aMatAbs[8]*theBox.myHSize[2]) +
(Standard_Real)myHSize[2]))
aResult = Standard_True;
else {
// theBox is rotated, scaled and translated. We apply the reverse
// translation and scaling then check against the rotated box 'this'
if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
> theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
aMatAbs[3]*myHSize[1] +
aMatAbs[6]*myHSize[2])) ||
(Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
> theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
aMatAbs[4]*myHSize[1] +
aMatAbs[7]*myHSize[2])) ||
(Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
> theBox.myHSize[2]*aScaleAbs + (aMatAbs[2]*myHSize[0] +
aMatAbs[5]*myHSize[1] +
aMatAbs[8]*myHSize[2])))
aResult = Standard_True;
}
}
return aResult;
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
Standard_Boolean Bnd_B3x::IsOut (const gp_Ax3& thePlane) const
{
if (IsVoid())
return Standard_True;
const gp_XYZ& anOrigin = thePlane.Location().XYZ();
const gp_XYZ& aDir = thePlane.Direction().XYZ();
const gp_XYZ aBoxCenter ((Standard_Real)myCenter[0],
(Standard_Real)myCenter[1],
(Standard_Real)myCenter[2]);
const Standard_Real aDist0 = (aBoxCenter - anOrigin) * aDir;
// Find the signed distances from two opposite corners of the box to the plane
// If the distances are not the same sign, then the plane crosses the box
const Standard_Real aDist1 = // proj of HSize on aDir
Standard_Real(myHSize[0]) * Abs(aDir.X()) +
Standard_Real(myHSize[1]) * Abs(aDir.Y()) +
Standard_Real(myHSize[2]) * Abs(aDir.Z());
return ((aDist0 + aDist1) * (aDist0 - aDist1) > 0.);
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
Standard_Boolean Bnd_B3x::IsOut (const gp_Ax1& theLine,
const Standard_Boolean isRay,
const Standard_Real theOverthickness) const
{
const Standard_Real aRes = gp::Resolution() * 100.;
if (IsVoid())
return Standard_True;
Standard_Real
anInter0[2] = {-RealLast(), RealLast()},
anInter1[2] = {-RealLast(), RealLast()};
const gp_XYZ& aDir = theLine.Direction().XYZ();
const gp_XYZ aDiff ((Standard_Real)myCenter[0] - theLine.Location().X(),
(Standard_Real)myCenter[1] - theLine.Location().Y(),
(Standard_Real)myCenter[2] - theLine.Location().Z());
// Find the parameter interval in X dimention
Standard_Real aHSize = (Standard_Real)myHSize[0]+theOverthickness;
if (aDir.X() > aRes) {
anInter0[0]= (aDiff.X() - aHSize) / aDir.X();
anInter0[1]= (aDiff.X() + aHSize) / aDir.X();
} else if (aDir.X() < -aRes) {
anInter0[0]= (aDiff.X() + aHSize) / aDir.X();
anInter0[1]= (aDiff.X() - aHSize) / aDir.X();
} else
// the line is orthogonal to OX axis. Test for inclusion in box limits
if (Abs(aDiff.X()) > aHSize)
return Standard_True;
// Find the parameter interval in Y dimention
aHSize = (Standard_Real)myHSize[1]+theOverthickness;
if (aDir.Y() > aRes) {
anInter1[0]= (aDiff.Y() - aHSize) / aDir.Y();
anInter1[1]= (aDiff.Y() + aHSize) / aDir.Y();
} else if (aDir.Y() < -aRes) {
anInter1[0]= (aDiff.Y() + aHSize) / aDir.Y();
anInter1[1]= (aDiff.Y() - aHSize) / aDir.Y();
} else
// the line is orthogonal to OY axis. Test for inclusion in box limits
if (Abs(aDiff.Y()) > aHSize)
return Standard_True;
// Intersect Y-interval with X-interval
if (anInter0[0] > (anInter1[1] + aRes) || anInter0[1] < (anInter1[0] - aRes))
return Standard_True;
if (anInter1[0] > anInter0[0])
anInter0[0] = anInter1[0];
if (anInter1[1] < anInter0[1])
anInter0[1] = anInter1[1];
if (isRay && anInter0[1] < -aRes)
return Standard_True;
// Find the parameter interval in Z dimention
aHSize = (Standard_Real)myHSize[2]+theOverthickness;
if (aDir.Z() > aRes) {
anInter1[0]= (aDiff.Z() - aHSize) / aDir.Z();
anInter1[1]= (aDiff.Z() + aHSize) / aDir.Z();
} else if (aDir.Z() < -aRes) {
anInter1[0]= (aDiff.Z() + aHSize) / aDir.Z();
anInter1[1]= (aDiff.Z() - aHSize) / aDir.Z();
} else
// the line is orthogonal to OZ axis. Test for inclusion in box limits
return (Abs(aDiff.Z()) > aHSize);
if (isRay && anInter1[1] < -aRes)
return Standard_True;
return (anInter0[0] > (anInter1[1]+aRes) || anInter0[1] < (anInter1[0]-aRes));
}
//=======================================================================
//function : IsIn
//purpose : Test the complete inclusion of this box in transformed theOtherBox
//=======================================================================
Standard_Boolean Bnd_B3x::IsIn (const Bnd_B3x& theBox,
const gp_Trsf& theTrsf) const
{
Standard_Boolean aResult (Standard_False);
const gp_TrsfForm aForm = theTrsf.Form();
const Standard_Real aScale = theTrsf.ScaleFactor();
const Standard_Real aScaleAbs = Abs(aScale);
if (aForm == gp_Translation || aForm == gp_Identity ||
aForm == gp_PntMirror || aForm == gp_Scale)
{
aResult =
(Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
- myCenter[0])
< RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
- myCenter[1])
< RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1] &&
Abs (RealType(theBox.myCenter[2]*aScale + theTrsf.TranslationPart().Y())
- myCenter[2])
< RealType (theBox.myHSize[2]*aScaleAbs) - myHSize[2]);
} else {
// theBox is rotated, scaled and translated. We apply the reverse
// translation and scaling then check against the rotated box 'this'
const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
gp_XYZ aCenter ((Standard_Real)theBox.myCenter[0],
(Standard_Real)theBox.myCenter[1],
(Standard_Real)theBox.myCenter[2]);
theTrsf.Transforms (aCenter);
const Standard_Real aDist[3] = {
aCenter.X() - (Standard_Real)myCenter[0],
aCenter.Y() - (Standard_Real)myCenter[1],
aCenter.Z() - (Standard_Real)myCenter[2]
};
if ((Abs(aMat[0]*aDist[0]+aMat[3]*aDist[1]+aMat[6]*aDist[2])
< theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
Abs(aMat[3])*myHSize[1] +
Abs(aMat[6])*myHSize[2])) &&
(Abs(aMat[1]*aDist[0]+aMat[4]*aDist[1]+aMat[7]*aDist[2])
< theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
Abs(aMat[4])*myHSize[1] +
Abs(aMat[7])*myHSize[2])) &&
(Abs(aMat[2]*aDist[0]+aMat[5]*aDist[1]+aMat[8]*aDist[2])
< theBox.myHSize[2]*aScaleAbs - (Abs(aMat[2])*myHSize[0] +
Abs(aMat[5])*myHSize[1] +
Abs(aMat[8])*myHSize[2])))
aResult = Standard_True;
}
return aResult;
}

170
src/Bnd/Bnd_B3x.lxx Executable file
View File

@@ -0,0 +1,170 @@
// File: Bnd_B3x.lxx
// Created: 08.09.05 20:55:36
// Author: Alexander GRIGORIEV
// Copyright: Open Cascade 2005
#include <gp_Pnt.hxx>
#ifndef Bnd_B3x_RealLast
#define Bnd_B3x_RealLast RealType(1e30);
#endif
/**
* Empty constructor
*/
inline Bnd_B3x::Bnd_B3x ()
{
Clear();
}
/**
* Constructor.
* @param theCenter
* Center of the created box
* @param theHSize
* Half-diagonal of the box, both X and Y should be non-negative
*/
inline Bnd_B3x::Bnd_B3x (const gp_XYZ& theCenter,
const gp_XYZ& theHSize)
{
myCenter[0] = RealType(theCenter.X());
myCenter[1] = RealType(theCenter.Y());
myCenter[2] = RealType(theCenter.Z());
myHSize[0] = RealType(theHSize.X());
myHSize[1] = RealType(theHSize.Y());
myHSize[2] = RealType(theHSize.Z());
}
/**
* Reset the box data.
*/
inline void Bnd_B3x::Clear ()
{
myCenter[0] = Bnd_B3x_RealLast;
myCenter[1] = Bnd_B3x_RealLast;
myCenter[2] = Bnd_B3x_RealLast;
myHSize[0] = -Bnd_B3x_RealLast;
myHSize[1] = -Bnd_B3x_RealLast;
myHSize[2] = -Bnd_B3x_RealLast;
}
/**
* Check if the box is empty.
*/
inline Standard_Boolean Bnd_B3x::IsVoid () const
{
return (myHSize[0] < -1e-5);
}
/**
* Update the box by point.
*/
inline void Bnd_B3x::Add (const gp_Pnt& thePnt)
{
Add (thePnt.XYZ());
}
/**
* Update the box by another box.
*/
inline void Bnd_B3x::Add (const Bnd_B3x& theBox)
{
if (theBox.IsVoid() == Standard_False) {
Add (theBox.CornerMin());
Add (theBox.CornerMax());
}
}
/**
* Query a box corner.
*/
inline gp_XYZ Bnd_B3x::CornerMin () const
{
return gp_XYZ (myCenter[0] - myHSize[0],
myCenter[1] - myHSize[1],
myCenter[2] - myHSize[2]);
}
/**
* Query a box corner.
*/
inline gp_XYZ Bnd_B3x::CornerMax () const
{
return gp_XYZ (myCenter[0] + myHSize[0],
myCenter[1] + myHSize[1],
myCenter[2] + myHSize[2]);
}
/**
* Query the square diagonal.
*/
inline Standard_Real Bnd_B3x::SquareExtent () const
{
return 4 * (myHSize[0] * myHSize[0] +
myHSize[1] * myHSize[1] +
myHSize[2] * myHSize[2]);
}
/**
* Set the Center coordinates.
*/
inline void Bnd_B3x::SetCenter (const gp_XYZ& theCenter)
{
myCenter[0] = RealType(theCenter.X());
myCenter[1] = RealType(theCenter.Y());
myCenter[2] = RealType(theCenter.Z());
}
/**
* Set the Center coordinates.
*/
inline void Bnd_B3x::SetHSize (const gp_XYZ& theHSize)
{
myHSize[0] = RealType(theHSize.X());
myHSize[1] = RealType(theHSize.Y());
myHSize[2] = RealType(theHSize.Z());
}
/**
* Increase the box.
* @param aDiff
* absolute value of this parameter is added to the box size in all dimensions.
*/
inline void Bnd_B3x::Enlarge (const Standard_Real aDiff)
{
const Standard_Real aD = Abs(aDiff);
myHSize[0] += RealType(aD);
myHSize[1] += RealType(aD);
myHSize[2] += RealType(aD);
}
/**
* Intersection Box - Point
*/
inline Standard_Boolean Bnd_B3x::IsOut (const gp_XYZ& thePnt) const
{
return (Abs(RealType(thePnt.X()) - myCenter[0]) > myHSize[0] ||
Abs(RealType(thePnt.Y()) - myCenter[1]) > myHSize[1] ||
Abs(RealType(thePnt.Z()) - myCenter[2]) > myHSize[2]);
}
/**
* Intersection Box-Box.
*/
inline Standard_Boolean Bnd_B3x::IsOut (const Bnd_B3x& theBox) const
{
return (Abs(theBox.myCenter[0]-myCenter[0]) > theBox.myHSize[0]+myHSize[0] ||
Abs(theBox.myCenter[1]-myCenter[1]) > theBox.myHSize[1]+myHSize[1] ||
Abs(theBox.myCenter[2]-myCenter[2]) > theBox.myHSize[2]+myHSize[2]);
}
/**
* Test the complete inclusion of this box in theBox.
*/
inline Standard_Boolean Bnd_B3x::IsIn (const Bnd_B3x& theBox) const
{
return (Abs(theBox.myCenter[0]-myCenter[0]) < theBox.myHSize[0]-myHSize[0] &&
Abs(theBox.myCenter[1]-myCenter[1]) < theBox.myHSize[1]-myHSize[1] &&
Abs(theBox.myCenter[2]-myCenter[2]) < theBox.myHSize[2]-myHSize[2]);
}

133
src/Bnd/Bnd_BoundSortBox.cdl Executable file
View File

@@ -0,0 +1,133 @@
-- File: BoundSortBox.cdl
-- Created: Tue Nov 24 12:30:47 1992
-- Author: Didier PIFFAULT
-- <dpf@phylox>
---Copyright: Matra Datavision 1992
class BoundSortBox from Bnd
---Purpose: A tool to compare a bounding box or a plane with a set of
-- bounding boxes. It sorts the set of bounding boxes to give
-- the list of boxes which intersect the element being compared.
-- The boxes being sorted generally bound a set of shapes,
-- while the box being compared bounds a shape to be
-- compared. The resulting list of intersecting boxes therefore
-- gives the list of items which potentially intersect the shape to be compared.
uses Integer from Standard,
Real from Standard,
ListOfInteger from TColStd,
Pln from gp,
Box from Bnd,
HArray1OfBox from Bnd,
DataMapOfIntegerInteger from TColStd
raises NullValue from Standard, MultiplyDefined from Standard
is Create returns BoundSortBox from Bnd;
---Purpose: Constructs an empty comparison algorithm for bounding boxes.
-- The bounding boxes are then defined using the Initialize function.
Initialize (me : in out;
CompleteBox : Box from Bnd;
SetOfBox : HArray1OfBox from Bnd)
is static;
---Purpose: Initializes this comparison algorithm with
-- - the set of bounding boxes SetOfBox.
Initialize (me : in out;
SetOfBox : HArray1OfBox from Bnd)
is static;
---Purpose: Initializes this comparison algorithm with
-- - the set of bounding boxes SetOfBox, where
-- CompleteBox is given as the global bounding box of SetOfBox.
SortBoxes (me : in out)
raises NullValue from Standard is static private;
---Purpose: Prepares BoundSortBox and sorts the boxes of
-- <SetOfBox> .
Initialize (me : in out;
CompleteBox : Box from Bnd;
nbComponents : Integer from Standard)
raises NullValue from Standard is static;
---Purpose: Initializes this comparison algorithm, giving it only
-- - the maximum number nbComponents
-- of the bounding boxes to be managed. Use the Add
-- function to define the array of bounding boxes to be sorted by this algorithm.
Add (me : in out;
theBox : Box from Bnd;
boxIndex : Integer from Standard)
raises MultiplyDefined from Standard is static;
---Purpose: Adds the bounding box theBox at position boxIndex in
-- the array of boxes to be sorted by this comparison algorithm.
-- This function is used only in conjunction with the third
-- syntax described in the synopsis of Initialize.
--
-- Exceptions:
--
-- - Standard_OutOfRange if boxIndex is not in the
-- range [ 1,nbComponents ] where
-- nbComponents is the maximum number of bounding
-- boxes declared for this comparison algorithm at
-- initialization.
--
-- - Standard_MultiplyDefined if a box already exists at
-- position boxIndex in the array of boxes to be sorted by
-- this comparison algorithm.
Compare (me : in out;
theBox : Box from Bnd)
returns ListOfInteger from TColStd
---Purpose: Compares the bounding box theBox,
-- with the set of bounding boxes to be sorted by this
-- comparison algorithm, and returns the list of intersecting
-- bounding boxes as a list of indexes on the array of
-- bounding boxes used by this algorithm.
---C++: return const &
raises NullValue from Standard is static;
Compare (me : in out;
P : Pln from gp)
returns ListOfInteger from TColStd
---Purpose: Compares the plane P
-- with the set of bounding boxes to be sorted by this
-- comparison algorithm, and returns the list of intersecting
-- bounding boxes as a list of indexes on the array of
-- bounding boxes used by this algorithm.
---C++: return const &
raises NullValue from Standard is static;
Dump (me) is static;
Destroy(me: in out)
---C++: alias ~
is static;
fields myBox : Box from Bnd;
myBndComponents : HArray1OfBox from Bnd;
Xmin : Real from Standard;
Ymin : Real from Standard;
Zmin : Real from Standard;
deltaX : Real from Standard;
deltaY : Real from Standard;
deltaZ : Real from Standard;
discrX : Integer from Standard;
discrY : Integer from Standard;
discrZ : Integer from Standard;
theFound : Integer from Standard;
Crible : DataMapOfIntegerInteger from TColStd;
lastResult : ListOfInteger from TColStd;
TabBits : Address from Standard;
end BoundSortBox;

777
src/Bnd/Bnd_BoundSortBox.cxx Executable file
View File

@@ -0,0 +1,777 @@
// File: Bnd_BoundSortBox.cxx
// Created: Tue Nov 24 16:06:09 1992
// Author: Didier PIFFAULT
// <dpf@phylox>
#include <Bnd_BoundSortBox.ixx>
#include <Standard_NullValue.hxx>
#include <Standard_MultiplyDefined.hxx>
#include <Bnd_Array1OfBox.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
//#if defined(WNT) || defined(LIN)
# include <stdio.h>
//#endif // WNT
//-- ================================================================================
//-- lbr le 27 fev 97
//--
//--
//-- Initialisation: Une boite englobante BE
//-- Une liste de boites Bi (Bi dans BE)
//--
//-- Compare(b) renvoie la liste des Boites Bi touchees par b
//--
//--
//-- Principe General:
//--
//-- 1) On discretise la boite BE en N*N*N voxels
//-- Chaque boite Bi touche un certain nombre de voxels
//-- Bi touche { Vijk avec i0<=i<=i1 ... k0<=k<=k1 }
//-- 2) On projete sur chaque axe X,Y,Z les boites Bi
//-- pour obtenir les structures suivantes :
//--
//-- Exemple :
//--
//-- la boite i1 touche les voxels { Vijk avec 1<=i<=N-1 ... }
//-- la boite i2 touche les voxels { Vijk avec 2<=i<=3 ... }
//-- la boite i3 touche les voxels { Vijk avec 1<=i<=2 ... }
//--
//--
//-- X[.] | 1 2 3 4 .... N-1 N
//-- -----|-------------------------------------
//-- | i3 i1 i1 i1 i1
//-- | i2 i2
//-- | i3
//--
//--
//-- On realise la meme chose pour les axes Y et Z
//--
//-- On obtient donc 3 tableaux (X,Y,Z) de listes d entiers (les indices des boites)
//--
//-- 3) Pour rechercher les boites en contact avec une boite bt
//-- a) On cherche les voxels touches par bt -> i0bt,i1bt ... k0bt,k1bt
//-- b) On cherche dans la liste Z les boites presentes dans les cases Z[k0bt ... k1bt]
//-- c) On cherche parmi ces boites celles presentes dans les cases Y[j0bt ... j1bt]
//-- d) et le resultat est l intersection du result. precedent avec X[i0bt ... i1bt]
//--
//--
//-- Rejection de plus haut niveau.
//--
//-- *) On garde une representation a l aide d un tableau de bit des voxels de l espace BE
//-- qui contiennenrt au moins une boite Bi.
//-- *) Lorsque on teste une boite bt, on regarde tout d abord si cette boite comprend dans
//-- le tableau de bit au moins un voxel occuppe.
//-- Si un voxel occuppe est touche : pas de rejection
//-- Sinon return
//--
//-- **) Une autre rejection a ete adoptee. Elle consiste a ne pas checher a placer dans les
//-- structures ci-dessus (tableaux X,Y,Z et tableau de Bits) une boite Bi qui est grande
//-- devant la boite englobante BE.
//--
//-- Les indices de ces boites sont placees dans un tableau ToTest, et on comparera
//-- systematiquement ces boites avec bt.
//--
//--
//--
//--
//-- Note : des tableaux C remplacent ici avantageusement les HArray1OfListOfInteger et autres
//-- structures agreables lorsqu il faut ajouter des donnees mais lentes a la lecture.
//--
//-- Ici, on ajoute les donnees au debut (ds les fcts Initialize et SortBoxes) et ensuite,
//-- on passe beaucoup de temps a parcourir les tableaux. Des structures lentes a l ecriture
//-- mais rapides a la lecture sont donc meilleures.
//--
//--
//--
//--
//--
//=======================================================================
#define VERIFICATION 0
#define DEBUG 0
#define DIMAXIS 20
#if DEBUG
static long unsigned APPELREJECTION=0L;
static long unsigned REJECTNIV0=0L;
static long unsigned REJECTNIV1=0L;
static long unsigned NBCOMPARE=0L;
static long unsigned NBBOITES=0L;
static long unsigned NBBOITESATESTER=0L;
#endif
//=======================================================================
static Standard_Integer ComputeSize(const Standard_Integer n) {
if(n>40000) return(128);
if(n>10000) return(64);
if(n>1000) return(32);
if(n>100) return(16);
return(8);
}
//=======================================================================
static long unsigned _P2[32] = { 1,2,4,8, 16,32,64,128, 256,512,1024,2048,
4096,8192,16384,32768,
65536,131072,262144,524288,
1048576,2097152,4194304,8388608,
16777216,33554432,67108864,134217728,
268435456,536870912,1073741824,2147483648U};
class BSB_T3Bits { //-- size est une puissance de 2 > 4
public:
Standard_Integer _DECAL;
Standard_Integer _DECAL2;
Standard_Integer _BASE;
Standard_Integer _BASEM1;
long unsigned ind;
long unsigned Isize;
Standard_Integer ssize;
Standard_Real Xmin,Xmax,Ymin,Ymax,Zmin,Zmax;
long unsigned *p;
Standard_Integer **axisX;
Standard_Integer **axisY;
Standard_Integer **axisZ;
Standard_Integer *ToTest;
public:
BSB_T3Bits(int size);
~BSB_T3Bits();
//-- Partie HArray1OfListOfInteger
void AppendAxisX(const Standard_Integer i,const Standard_Integer v);
void AppendAxisY(const Standard_Integer i,const Standard_Integer v);
void AppendAxisZ(const Standard_Integer i,const Standard_Integer v);
void Add(long unsigned t) { int o=t&31; int k=t>>5; p[k]|=_P2[o]; }
int Val(long unsigned t) { int o=t&31; int k=t>>5; return(p[k]&_P2[o]); }
void Raz(long unsigned t) { int o=t&31; int k=t>>5; p[k]&= ~(_P2[o]); }
Standard_Integer NbAxisX(const Standard_Integer i) { return(axisX[0][i]); }
Standard_Integer NbAxisY(const Standard_Integer i) { return(axisY[0][i]); }
Standard_Integer NbAxisZ(const Standard_Integer i) { return(axisZ[0][i]); }
inline Standard_Integer GrilleInteger(Standard_Integer ix,
Standard_Integer iy,
Standard_Integer iz) {
Standard_Integer tz = iz<<_DECAL2;
Standard_Integer ty = iy<<_DECAL;
Standard_Integer t = ix;
t|=ty; t|=tz;
return(t);
}
inline void IntegerGrille(Standard_Integer t,
Standard_Integer &ix,
Standard_Integer &iy,
Standard_Integer &iz) {
ix = t & _BASEM1; t>>=_DECAL;
iy = t & _BASEM1; t>>=_DECAL;
iz = t;
}
};
//=======================================================================
BSB_T3Bits::~BSB_T3Bits() {
if(p) { delete [] p; p=0; }
#if DEBUG
printf("\n BASE:%d\n",_BASE);
#endif
for(Standard_Integer i=0; i<=ssize; i++) {
if(axisX[i]) { delete [] axisX[i]; axisX[i]=0; }
if(axisY[i]) { delete [] axisY[i]; axisY[i]=0; }
if(axisZ[i]) { delete [] axisZ[i]; axisZ[i]=0; }
}
free(axisX); axisX=0;
free(axisY); axisY=0;
free(axisZ); axisZ=0;
if(ToTest) { delete [] ToTest; ToTest=0; }
}
//=======================================================================
BSB_T3Bits::BSB_T3Bits(int size) {
switch (size) {
case 128: { _DECAL=7; _DECAL2=14; _BASE=128; _BASEM1=127; break; }
case 64: { _DECAL=6; _DECAL2=12; _BASE= 64; _BASEM1= 63; break; }
case 32: { _DECAL=5; _DECAL2=10; _BASE= 32; _BASEM1= 31; break; }
case 16: { _DECAL=4; _DECAL2= 8; _BASE= 16; _BASEM1= 15; break; }
default : { _DECAL=3; _DECAL2= 6; _BASE= 8; _BASEM1= 7; break; }
}
Standard_Integer i ;
long unsigned nb = (size*size*size)>>5;
Isize = nb;
ssize = size;
p = new long unsigned [nb];
do { p[--nb]=0; } while(nb);
axisX = (Standard_Integer **) malloc((size+1)*sizeof(Standard_Integer *));
axisY = (Standard_Integer **) malloc((size+1)*sizeof(Standard_Integer *));
axisZ = (Standard_Integer **) malloc((size+1)*sizeof(Standard_Integer *));
axisX[0]=new Standard_Integer [_BASE+1];
axisY[0]=new Standard_Integer [_BASE+1];
axisZ[0]=new Standard_Integer [_BASE+1];
for( i=0; i<(_BASE+1); i++) {
axisX[0][i]=0;
axisY[0][i]=0;
axisZ[0][i]=0;
}
for(i=1; i<=size; i++) {
axisX[i] = new Standard_Integer[DIMAXIS];
axisY[i] = new Standard_Integer[DIMAXIS];
axisZ[i] = new Standard_Integer[DIMAXIS];
axisX[i][0]=DIMAXIS;
axisY[i][0]=DIMAXIS;
axisZ[i][0]=DIMAXIS;
axisX[i][1]=axisY[i][1]=axisZ[i][1]=-1;
}
ToTest=0;
}
//=======================================================================
void BSB_T3Bits::AppendAxisZ(const Standard_Integer i,
const Standard_Integer v) {
Standard_Integer n = axisZ[0][i];
n++;
if(n<axisZ[i][0]) { axisZ[i][n]=v; }
else {
Standard_Integer s=axisZ[i][0];
Standard_Integer *nt = new Standard_Integer [s+s];
nt[0]=s+s;
for(Standard_Integer j=1;j<s;j++) {
nt[j]=axisZ[i][j];
}
nt[n]=v;
delete [] axisZ[i];
axisZ[i]=nt;
}
axisZ[0][i]=n;
}
//=======================================================================
void BSB_T3Bits::AppendAxisY(const Standard_Integer i,
const Standard_Integer v) {
Standard_Integer n = axisY[0][i];
n++;
if(n<axisY[i][0]) { axisY[i][n]=v; }
else {
Standard_Integer s=axisY[i][0];
Standard_Integer *nt = new Standard_Integer [s+s];
nt[0]=s+s;
for(Standard_Integer j=1;j<s;j++) {
nt[j]=axisY[i][j];
}
nt[n]=v;
delete [] axisY[i];
axisY[i]=nt;
}
axisY[0][i]=n;
}
//=======================================================================
void BSB_T3Bits::AppendAxisX(const Standard_Integer i,
const Standard_Integer v) {
Standard_Integer n = axisX[0][i];
n++;
if(n<axisX[i][0]) { axisX[i][n]=v; }
else {
//-- il faut etendre
Standard_Integer s=axisX[i][0];
Standard_Integer *nt = new Standard_Integer [s+s];
nt[0]=s+s;
for(Standard_Integer j=1;j<s;j++) {
nt[j]=axisX[i][j];
}
nt[n]=v;
delete [] axisX[i];
axisX[i]=nt;
}
axisX[0][i]=n;
}
//=======================================================================
//=======================================================================
//function : Bnd_BoundSortBox
//purpose :
//=======================================================================
Bnd_BoundSortBox::Bnd_BoundSortBox()
: discrX(0), discrY(0), discrZ(0)
{
TabBits=0;
#if DEBUG
NBCOMPARE=0L; NBBOITES=0L; NBBOITESATESTER=0L;
APPELREJECTION=0L; REJECTNIV0=0L; REJECTNIV1=0L;
#endif
}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox::Initialize(const Bnd_Box& CompleteBox,
const Handle(Bnd_HArray1OfBox)& SetOfBox)
{
myBox=CompleteBox;
myBndComponents=SetOfBox;
const Bnd_Array1OfBox & taBox=myBndComponents->Array1();
discrX=discrY=discrZ=ComputeSize(taBox.Upper()-taBox.Lower());
Standard_Real Xmax, Ymax, Zmax;
if(CompleteBox.IsVoid())
return;
CompleteBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
deltaX = (Xmax-Xmin == 0. ? 0. : discrX/(Xmax-Xmin));
deltaY = (Ymax-Ymin == 0. ? 0. : discrY/(Ymax-Ymin));
deltaZ = (Zmax-Zmin == 0. ? 0. : discrZ/(Zmax-Zmin));
SortBoxes();
}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox::Initialize(const Handle(Bnd_HArray1OfBox)& SetOfBox)
{
myBndComponents=SetOfBox;
const Bnd_Array1OfBox & taBox=myBndComponents->Array1();
Standard_Integer i0,i1;
i0=taBox.Lower();
i1=taBox.Upper();
discrX=discrY=discrZ=ComputeSize(i1-i0);
Standard_Integer labox;
for (labox=i0; labox<=i1; labox++) {
if (!taBox(labox).IsVoid()) {
myBox.Add(taBox(labox));
}
}
Standard_Real Xmax, Ymax, Zmax;
if(myBox.IsVoid())
return;
myBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
deltaX = (Xmax-Xmin == 0. ? 0. : discrX/(Xmax-Xmin));
deltaY = (Ymax-Ymin == 0. ? 0. : discrY/(Ymax-Ymin));
deltaZ = (Zmax-Zmin == 0. ? 0. : discrZ/(Zmax-Zmin));
SortBoxes();
}
//=======================================================================
//function : SortBoxes
//purpose :
//=======================================================================
void Bnd_BoundSortBox::SortBoxes()
{
Standard_Integer labox;
Standard_Integer lacaseX, firstcaseX, lastcaseX;
Standard_Integer lacaseY, firstcaseY, lastcaseY;
Standard_Integer lacaseZ, firstcaseZ, lastcaseZ;
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
const Bnd_Array1OfBox & taBox=myBndComponents->Array1();
Standard_Integer i0=taBox.Lower();
Standard_Integer i1=taBox.Upper();
BSB_T3Bits* Map=0;
if(TabBits) {
BSB_T3Bits* _Map = (BSB_T3Bits *)TabBits;
delete _Map;
}
Map = new BSB_T3Bits(discrX);
TabBits = (void *)Map;
if(Map->ToTest==0) {
Standard_Integer s=i1-i0;
if(s<2) s=2;
Map->ToTest = new Standard_Integer [s];
for(Standard_Integer i=0; i<s; i++) {
Map->ToTest[i]=i0-1;
}
}
Standard_Real _Xmax,_Xmin,_Ymax,_Ymin,_Zmin,_Zmax;
myBox.Get(_Xmin,_Ymin,_Zmin,_Xmax,_Ymax,_Zmax);
Map->Xmax=_Xmax; Map->Ymax=_Ymax; Map->Zmax=_Zmax;
Map->Xmin=_Xmin; Map->Ymin=_Ymin; Map->Zmin=_Zmin;
for (labox=i0; labox<=i1; labox++) {
if (!taBox(labox).IsVoid()) {
taBox(labox).Get(xmin, ymin, zmin, xmax, ymax, zmax);
if(xmin>Xmin) firstcaseX=(Standard_Integer )((xmin-Xmin)*deltaX)-1; else firstcaseX=1;
if(ymin>Ymin) firstcaseY=(Standard_Integer )((ymin-Ymin)*deltaY)-1; else firstcaseY=1;
if(zmin>Zmin) firstcaseZ=(Standard_Integer )((zmin-Zmin)*deltaZ)-1; else firstcaseZ=1;
if(xmax<_Xmax) lastcaseX=(Standard_Integer )((xmax-Xmin)*deltaX)+1; else lastcaseX=discrX;
if(ymax<_Ymax) lastcaseY=(Standard_Integer )((ymax-Ymin)*deltaY)+1; else lastcaseY=discrY;
if(zmax<_Zmax) lastcaseZ=(Standard_Integer )((zmax-Zmin)*deltaZ)+1; else lastcaseZ=discrZ;
if(firstcaseX<1) firstcaseX=1; else if(firstcaseX>discrX) firstcaseX=discrX;
if(firstcaseY<1) firstcaseY=1; else if(firstcaseY>discrY) firstcaseY=discrY;
if(firstcaseZ<1) firstcaseZ=1; else if(firstcaseZ>discrZ) firstcaseZ=discrZ;
if(lastcaseX<1) lastcaseX=1; else if(lastcaseX>discrX) lastcaseX=discrX;
if(lastcaseY<1) lastcaseY=1; else if(lastcaseY>discrY) lastcaseY=discrY;
if(lastcaseZ<1) lastcaseZ=1; else if(lastcaseZ>discrZ) lastcaseZ=discrZ;
Standard_Integer n = (lastcaseX-firstcaseX);
if(n>(lastcaseY-firstcaseY)) n=lastcaseY-firstcaseY;
if(n>(lastcaseZ-firstcaseZ)) n=lastcaseZ-firstcaseZ;
#if DEBUG
NBBOITES++;
#endif
n<<=2;
if(n>discrX) {
#if DEBUG
NBBOITESATESTER++;
#endif
for(Standard_Integer i=0; i<(i1-i0); i++) {
if(Map->ToTest[i]<i0) {
Map->ToTest[i]=labox;
break;
}
}
}
else {
for (lacaseX=firstcaseX; lacaseX<=lastcaseX; lacaseX++) {
Map->AppendAxisX(lacaseX,labox);
}
for (lacaseY=firstcaseY; lacaseY<=lastcaseY; lacaseY++) {
Map->AppendAxisY(lacaseY,labox);
}
for (lacaseZ=firstcaseZ; lacaseZ<=lastcaseZ; lacaseZ++) {
Map->AppendAxisZ(lacaseZ,labox);
}
//------------------------------------------------------------
//-- remplissage du tableau de bits
//--
if(Map) {
for (lacaseX=firstcaseX; lacaseX<=lastcaseX; lacaseX++) {
for (lacaseY=firstcaseY; lacaseY<=lastcaseY; lacaseY++) {
for (lacaseZ=firstcaseZ; lacaseZ<=lastcaseZ; lacaseZ++) {
long unsigned t=Map->GrilleInteger(lacaseX-1,lacaseY-1,lacaseZ-1);
Map->Add(t);
}
}
}
}
}
}
}
}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox::Initialize(const Bnd_Box& CompleteBox,
const Standard_Integer nbComponents)
{
Standard_NullValue_Raise_if (nbComponents <=0, "BoundSortBox nul!");
myBox=CompleteBox;
myBndComponents=new Bnd_HArray1OfBox(1,nbComponents);
//***>>> JCD - 04.08.2000 - Array initialization is missing...
Bnd_Box emptyBox;
myBndComponents->Init( emptyBox );
//***<<< JCD - End
discrX=discrY=discrZ=ComputeSize(nbComponents);
Standard_Real Xmax, Ymax, Zmax;
if(CompleteBox.IsVoid())
return;
CompleteBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
myBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
deltaX = (Xmax-Xmin == 0. ? 0. : discrX/(Xmax-Xmin));
deltaY = (Ymax-Ymin == 0. ? 0. : discrY/(Ymax-Ymin));
deltaZ = (Zmax-Zmin == 0. ? 0. : discrZ/(Zmax-Zmin));
if(TabBits) {
BSB_T3Bits* _Map = (BSB_T3Bits *)TabBits;
delete _Map;
TabBits=0;
}
BSB_T3Bits* Map=0;
Map = new BSB_T3Bits(discrX);
TabBits = (void *)Map;
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Bnd_BoundSortBox::Add(const Bnd_Box& theBox,
const Standard_Integer boxIndex)
{
Standard_MultiplyDefined_Raise_if (!(myBndComponents->Value(boxIndex).IsVoid()), " This box is already defined !");
if (!theBox.IsVoid()) {
Standard_Integer i0=myBndComponents->Lower();
Standard_Integer i1=myBndComponents->Upper();
Standard_Integer theGapX, firstGapX , lastGapX;
Standard_Integer theGapY, firstGapY , lastGapY;
Standard_Integer theGapZ, firstGapZ , lastGapZ;
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
myBndComponents->SetValue(boxIndex, theBox);
theBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
BSB_T3Bits* Map = (BSB_T3Bits *)TabBits;
if(Map->ToTest==0) {
Standard_Integer s=i1-i0;
if(s<2) s=2;
Map->ToTest = new Standard_Integer [s];
for(Standard_Integer i=0; i<s; i++) {
Map->ToTest[i]=i0-1;
}
}
Standard_Real _Xmax,_Ymax,_Zmax;
_Xmax=Map->Xmax; _Ymax=Map->Ymax; _Zmax=Map->Zmax;
if(xmin>Xmin) firstGapX=(Standard_Integer )((xmin-Xmin)*deltaX)-1; else firstGapX=1;
if(ymin>Ymin) firstGapY=(Standard_Integer )((ymin-Ymin)*deltaY)-1; else firstGapY=1;
if(zmin>Zmin) firstGapZ=(Standard_Integer ) ((zmin-Zmin)*deltaZ)-1; else firstGapZ=1;
if(xmax<_Xmax) lastGapX=(Standard_Integer )((xmax-Xmin)*deltaX)+1; else lastGapX=discrX;
if(ymax<_Ymax) lastGapY=(Standard_Integer )((ymax-Ymin)*deltaY)+1; else lastGapY=discrY;
if(zmax<_Zmax) lastGapZ=(Standard_Integer )((zmax-Zmin)*deltaZ)+1; else lastGapZ=discrZ;
if(firstGapX<1) firstGapX=1; else if(firstGapX>discrX) firstGapX=discrX;
if(firstGapY<1) firstGapY=1; else if(firstGapY>discrY) firstGapY=discrY;
if(firstGapZ<1) firstGapZ=1; else if(firstGapZ>discrZ) firstGapZ=discrZ;
if(lastGapX<1) lastGapX=1; else if(lastGapX>discrX) lastGapX=discrX;
if(lastGapY<1) lastGapY=1; else if(lastGapY>discrY) lastGapY=discrY;
if(lastGapZ<1) lastGapZ=1; else if(lastGapZ>discrZ) lastGapZ=discrZ;
Standard_Integer n = (lastGapX-firstGapX);
if(n>(lastGapY-firstGapY)) n=lastGapY-firstGapY;
if(n>(lastGapZ-firstGapZ)) n=lastGapZ-firstGapZ;
n<<=2;
#if DEBUG
NBBOITES++;
#endif
if(n>discrX) {
#if DEBUG
NBBOITESATESTER++;
#endif
for(Standard_Integer i=0; i<(i1-i0); i++) {
if(Map->ToTest[i]<i0) {
Map->ToTest[i]=boxIndex;
break;
}
}
}
for (theGapY=firstGapY; theGapY<=lastGapY; theGapY++) {
Map->AppendAxisY(theGapY,boxIndex);
}
for (theGapX=firstGapX; theGapX<=lastGapX; theGapX++) {
Map->AppendAxisX(theGapX,boxIndex);
}
for (theGapZ=firstGapZ; theGapZ<=lastGapZ; theGapZ++) {
Map->AppendAxisZ(theGapZ,boxIndex);
}
//------------------------------------------------------------
//-- remplissage du tableau de bits
//--
if(TabBits) {
Map=(BSB_T3Bits *)TabBits;
for (theGapX=firstGapX; theGapX<=lastGapX; theGapX++) {
for (theGapY=firstGapY; theGapY<=lastGapY; theGapY++) {
for (theGapZ=firstGapZ; theGapZ<=lastGapZ; theGapZ++) {
long unsigned t=Map->GrilleInteger(theGapX-1,theGapY-1,theGapZ-1);
Map->Add(t);
}
}
}
}
}
}
//=======================================================================
#if VERIFICATION
static void VerifCompare(const TColStd_ListOfInteger& lastResult,
const Bnd_Box& theBox,
const Bnd_Array1OfBox& taBox) {
static int Verif = 1;
Standard_Integer i ;
if(Verif) {
Standard_Integer i0,i1;
i0=taBox.Lower();
i1=taBox.Upper();
char * qwe=new char [i1+1]; //-- $$$$$$$ ATTENTION SI I0 < 0
for( i=i0; i<=i1; i++) qwe[i]='\0';
TColStd_ListIteratorOfListOfInteger theList(lastResult);
for (; theList.More(); theList.Next()) {
qwe[theList.Value()]=(char)1;
}
Standard_Integer labox;
for (labox=i0; labox<=i1; labox++) {
if (!taBox(labox).IsOut(theBox)) {
qwe[labox]+=2;
}
}
for(i=i0;i<=i1;i++) {
if(qwe[i]==2) {
printf("\nPb avec boite: %d ",i);
}
else if(qwe[i]==1) {
printf("\n fausse rejection en %d \n",i);
}
}
delete [] qwe;
}
}
#endif
//=======================================================================
//function : Compare
//purpose :
//=======================================================================
const TColStd_ListOfInteger& Bnd_BoundSortBox::Compare (const Bnd_Box& theBox)
{
Standard_Integer lacase ;
#if DEBUG
NBCOMPARE++;
#endif
lastResult.Clear();
if (theBox.IsVoid()) return lastResult;
if (theBox.IsOut(myBox)) {
#if DEBUG
REJECTNIV0++;
#endif
return lastResult;
}
const Bnd_Array1OfBox& taBox=myBndComponents->Array1();
//-- Rejection avec le tableau de bits
Standard_Boolean touch = Standard_True;
touch = Standard_False;
Standard_Real _Xmin,_Ymin,_Zmin,_Xmax,_Ymax,_Zmax;
BSB_T3Bits* Map = (BSB_T3Bits *)TabBits;
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
_Xmax=Map->Xmax; _Ymax=Map->Ymax; _Zmax=Map->Zmax;
_Xmin=Map->Xmin; _Ymin=Map->Ymin; _Zmin=Map->Zmin;
theBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
Standard_Integer i0,i1,j0,j1,k0,k1;
if(xmin>Xmin) i0=(Standard_Integer )((xmin-Xmin)*deltaX)-1; else i0=1;
if(ymin>Ymin) j0=(Standard_Integer )((ymin-Ymin)*deltaY)-1; else j0=1;
if(zmin>Zmin) k0=(Standard_Integer )((zmin-Zmin)*deltaZ)-1; else k0=1;
if(xmax<_Xmax) i1=(Standard_Integer )((xmax-Xmin)*deltaX)+1; else i1=discrX;
if(ymax<_Ymax) j1=(Standard_Integer )((ymax-Ymin)*deltaY)+1; else j1=discrY;
if(zmax<_Zmax) k1=(Standard_Integer )((zmax-Zmin)*deltaZ)+1; else k1=discrZ;
if(i0<1) i0=1; else if(i0>discrX) i0=discrX;
if(j0<1) j0=1; else if(j0>discrY) j0=discrY;
if(k0<1) k0=1; else if(k0>discrZ) k0=discrZ;
if(i1<1) i1=1; else if(i1>discrX) i1=discrX;
if(j1<1) j1=1; else if(j1>discrY) j1=discrY;
if(k1<1) k1=1; else if(k1>discrZ) k1=discrZ;
i0--; j0--; k0--; i1--; j1--; k1--;
for(Standard_Integer i=i0; touch==Standard_False && i<=i1;i++) {
for(Standard_Integer j=j0; touch==Standard_False && j<=j1;j++) {
for(Standard_Integer k=k0; touch==Standard_False && k<=k1;k++) {
long unsigned t=Map->GrilleInteger(i,j,k);
if(Map->Val(t)) {
touch = Standard_True;
}
}
}
}
//-- traitement des boites a tester systematiquement
if(Map->ToTest) {
Standard_Integer l0 = taBox.Lower();
Standard_Integer l1 = taBox.Upper();
l1-=l0;
for(Standard_Integer l=0; Map->ToTest[l]>=l0 && l<(l1-l0); l++) {
if(Map->ToTest[l]>=l0) {
if (!taBox(Map->ToTest[l]).IsOut(theBox)){
lastResult.Append(Map->ToTest[l]);
}
}
}
}
if(touch == Standard_False) {
#if DEBUG
REJECTNIV1++;
#endif
#if VERIFICATION
VerifCompare(lastResult,theBox,taBox);
#endif
return(lastResult);
}
//-------------------------
//-- traitement classique
//-------------------------
i0++; i1++; j0++; j1++; k0++; k1++;
Crible.Clear();
theFound=6;
Standard_Integer cardY=0;
for (lacase=j0; lacase<=j1; lacase++) {
Standard_Integer nby=Map->NbAxisY(lacase);
while(nby>0) {
cardY++;
Crible.Bind(Map->axisY[lacase][nby], 4);
nby--;
}
}
if (cardY==0) {
#if VERIFICATION
VerifCompare(lastResult,theBox,taBox);
#endif
return lastResult;
}
Standard_Integer cardZ=0;
for (lacase=k0; lacase<=k1; lacase++) {
Standard_Integer nbz=Map->NbAxisZ(lacase);
while(nbz>0) {
cardZ++;
if (Crible.IsBound(Map->axisZ[lacase][nbz])) {
Crible.Bind(Map->axisZ[lacase][nbz], 6);
}
nbz--;
}
}
if (cardZ==0) {
#if VERIFICATION
VerifCompare(lastResult,theBox,taBox);
#endif
return lastResult;
}
for (lacase=i0; lacase<=i1; lacase++) {
Standard_Integer nbx = Map->NbAxisX(lacase);
while(nbx>0) {
Standard_Integer x=Map->axisX[lacase][nbx];
if (Crible.IsBound(x)) {
if (Crible(x)==theFound) {
Crible.UnBind(x);
if (!taBox(x).IsOut(theBox)){
lastResult.Append(x);
}
}
}
nbx--;
}
}
#if VERIFICATION
VerifCompare(lastResult,theBox,taBox);
#endif
return lastResult;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Bnd_BoundSortBox::Dump() const
{}
//=======================================================================
//function : Compare
//purpose :
//=======================================================================
const TColStd_ListOfInteger& Bnd_BoundSortBox::Compare(const gp_Pln& thePlane)
{
lastResult.Clear();
Standard_Integer i;
const Bnd_Array1OfBox& boxes = myBndComponents->Array1();
for (i = boxes.Lower(); i <= boxes.Upper(); i++) {
if (!boxes(i).IsOut(thePlane))
lastResult.Append(i);
}
return lastResult;
}
//=======================================================================
void Bnd_BoundSortBox::Destroy() {
#if DEBUG
printf("\nDESTROY NBCOMPARE:%lu REJECTNIV0:%lu REJECTIONSOK=%lu NBBOITES:%lu NBBOITESATESTER:%lu\n",
NBCOMPARE,REJECTNIV0,REJECTNIV1,NBBOITES,NBBOITESATESTER);
#endif
BSB_T3Bits* Map = (BSB_T3Bits *)TabBits;
if(Map) {
delete Map;
Map=0;
}
}
//=======================================================================

110
src/Bnd/Bnd_BoundSortBox2d.cdl Executable file
View File

@@ -0,0 +1,110 @@
-- File: Bnd_BoundSortBox2d.cdl
-- Created: Fri Mar 5 15:45:24 1993
-- Author: Didier PIFFAULT
-- <dpf@phylox>
---Copyright: Matra Datavision 1993
class BoundSortBox2d from Bnd
---Purpose: A tool to compare a 2D bounding box with a set of 2D
-- bounding boxes. It sorts the set of bounding boxes to give
-- the list of boxes which intersect the element being compared.
-- The boxes being sorted generally bound a set of shapes,
-- while the box being compared bounds a shape to be
-- compared. The resulting list of intersecting boxes therefore
-- gives the list of items which potentially intersect the shape to be compared.
uses Integer from Standard,
Real from Standard,
ListOfInteger from TColStd,
Box2d from Bnd,
HArray1OfBox2d from Bnd,
DataMapOfIntegerInteger from TColStd,
HArray1OfListOfInteger from TColStd
raises NullValue from Standard, MultiplyDefined from Standard
is Create returns BoundSortBox2d from Bnd;
---Purpose: Constructs an empty comparison algorithm for 2D bounding boxes.
-- The bounding boxes are then defined using the Initialize function.
Initialize (me : in out;
CompleteBox : Box2d from Bnd;
SetOfBox : HArray1OfBox2d from Bnd)
is static;
---Purpose: Initializes this comparison algorithm with
-- - the set of 2D bounding boxes SetOfBox
Initialize (me : in out;
SetOfBox : HArray1OfBox2d from Bnd)
is static;
---Purpose: Initializes this comparison algorithm with
-- - the set of 2D bounding boxes SetOfBox, where
-- CompleteBox is given as the global bounding box of SetOfBox.
SortBoxes (me : in out)
raises NullValue from Standard is static private;
---Purpose: Prepares BoundSortBox2d and sorts the rectangles of
-- <SetOfBox> .
Initialize (me : in out;
CompleteBox : Box2d from Bnd;
nbComponents : Integer from Standard)
raises NullValue from Standard is static;
---Purpose: Initializes this comparison algorithm, giving it only
-- - the maximum number nbComponents, and
-- - the global bounding box CompleteBox,
-- of the 2D bounding boxes to be managed. Use the Add
-- function to define the array of bounding boxes to be sorted by this algorithm.
Add (me : in out;
theBox : Box2d from Bnd;
boxIndex : Integer from Standard)
raises MultiplyDefined from Standard is static;
---Purpose: Adds the 2D bounding box theBox at position boxIndex in
-- the array of boxes to be sorted by this comparison algorithm.
-- This function is used only in conjunction with the third
-- syntax described in the synopsis of Initialize.
-- Exceptions
-- - Standard_OutOfRange if boxIndex is not in the
-- range [ 1,nbComponents ] where
-- nbComponents is the maximum number of bounding
-- boxes declared for this comparison algorithm at
-- initialization.
-- - Standard_MultiplyDefined if a box still exists at
-- position boxIndex in the array of boxes to be sorted by
-- this comparison algorithm.
Compare (me : in out;
theBox : Box2d from Bnd)
returns ListOfInteger from TColStd
---C++: return const &
raises NullValue from Standard is static;
---Purpose:
-- Compares the 2D bounding box theBox with the set of
-- bounding boxes to be sorted by this comparison algorithm,
-- and returns the list of intersecting bounding boxes as a list
-- of indexes on the array of bounding boxes used by this algorithm.
Dump (me) is static;
fields myBox : Box2d from Bnd;
myBndComponents : HArray1OfBox2d from Bnd;
Xmin : Real from Standard;
Ymin : Real from Standard;
deltaX : Real from Standard;
deltaY : Real from Standard;
discrX : Integer from Standard;
discrY : Integer from Standard;
axisX : HArray1OfListOfInteger from TColStd;
axisY : HArray1OfListOfInteger from TColStd;
theFound : Integer from Standard;
Crible : DataMapOfIntegerInteger from TColStd;
lastResult : ListOfInteger from TColStd;
end BoundSortBox2d;

392
src/Bnd/Bnd_BoundSortBox2d.cxx Executable file
View File

@@ -0,0 +1,392 @@
// File: Bnd_BoundSortBox2d.cxx
// Created: Mon Mar 8 15:20:59 1993
// Author: Didier PIFFAULT
// <dpf@phylox>
#include <Bnd_BoundSortBox2d.ixx>
#include <Standard_NullValue.hxx>
#include <Bnd_Array1OfBox.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
#include <TColStd_Array1OfListOfInteger.hxx>
//=======================================================================
//function : Bnd_BoundSortBox2d
//purpose :
//=======================================================================
Bnd_BoundSortBox2d::Bnd_BoundSortBox2d()
: discrX(0), discrY(0)
{}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::Initialize(const Bnd_Box2d& CompleteBox,
const Handle(Bnd_HArray1OfBox2d)& SetOfBox)
{
myBox=CompleteBox;
myBndComponents=SetOfBox;
discrX=SetOfBox->Length();
discrY=discrX;
Standard_Real xmin, ymin, xmax, ymax;
Standard_Real middleX=0.;
Standard_Real middleY=0.;
const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
Standard_Integer labox;
for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
if (!taBox(labox).IsVoid()) {
taBox.Value(labox).Get(xmin, ymin, xmax, ymax);
middleX+=xmax-xmin;
middleY+=ymax-ymin;
}
}
middleX=middleX/taBox.Length();
middleY=middleY/taBox.Length();
Standard_Real Xmax, Ymax;
CompleteBox.Get(Xmin, Ymin, Xmax, Ymax);
deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
if (middleX < Epsilon(100.)) {
discrX=1;
deltaX=Xmax-Xmin;
}
else if (middleX > deltaX) {
discrX=(Standard_Integer)((Xmax-Xmin)/middleX);
deltaX=middleX;
discrX++;
}
if (middleY < Epsilon(100.)) {
discrY=1;
deltaY=Ymax-Ymin;
}
else if (middleY > deltaY) {
discrY=(Standard_Integer)((Ymax-Ymin)/middleY + 0.1);
deltaY=middleY;
discrY++;
}
SortBoxes();
}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::Initialize(const Handle_Bnd_HArray1OfBox2d& SetOfBox)
{
myBndComponents=SetOfBox;
discrX=SetOfBox->Length();
discrY=discrX;
Standard_Real xmin, ymin, xmax, ymax;
Standard_Real middleX=0.;
Standard_Real middleY=0.;
const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
Standard_Integer labox;
for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
if (!taBox(labox).IsVoid()) {
myBox.Add(taBox(labox));
taBox.Value(labox).Get(xmin, ymin, xmax, ymax);
middleX+=xmax-xmin;
middleY+=ymax-ymin;
}
}
middleX=middleX/taBox.Length();
middleY=middleY/taBox.Length();
Standard_Real Xmax, Ymax;
myBox.Get(Xmin, Ymin, Xmax, Ymax);
deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
if (middleX < Epsilon(100.)) {
discrX=1;
deltaX=Xmax-Xmin;
}
else if (middleX > deltaX) {
discrX=(Standard_Integer)((Xmax-Xmin)/middleX);
deltaX=middleX;
discrX++;
}
if (middleY < Epsilon(100.)) {
discrY=1;
deltaY=Ymax-Ymin;
}
else if (middleY > deltaY) {
discrY=(Standard_Integer)((Ymax-Ymin)/middleY + 0.1);
deltaY=middleY;
discrY++;
}
SortBoxes();
}
//=======================================================================
//function : SortBoxes
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::SortBoxes()
{
Standard_NullValue_Raise_if (discrX+discrY <=0, "BoundSortBox2d nul!");
Standard_Integer labox, lacase, firstcase, lastcase;
Standard_Real xmin, ymin, xmax, ymax;
const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
axisX=new TColStd_HArray1OfListOfInteger(1, discrX);
TColStd_Array1OfListOfInteger & tabListX=axisX->ChangeArray1();
axisY=new TColStd_HArray1OfListOfInteger(1, discrY);
TColStd_Array1OfListOfInteger & tabListY=axisY->ChangeArray1();
for (labox=taBox.Lower(); labox<=taBox.Upper(); labox++) {
if (!taBox(labox).IsVoid()) {
taBox(labox).Get(xmin, ymin, xmax, ymax);
if (discrX>1) {
firstcase=(Standard_Integer ) Max(1.0, (xmin-Xmin)/deltaX);
lastcase=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
for (lacase=firstcase; lacase<=lastcase; lacase++) {
tabListX(lacase).Append(labox);
}
}
if (discrY >1) {
firstcase=(Standard_Integer ) Max(1.0, (ymin-Ymin)/deltaY);
lastcase=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
for (lacase=firstcase; lacase<=lastcase; lacase++) {
tabListY(lacase).Append(labox);
}
}
}
}
}
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::Initialize(const Bnd_Box2d& CompleteBox,
const Standard_Integer nbComponents)
{
Standard_NullValue_Raise_if (nbComponents <=0, "BoundSortBox nul!");
myBox=CompleteBox;
myBndComponents=new Bnd_HArray1OfBox2d(1, nbComponents);
Bnd_Box2d emptyBox;
myBndComponents->Init( emptyBox );
discrX=nbComponents;
discrY=nbComponents;
Standard_Real Xmax, Ymax;
CompleteBox.Get(Xmin, Ymin, Xmax, Ymax);
deltaX=(Xmax-Xmin)/(Standard_Real)discrX;
deltaY=(Ymax-Ymin)/(Standard_Real)discrY;
if (deltaX < Epsilon(100.)) {
discrX=1;
deltaX=Xmax-Xmin;
}
else axisX=new TColStd_HArray1OfListOfInteger(1, discrX);
if (deltaY < Epsilon(100.)) {
discrY=1;
deltaY=Ymax-Ymin;
}
else axisY=new TColStd_HArray1OfListOfInteger(1, discrY);
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::Add(const Bnd_Box2d& theBox,
const Standard_Integer boxIndex)
{
Standard_MultiplyDefined_Raise_if
(!(myBndComponents->Value(boxIndex).IsVoid()),
" This box is already defined !");
if (!theBox.IsVoid()) {
Bnd_Array1OfBox2d & taBox=myBndComponents->ChangeArray1();
Standard_Integer theGap, firstGap , lastGap;
Standard_Real xmin, ymin, xmax, ymax;
theBox.Get(xmin, ymin, xmax, ymax);
if (taBox.Lower()<=boxIndex && boxIndex<=taBox.Upper())
taBox(boxIndex).Update(xmin, ymin, xmax, ymax);
TColStd_Array1OfListOfInteger & tabListX=axisX->ChangeArray1();
if (discrX>1) {
firstGap=(Standard_Integer ) Max(1.0, ((xmin-Xmin)/deltaX)+1);
lastGap=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
for (theGap=firstGap; theGap<=lastGap; theGap++) {
tabListX(theGap).Append(boxIndex);
}
}
TColStd_Array1OfListOfInteger & tabListY=axisY->ChangeArray1();
if (discrY >1) {
firstGap=(Standard_Integer ) Max(1.0, ((ymin-Ymin)/deltaY)+1);
lastGap=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
for (theGap=firstGap; theGap<=lastGap; theGap++) {
tabListY(theGap).Append(boxIndex);
}
}
}
}
//=======================================================================
//function : Compare
//purpose :
//=======================================================================
const TColStd_ListOfInteger& Bnd_BoundSortBox2d::Compare
(const Bnd_Box2d& theBox)
{
Standard_NullValue_Raise_if (discrX+discrY <=0,
"Compare sur 1 BoundSortBox2d nul!");
lastResult.Clear();
if (theBox.IsVoid()) return lastResult;
if (theBox.IsOut(myBox)) return lastResult;
Standard_Integer lacase, firstcase, lastcase;
Standard_Real xmin, ymin, xmax, ymax;
theBox.Get(xmin, ymin, xmax, ymax);
const Bnd_Array1OfBox2d & taBox=myBndComponents->Array1();
Crible.Clear();
theFound=2;
Standard_Integer cardY=0;
if (discrY>1 && (!theBox.IsOpenYmin() || !theBox.IsOpenYmax())) {
const TColStd_Array1OfListOfInteger & tabList=axisY->Array1();
firstcase=(Standard_Integer ) Max(1.0, (ymin-Ymin)/deltaY);
lastcase=(Standard_Integer ) Min((Standard_Real)discrY, ((ymax-Ymin)/deltaY)+1);
for (lacase=firstcase; lacase<=lastcase; lacase++) {
TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
for (; theList.More(); theList.Next()) {
cardY++;
Crible.Bind(theList.Value(), 2);
}
}
if (cardY==0) return lastResult;
}
else {
if (ymin > Ymin+deltaY || ymax < Ymin)
return lastResult;
theFound-=2;
}
if (discrX>1 && (!theBox.IsOpenXmin() || !theBox.IsOpenXmax())) {
const TColStd_Array1OfListOfInteger & tabList=axisX->Array1();
firstcase=(Standard_Integer ) Max(1.0, (xmin-Xmin)/deltaX);
lastcase=(Standard_Integer ) Min((Standard_Real)discrX, ((xmax-Xmin)/deltaX)+1);
for (lacase=firstcase; lacase<=lastcase; lacase++) {
TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
for (; theList.More(); theList.Next()) {
if (Crible.IsBound(theList.Value())) {
if (Crible(theList.Value())==theFound) {
if (!taBox.Value(theList.Value()).IsOut(theBox)){
lastResult.Append(theList.Value());
Crible(theList.Value())=0;
}
}
}
}
}
return lastResult;
}
else {
if (xmin > Xmin+deltaX || xmax < Xmin) return lastResult;
else if (discrY==1)
{
lacase=1;
for(Standard_Integer i=taBox.Lower();i<=taBox.Upper();i++)
{
lastResult.Append(i);
}
}
else{
TColStd_DataMapIteratorOfDataMapOfIntegerInteger itDM(Crible);
for (; itDM.More(); itDM.Next()) {
if (itDM.Value()==theFound) {
if (taBox.Lower()<=itDM.Key() && itDM.Key()<=taBox.Upper()) {
if (!taBox(itDM.Key()).IsOut(theBox))
lastResult.Append(itDM.Key());
}
else {
lastResult.Append(itDM.Key());
}
}
}
}
}
return lastResult;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Bnd_BoundSortBox2d::Dump() const
{
Standard_Integer lacase;
cout << "axis X : " << discrX << " intervalles de " << deltaX << endl;
if (discrX>1) {
const TColStd_Array1OfListOfInteger & tabList=axisX->Array1();
for (lacase=1; lacase<=discrX; lacase++) {
cout << " X " << lacase << " : " ;
TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
for (; theList.More(); theList.Next()) {
cout << theList.Value() << " ";
}
cout << "\n";
}
}
cout << "axis Y : " << discrY << " intervalles de " << deltaY << endl;
if (discrY>1) {
const TColStd_Array1OfListOfInteger & tabList=axisY->Array1();
for (lacase=1; lacase<=discrY; lacase++) {
cout << " Y " << lacase << " : " ;
TColStd_ListIteratorOfListOfInteger theList(tabList(lacase));
for (; theList.More(); theList.Next()) {
cout << theList.Value() << " ";
}
cout << "\n";
}
}
}

290
src/Bnd/Bnd_Box.cdl Executable file
View File

@@ -0,0 +1,290 @@
-- File: Box.cdl
-- Created: Mon Jan 28 11:51:08 1991
-- Author: Remi Lequette
-- <rle@topsn3>
-- Modified : by Maria Pumborios at fri Apr 26
-- add the method distance
---Copyright: Matra Datavision 1991, 1992
class Box from Bnd
---Purpose: Describes a bounding box in 3D space.
-- A bounding box is parallel to the axes of the coordinates
-- system. If it is finite, it is defined by the three intervals:
-- - [ Xmin,Xmax ],
-- - [ Ymin,Ymax ],
-- - [ Zmin,Zmax ].
-- A bounding box may be infinite (i.e. open) in one or more
-- directions. It is said to be:
-- - OpenXmin if it is infinite on the negative side of the "X Direction";
-- - OpenXmax if it is infinite on the positive side of the "X Direction";
-- - OpenYmin if it is infinite on the negative side of the "Y Direction";
-- - OpenYmax if it is infinite on the positive side of the "Y Direction";
-- - OpenZmin if it is infinite on the negative side of the "Z Direction";
-- - OpenZmax if it is infinite on the positive side of the "Z Direction";
-- - WholeSpace if it is infinite in all six directions. In this
-- case, any point of the space is inside the box;
-- - Void if it is empty. In this case, there is no point included in the box.
-- A bounding box is defined by:
-- - six bounds (Xmin, Xmax, Ymin, Ymax, Zmin and
-- Zmax) which limit the bounding box if it is finite,
-- - eight flags (OpenXmin, OpenXmax, OpenYmin,
-- OpenYmax, OpenZmin, OpenZmax,
-- WholeSpace and Void) which describe the
-- bounding box if it is infinite or empty, and
-- - a gap, which is included on both sides in any direction
-- when consulting the finite bounds of the box.
uses Pnt from gp,
Lin from gp,
Dir from gp,
Trsf from gp,
Pln from gp
raises
ConstructionError from Standard
is
Create returns Box from Bnd;
---Purpose: Creates an empty Box.
-- The constructed box is qualified Void. Its gap is null.
SetWhole(me : in out) is static;
---Purpose: Sets this bounding box so that it covers the whole of 3D space.
-- It is infinitely long in all directions.
SetVoid(me : in out) is static;
---Purpose: Sets this bounding box so that it is empty. All points are outside a void box.
Set(me : in out; P : Pnt) is static;
---Purpose: Sets this bounding box so that it bounds
-- - the point P. This involves first setting this bounding box
-- to be void and then adding the point P.
Set(me : in out; P : Pnt; D : Dir) is static;
---Purpose: Sets this bounding box so that it bounds
--- the half-line defined by point P and direction D, i.e. all
-- points M defined by M=P+u*D, where u is greater than
-- or equal to 0, are inside the bounding volume. This
-- involves first setting this box to be void and then adding the half-line.
Update(me : in out; aXmin, aYmin, aZmin, aXmax, aYmax, aZmax : Real)
---Purpose: Enlarges this bounding box, if required, so that it
-- contains at least:
-- - interval [ aXmin,aXmax ] in the "X Direction",
-- - interval [ aYmin,aYmax ] in the "Y Direction",
-- - interval [ aZmin,aZmax ] in the "Z Direction";
is static;
Update(me : in out; X,Y,Z : Real)
---Purpose: Adds a point of coordinates (X,Y,Z) to this bounding box.
is static;
GetGap(me) returns Real
---Purpose: Returns the gap of this bounding box.
is static;
SetGap(me : in out; Tol : Real)
---Purpose: Set the gap of this bounding box to abs(Tol).
is static;
Enlarge(me : in out; Tol : Real)
---Purpose: Enlarges the box with a tolerance value.
-- (minvalues-Abs(<tol>) and maxvalues+Abs(<tol>))
-- This means that the minimum values of its X, Y and Z
-- intervals of definition, when they are finite, are reduced by
-- the absolute value of Tol, while the maximum values are
-- increased by the same amount.
is static;
Get(me; aXmin, aYmin, aZmin, aXmax, aYmax, aZmax : out Real)
---Purpose: Returns the bounds of this bounding box. The gap is included.
-- If this bounding box is infinite (i.e. "open"), returned values
-- may be equal to +/- Precision::Infinite().
raises ConstructionError -- if IsVoid()
is static;
OpenXmin(me : in out)
---Purpose: The Box will be infinitely long in the Xmin
-- direction.
---Level: Public
is static;
OpenXmax(me : in out)
---Purpose: The Box will be infinitely long in the Xmax
-- direction.
---Level: Public
is static;
OpenYmin(me : in out)
---Purpose: The Box will be infinitely long in the Ymin
-- direction.
---Level: Public
is static;
OpenYmax(me : in out)
---Purpose: The Box will be infinitely long in the Ymax
-- direction.
---Level: Public
is static;
OpenZmin(me : in out)
---Purpose: The Box will be infinitely long in the Zmin
-- direction.
---Level: Public
is static;
OpenZmax(me : in out)
---Purpose: The Box will be infinitely long in the Zmax
-- direction.
---Level: Public
is static;
IsOpenXmin(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Xmin direction.
is static;
IsOpenXmax(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Xmax direction.
is static;
IsOpenYmin(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Ymix direction.
is static;
IsOpenYmax(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Ymax direction.
is static;
IsOpenZmin(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Zmin direction.
is static;
IsOpenZmax(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Zmax direction.
is static;
IsWhole(me) returns Boolean
--- Purpose: Returns true if this bounding box is infinite in all 6 directions (WholeSpace flag).
is static;
IsVoid(me) returns Boolean
---Purpose: Returns true if this bounding box is empty (Void flag).
is static;
IsXThin(me; tol : Real) returns Boolean
---Purpose: true if xmax-xmin < tol.
---Level: Public
is static;
IsYThin(me; tol : Real) returns Boolean
---Purpose: true if ymax-ymin < tol.
---Level: Public
is static;
IsZThin(me; tol : Real) returns Boolean
---Purpose: true if zmax-zmin < tol.
---Level: Public
is static;
IsThin(me; tol : Real) returns Boolean
---Purpose: Returns true if IsXThin, IsYThin and IsZThin are all true,
-- i.e. if the box is thin in all three dimensions.
---Level: Public
is static;
Transformed(me; T : Trsf from gp)
---Purpose: Returns a bounding box which is the result of applying the
-- transformation T to this bounding box.
-- Warning
-- Applying a geometric transformation (for example, a
-- rotation) to a bounding box generally increases its
-- dimensions. This is not optimal for algorithms which use it.
returns Box from Bnd
is static;
Add(me : in out; Other : Box)
is static;
---Purpose: Adds the box <Other> to <me>.
---Level: Public
Add(me : in out; P : Pnt)
is static;
---Purpose: Adds a Pnt to the box.
---Level: Public
Add(me : in out; P : Pnt; D : Dir)
is static;
---Purpose: Extends <me> from the Pnt <P> in the direction <D>.
---Level: Public
Add(me : in out; D : Dir)
is static;
---Purpose: Extends the Box in the given Direction, i.e. adds
-- an half-line. The box may become infinite in
-- 1,2 or 3 directions.
---Level: Public
IsOut(me; P : Pnt from gp) returns Boolean
---Purpose: Returns True if the Pnt is out the box.
---Level: Public
is static;
IsOut(me; L : Lin from gp) returns Boolean
---Purpose: Returns False if the line intersects the box.
---Level: Public
is static;
IsOut(me; P : Pln from gp) returns Boolean
---Purpose: Returns False if the plane intersects the box.
---Level: Public
is static;
IsOut(me; Other : Box) returns Boolean
is static;
---Purpose: Returns False if the <Box> intersects or is inside <me>.
---Level: Public
IsOut(me; Other : Box; T : Trsf from gp) returns Boolean
is static;
---Purpose: Returns False if the transformed <Box> intersects
-- or is inside <me>.
---Level: Public
IsOut(me; T1 : Trsf from gp; Other : Box; T2 : Trsf from gp)
returns Boolean
is static;
---Purpose: Returns False if the transformed <Box> intersects
-- or is inside the transformed box <me>.
---Level: Public
IsOut(me; P1, P2: Pnt from gp; D: Dir from gp)
returns Boolean
is static;
---Purpose: Returns False if the flat band lying between two parallel
-- lines represented by their reference points <P1>, <P2> and
-- direction <D> intersects the box.
---Level: Public
Distance (me; Other : Box) returns Real is static;
--- Purpose : Computes the minimum distance between two boxes.
Dump (me) is static;
SquareExtent(me) returns Real;
--- Purpose : Computes the squared diagonal of me.
---C++: inline
fields Xmin : Real;
Xmax : Real;
Ymin : Real;
Ymax : Real;
Zmin : Real;
Zmax : Real;
Gap : Real;
Flags : Integer; -- 8 flags
end Box ;

1056
src/Bnd/Bnd_Box.cxx Executable file

File diff suppressed because it is too large Load Diff

18
src/Bnd/Bnd_Box.lxx Executable file
View File

@@ -0,0 +1,18 @@
// File: Bnd_Box.lxx
// Created: 14.02.05 12:38:11
// Author: Alexey MORENOV
// Copyright: Open CASCADE 2005
//=======================================================================
//function : SquareExtent
//purpose : Computes the squared diagonal
//=======================================================================
inline Standard_Real Bnd_Box::SquareExtent() const
{
if ( IsVoid() ) return 0.;
Standard_Real dx = Xmax-Xmin+Gap;
Standard_Real dy = Ymax-Ymin+Gap;
Standard_Real dz = Zmax-Zmin+Gap;
return dx*dx + dy*dy + dz*dz;
}

221
src/Bnd/Bnd_Box2d.cdl Executable file
View File

@@ -0,0 +1,221 @@
-- File: Box2d.cdl
-- Created: Mon Jan 28 11:51:08 1991
-- Author: Remi Lequette
-- <rle@topsn3>
---Copyright: Matra Datavision 1991, 1992
class Box2d from Bnd
---Purpose: Describes a bounding box in 2D space.
-- A bounding box is parallel to the axes of the coordinates
-- system. If it is finite, it is defined by the two intervals:
-- - [ Xmin,Xmax ], and
-- - [ Ymin,Ymax ].
-- A bounding box may be infinite (i.e. open) in one or more
-- directions. It is said to be:
-- - OpenXmin if it is infinite on the negative side of the "X Direction";
-- - OpenXmax if it is infinite on the positive side of the "X Direction";
-- - OpenYmin if it is infinite on the negative side of the "Y Direction";
-- - OpenYmax if it is infinite on the positive side of the "Y Direction";
-- - WholeSpace if it is infinite in all four directions. In
-- this case, any point of the space is inside the box;
-- - Void if it is empty. In this case, there is no point included in the box.
-- A bounding box is defined by four bounds (Xmin, Xmax, Ymin and Ymax) which
-- limit the bounding box if it is finite, six flags (OpenXmin, OpenXmax, OpenYmin,
-- OpenYmax, WholeSpace and Void) which describe the bounding box if it is infinite or empty, and
-- - a gap, which is included on both sides in any direction when consulting the finite bounds of the box.
uses Pnt2d from gp,
Dir2d from gp,
Lin2d from gp,
Trsf2d from gp
raises
ConstructionError from Standard
is
Create returns Box2d from Bnd;
---Purpose: Creates an empty 2D bounding box.
-- The constructed box is qualified Void. Its gap is null.
---C++: inline
SetWhole(me : in out) is static;
---Purpose: Sets this bounding box so that it covers the whole 2D
-- space, i.e. it is infinite in all directions.
---C++: inline
SetVoid(me : in out) is static;
---Purpose: Sets this 2D bounding box so that it is empty. All points are outside a void box.
---C++: inline
Set(me : in out; P : Pnt2d) is static;
---Purpose: Sets this 2D bounding box so that it bounds
-- the point P. This involves first setting this bounding box
-- to be void and then adding the point PThe rectangle bounds the point <P>.
---C++: inline
Set(me : in out; P : Pnt2d; D : Dir2d) is static;
---Purpose: Sets this 2D bounding box so that it bounds
-- the half-line defined by point P and direction D, i.e. all
-- points M defined by M=P+u*D, where u is greater than
-- or equal to 0, are inside the bounding area. This involves
-- first setting this 2D box to be void and then adding the half-line.
---C++: inline
Update(me : in out; aXmin, aYmin, aXmax, aYmax : Real)
---Purpose: Enlarges this 2D bounding box, if required, so that it
-- contains at least:
-- - interval [ aXmin,aXmax ] in the "X Direction",
-- - interval [ aYmin,aYmax ] in the "Y Direction"
is static;
Update(me : in out; X,Y : Real)
---Purpose: Adds a point of coordinates (X,Y) to this bounding box.
is static;
GetGap(me) returns Real
---Purpose: Returns the gap of this 2D bounding box.
---C++: inline
is static;
SetGap(me : in out; Tol : Real)
---Purpose: Set the gap of this 2D bounding box to abs(Tol).
---C++: inline
is static;
Enlarge(me : in out; Tol : Real)
---Purpose: Enlarges the box with a tolerance value.
-- This means that the minimum values of its X and Y
-- intervals of definition, when they are finite, are reduced by
-- the absolute value of Tol, while the maximum values are
-- increased by the same amount.
---C++: inline
is static;
Get(me; aXmin, aYmin, aXmax, aYmax : out Real)
---Purpose: Returns the bounds of this 2D bounding box.
-- The gap is included. If this bounding box is infinite (i.e. "open"), returned values
-- may be equal to +/- Precision::Infinite().
raises ConstructionError -- if IsVoid()
is static;
OpenXmin(me : in out)
---Purpose: The Box will be infinitely long in the Xmin direction.
---Level: Public
---C++: inline
is static;
OpenXmax(me : in out)
---Purpose: The Box will be infinitely long in the Xmax direction.
---Level: Public
---C++: inline
is static;
OpenYmin(me : in out)
---Purpose: The Box will be infinitely long in the Ymin direction.
---Level: Public
---C++: inline
is static;
OpenYmax(me : in out)
---Purpose: The Box will be infinitely long in the Ymax direction.
---Level: Public
---C++: inline
is static;
IsOpenXmin(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Xmin direction.
---C++: inline
is static;
IsOpenXmax(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Xmax direction.
---C++: inline
is static;
IsOpenYmin(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Ymin direction.
---C++: inline
is static;
IsOpenYmax(me) returns Boolean
---Purpose: Returns true if this bounding box is open in the Ymax direction.
---C++: inline
is static;
IsWhole(me) returns Boolean is static;
---Purpose:
-- Returns true if this bounding box is infinite in all 4
-- directions (Whole Space flag).
---C++: inline
IsVoid(me) returns Boolean is static;
---Purpose:
-- Returns true if this 2D bounding box is empty (Void flag).
---C++: inline
Transformed(me; T : Trsf2d from gp)
---Purpose: Returns a bounding box which is the result of applying the
-- transformation T to this bounding box.
-- Warning
-- Applying a geometric transformation (for example, a
-- rotation) to a bounding box generally increases its
-- dimensions. This is not optimal for algorithms which use it.
returns Box2d from Bnd is static;
Add(me : in out; Other : Box2d) is static;
---Purpose: Adds the 2d box <Other> to <me>.
---Level: Public
Add(me : in out; P : Pnt2d) is static;
---Purpose: Adds the 2d pnt <P> to <me>.
---Level: Public
---C++: inline
Add(me : in out; P : Pnt2d; D : Dir2d) is static;
---Purpose: Extends <me> from the Pnt <P> in the direction <D>.
---Level: Public
---C++: inline
Add(me : in out; D : Dir2d) is static;
---Purpose: Extends the Box in the given Direction, i.e. adds
-- a half-line. The box may become infinite in 1 or 2
-- directions.
---Level: Public
IsOut(me; P : Pnt2d) returns Boolean is static;
---Purpose: Returns True if the 2d pnt <P> is out <me>.
---Level: Public
IsOut(me; Other : Box2d) returns Boolean is static;
---Purpose: Returns True if <Box2d> is out <me>.
---Level: Public
IsOut(me; Other : Box2d; T : Trsf2d from gp) returns Boolean is static;
---Purpose: Returns True if transformed <Box2d> is out <me>.
---Level: Public
---C++: inline
IsOut(me; T1 : Trsf2d from gp; Other : Box2d; T2 : Trsf2d from gp)
returns Boolean is static;
---Purpose: Compares a transformed bounding with a transformed
-- bounding. The default implementation is to make a copy
-- of <me> and <Other>, to transform them and to test.
---Level: Public
---C++: inline
Dump(me) is static;
fields Xmin : Real;
Xmax : Real;
Ymin : Real;
Ymax : Real;
Gap : Real;
Flags : Integer; -- 6 flags
end Box2d;

286
src/Bnd/Bnd_Box2d.cxx Executable file
View File

@@ -0,0 +1,286 @@
// File: Bnd_Box2d.cxx
// Created: Wed Oct 30 16:21:56 1991
// Author: Modelisation
// <model@sdsun1>
#include <Bnd_Box2d.ixx>
#include <Standard_Stream.hxx>
#include <gp.hxx>
//-- #include <Precision.hxx> Precision::Infinite() -> 1e+100
//=======================================================================
//function : Update
//purpose :
//=======================================================================
void Bnd_Box2d::Update (const Standard_Real x, const Standard_Real y,
const Standard_Real X, const Standard_Real Y)
{
if (Flags & VoidMask) {
Xmin = x;
Ymin = y;
Xmax = X;
Ymax = Y;
Flags &= ~VoidMask;
}
else {
if (!(Flags & XminMask) && (x < Xmin)) Xmin = x;
if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
if (!(Flags & YminMask) && (y < Ymin)) Ymin = y;
if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
}
}
//=======================================================================
//function : Update
//purpose :
//=======================================================================
void Bnd_Box2d::Update (const Standard_Real X, const Standard_Real Y)
{
if (Flags & VoidMask) {
Xmin = X;
Ymin = Y;
Xmax = X;
Ymax = Y;
Flags &= ~VoidMask;
}
else {
if (!(Flags & XminMask) && (X < Xmin)) Xmin = X;
else if (!(Flags & XmaxMask) && (X > Xmax)) Xmax = X;
if (!(Flags & YminMask) && (Y < Ymin)) Ymin = Y;
else if (!(Flags & YmaxMask) && (Y > Ymax)) Ymax = Y;
}
}
//=======================================================================
//function : Get
//purpose :
//=======================================================================
void Bnd_Box2d::Get (Standard_Real& x, Standard_Real& y,
Standard_Real& Xm, Standard_Real& Ym) const
{
if(Flags & VoidMask)
Standard_ConstructionError::Raise("Bnd_Box is void");
Standard_Real pinf = 1e+100; //-- Precision::Infinite();
if (Flags & XminMask) x = -pinf;
else x = Xmin-Gap;
if (Flags & XmaxMask) Xm = pinf;
else Xm = Xmax+Gap;
if (Flags & YminMask) y = -pinf;
else y = Ymin-Gap;
if (Flags & YmaxMask) Ym = pinf;
else Ym = Ymax+Gap;
}
//=======================================================================
//function : Transformed
//purpose :
//=======================================================================
Bnd_Box2d Bnd_Box2d::Transformed (const gp_Trsf2d& T) const
{
gp_TrsfForm F = T.Form();
Bnd_Box2d newb(*this);
if ( IsVoid() ) return newb;
if (F == gp_Identity) {}
else if (F == gp_Translation) {
Standard_Real DX,DY;
(T.TranslationPart()).Coord(DX,DY);
if (!(Flags & XminMask)) newb.Xmin += DX;
if (!(Flags & XmaxMask)) newb.Xmax += DX;
if (!(Flags & YminMask)) newb.Ymin += DY;
if (!(Flags & YmaxMask)) newb.Ymax += DY;
}
else {
gp_Pnt2d P[4];
Standard_Boolean Vertex[4];
Standard_Integer i;
Vertex[0] = Standard_True;
Vertex[1] = Standard_True;
Vertex[2] = Standard_True;
Vertex[3] = Standard_True;
gp_Dir2d D[6];
// Standard_Integer vertices = 0;
Standard_Integer directions = 0;
if (Flags & XminMask) {
D[directions].SetCoord(-1., 0.);
directions++;
Vertex[0] = Vertex[2] = Standard_False;
}
if (Flags & XmaxMask) {
D[directions].SetCoord( 1., 0.);
directions++;
Vertex[1] = Vertex[3] = Standard_False;
}
if (Flags & YminMask) {
D[directions].SetCoord( 0.,-1.);
directions++;
Vertex[0] = Vertex[1] = Standard_False;
}
if (Flags & YmaxMask) {
D[directions].SetCoord( 0., 1.);
directions++;
Vertex[2] = Vertex[3] = Standard_False;
}
newb.SetVoid();
for (i = 0; i < directions; i++) {
D[i].Transform(T);
newb.Add(D[i]);
}
P[0].SetCoord(Xmin,Ymin);
P[1].SetCoord(Xmax,Ymin);
P[2].SetCoord(Xmin,Ymax);
P[3].SetCoord(Xmax,Ymax);
if (Vertex[0]) {
P[0].Transform(T);
newb.Add(P[0]);
}
if (Vertex[1]) {
P[1].Transform(T);
newb.Add(P[1]);
}
if (Vertex[2]) {
P[2].Transform(T);
newb.Add(P[2]);
}
if (Vertex[3]) {
P[3].Transform(T);
newb.Add(P[3]);
}
newb.Gap=Gap;
}
return newb;
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Bnd_Box2d::Add (const Bnd_Box2d& Other)
{
if (IsWhole()) return;
else if (Other.IsVoid()) return;
else if (Other.IsWhole()) SetWhole();
else if (IsVoid()) (*this) = Other;
else
{
if ( ! IsOpenXmin() )
{
if (Other.IsOpenXmin()) OpenXmin();
else if (Xmin > Other.Xmin) Xmin = Other.Xmin;
}
if ( ! IsOpenXmax() )
{
if (Other.IsOpenXmax()) OpenXmax();
else if (Xmax < Other.Xmax) Xmax = Other.Xmax;
}
if ( ! IsOpenYmin() )
{
if (Other.IsOpenYmin()) OpenYmin();
else if (Ymin > Other.Ymin) Ymin = Other.Ymin;
}
if ( ! IsOpenYmax() )
{
if (Other.IsOpenYmax()) OpenYmax();
else if (Ymax < Other.Ymax) Ymax = Other.Ymax;
}
Gap = Max (Gap, Other.Gap);
}
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Bnd_Box2d::Add (const gp_Dir2d& D)
{
Standard_Real DX = D.X();
Standard_Real DY = D.Y();
if (DX < 0)
if (DX < - gp::Resolution()) OpenXmin();
else
if (DX > gp::Resolution()) OpenXmax();
if (DY < 0)
if (DY < - gp::Resolution()) OpenYmin();
else
if (DY > gp::Resolution()) OpenYmax();
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
Standard_Boolean Bnd_Box2d::IsOut (const gp_Pnt2d& P) const
{
if (IsWhole()) return Standard_False;
else if (IsVoid()) return Standard_True;
else {
Standard_Real X = P.X();
Standard_Real Y = P.Y();
if (!(Flags & XminMask) && (X < (Xmin-Gap))) return Standard_True;
else if (!(Flags & XmaxMask) && (X > (Xmax+Gap))) return Standard_True;
else if (!(Flags & YminMask) && (Y < (Ymin-Gap))) return Standard_True;
else if (!(Flags & YmaxMask) && (Y > (Ymax+Gap))) return Standard_True;
else return Standard_False;
}
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
Standard_Boolean Bnd_Box2d::IsOut (const Bnd_Box2d& Other) const
{
if (IsWhole()) return Standard_False;
else if (IsVoid()) return Standard_True;
else if (Other.IsWhole()) return Standard_False;
else if (Other.IsVoid()) return Standard_True;
else {
Bnd_Box2d OtherBox2d = Other; // DownEqual
Standard_Real OXmin,OXmax,OYmin,OYmax;
OtherBox2d.Get(OXmin,OYmin,OXmax,OYmax);
if (!(Flags & XminMask) && (OXmax < (Xmin-Gap))) return Standard_True;
else if (!(Flags & XmaxMask) && (OXmin > (Xmax+Gap))) return Standard_True;
else if (!(Flags & YminMask) && (OYmax < (Ymin-Gap))) return Standard_True;
else if (!(Flags & YmaxMask) && (OYmin > (Ymax+Gap))) return Standard_True;
}
return Standard_False;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Bnd_Box2d::Dump () const
{
cout << "Box2d : ";
if (IsVoid()) cout << "Void";
else if (IsWhole()) cout << "Whole";
else {
cout << "\n Xmin : ";
if (IsOpenXmin()) cout << "Infinite";
else cout << Xmin;
cout << "\n Xmax : ";
if (IsOpenXmax()) cout << "Infinite";
else cout << Xmax;
cout << "\n Ymin : ";
if (IsOpenYmin()) cout << "Infinite";
else cout << Ymin;
cout << "\n Ymax : ";
if (IsOpenYmax()) cout << "Infinite";
else cout << Ymax;
}
cout << "\n Gap : " << Gap;
cout << "\n";
}

223
src/Bnd/Bnd_Box2d.lxx Executable file
View File

@@ -0,0 +1,223 @@
// File: Bnd_Box2d.lxx
// Created: Thu Nov 27 11:12:34 1997
// Author: Christophe MARION
// <cma@partox.paris1.matra-dtv.fr>
#define VoidMask 0x01
#define XminMask 0x02
#define XmaxMask 0x04
#define YminMask 0x08
#define YmaxMask 0x10
#define WholeMask 0x1e
#include <gp_Pnt2d.hxx>
//=======================================================================
//function : Bnd_Box2d
//purpose :
//=======================================================================
inline Bnd_Box2d::Bnd_Box2d()
: Xmin(0.), Xmax(0.), Ymin(0.), Ymax(0.), Gap(0.), Flags (VoidMask)
{
}
//=======================================================================
//function : SetWhole
//purpose :
//=======================================================================
inline void Bnd_Box2d::SetWhole ()
{ Flags = WholeMask; }
//=======================================================================
//function : SetVoid
//purpose :
//=======================================================================
inline void Bnd_Box2d::SetVoid ()
{
Flags = VoidMask;
Gap=0.;
}
//=======================================================================
//function : Set
//purpose :
//=======================================================================
inline void Bnd_Box2d::Set(const gp_Pnt2d& P)
{
Flags = VoidMask;
Gap=0.;
Add(P);
}
//=======================================================================
//function : Set
//purpose :
//=======================================================================
inline void Bnd_Box2d::Set(const gp_Pnt2d& P, const gp_Dir2d& D)
{
Flags = VoidMask;
Gap=0.;
Add(P,D);
}
//=======================================================================
//function : GetGap
//purpose :
//=======================================================================
inline Standard_Real Bnd_Box2d::GetGap () const
{
return Gap;
}
//=======================================================================
//function : SetGap
//purpose :
//=======================================================================
inline void Bnd_Box2d::SetGap (const Standard_Real Tol)
{
Gap = Tol;
}
//=======================================================================
//function : Enlarge
//purpose :
//=======================================================================
inline void Bnd_Box2d::Enlarge (const Standard_Real Tol)
{
Standard_Real t = Tol;
if (t < 0) t = - t;
if (Gap < t) Gap = t;
}
//=======================================================================
//function : OpenXmin
//purpose :
//=======================================================================
inline void Bnd_Box2d::OpenXmin ()
{ Flags |= XminMask; }
//=======================================================================
//function : OpenXmax
//purpose :
//=======================================================================
inline void Bnd_Box2d::OpenXmax ()
{ Flags |= XmaxMask; }
//=======================================================================
//function : OpenYmin
//purpose :
//=======================================================================
inline void Bnd_Box2d::OpenYmin ()
{ Flags |= YminMask; }
//=======================================================================
//function : OpenYmax
//purpose :
//=======================================================================
inline void Bnd_Box2d::OpenYmax ()
{ Flags |= YmaxMask; }
//=======================================================================
//function : IsOpenXmin
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOpenXmin () const
{ return Flags & XminMask; }
//=======================================================================
//function : IsOpenXmax
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOpenXmax () const
{ return Flags & XmaxMask; }
//=======================================================================
//function : IsOpenYmin
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOpenYmin () const
{ return Flags & YminMask; }
//=======================================================================
//function : IsOpenYmax
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOpenYmax () const
{ return Flags & YmaxMask; }
//=======================================================================
//function : IsWhole
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsWhole () const
{ return (Flags & WholeMask) == WholeMask; }
//=======================================================================
//function : IsVoid
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsVoid () const
{ return Flags & VoidMask; }
//=======================================================================
//function : Add
//purpose :
//=======================================================================
inline void Bnd_Box2d::Add (const gp_Pnt2d& P)
{
Update(P.X(),P.Y());
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
inline void Bnd_Box2d::Add (const gp_Pnt2d& P, const gp_Dir2d& D)
{
Add(P);
Add(D);
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOut (const Bnd_Box2d& Other,
const gp_Trsf2d& T) const
{
return IsOut(Other.Transformed(T));
}
//=======================================================================
//function : IsOut
//purpose :
//=======================================================================
inline Standard_Boolean Bnd_Box2d::IsOut (const gp_Trsf2d& T1,
const Bnd_Box2d& Other,
const gp_Trsf2d& T2) const
{
return Transformed(T1).IsOut (Other.Transformed(T2));
}