/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2016, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Teigha(R) software pursuant to a license // agreement with Open Design Alliance. // Teigha(R) Copyright (C) 2002-2016 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef _SpBBox_h_Included_ #define _SpBBox_h_Included_ #include "Si/SiSpatialIndex.h" #include "Ge/GeBoundBlock3d.h" /** \details */ namespace OdSi { /** \details This class implements 3D Spatial Index bounding volumes. Library: SpatialIndex */ class BBox : public OdGeBoundBlock3d, public OdSiShape { public: enum ExtentsType { k2dExtents = 0, k3dExtents = 1 }; /** \details Explodes the specified extents box or bounding block into an array of points. \param extents [in] Any 3D extents or BoundBlock object. \param points [out] Receives the array[8] of points. \returns Returns the ExtentsType of the specified exents. \remarks explodeExtent() returns one of the following: Name Value k2dExtents 0 k3dExtents 1
The points array will start at extents.minPoint, and proceed clockwise about the extents. It will then repeat this sequence at the top of the extents. */ static ExtentsType explodeExtent(OdGePoint3d* points, const OdGeExtents3d& extents) { points[0] = extents.minPoint(); points[1].set( extents.minPoint().x, extents.maxPoint().y, extents.minPoint().z ); points[2].set( extents.maxPoint().x, extents.maxPoint().y, extents.minPoint().z ); points[3].set( extents.maxPoint().x, extents.minPoint().y, extents.minPoint().z ); if(points->z == extents.maxPoint().z) return k2dExtents; points[4].set( extents.minPoint().x, extents.minPoint().y, extents.maxPoint().z ); points[5].set( extents.minPoint().x, extents.maxPoint().y, extents.maxPoint().z ); points[6] = extents.maxPoint(); points[7].set( extents.maxPoint().x, extents.minPoint().y, extents.maxPoint().z ); return k3dExtents; } static ExtentsType explodeExtent(OdGePoint3d* points, const OdGeBoundBlock3d& extents) { OdGeVector3d side1, side2, side3; extents.get(points[0], side1, side2, side3); points[1] = points[0] + side1; points[2] = points[0] + side1 + side2; points[3] = points[0] + side2; if(OdZero(side3.length())) return k2dExtents; points[4] = points[0] + side3; points[5] = points[1] + side3; points[6] = points[2] + side3; points[7] = points[3] + side3; return k3dExtents; } virtual bool contains( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol ) const { ODA_ASSERT( planar == false ); if ( !OdGeBoundBlock3d::contains( extents.minPoint(), tol ) ) return false; if ( !OdGeBoundBlock3d::contains( extents.maxPoint(), tol ) ) return false; if ( !OdGeBoundBlock3d::contains( OdGePoint3d( extents.minPoint().x, extents.maxPoint().y, extents.minPoint().z ), tol ) ) return false; if ( !OdGeBoundBlock3d::contains( OdGePoint3d( extents.maxPoint().x, extents.minPoint().y, extents.minPoint().z ), tol ) ) return false; if(OdEqual(extents.maxPoint().z, extents.minPoint().z, tol.equalPoint())) return true; if ( !OdGeBoundBlock3d::contains( OdGePoint3d( extents.minPoint().x, extents.maxPoint().y, extents.maxPoint().z ), tol ) ) return false; if ( !OdGeBoundBlock3d::contains( OdGePoint3d( extents.maxPoint().x, extents.minPoint().y, extents.maxPoint().z ), tol ) ) return false; return true; } virtual bool intersects( const OdGeExtents3d& extents, bool planar = false, const OdGeTol& tol = OdGeContext::gTol) const { ODA_ASSERT( planar == false ); if (isBox()) { OdGePoint3d minPt, maxPt; getMinMaxPoints(minPt, maxPt); return !OdGeExtents3d(minPt, maxPt).isDisjoint(extents, tol); } else return !OdGeBoundBlock3d( extents.minPoint(), extents.maxPoint() ).isDisjoint( *this, tol ); } virtual OdSiShape* clone() const { return new BBox(*this); } virtual void transform(const OdGeMatrix3d& mtx) { setToBox(false); transformBy(mtx); setToBoxOrtho(); } /** \param p1 [in] First point of a coordinate-aligned block. \param p2 [in] Second point of a coordinate-aligned block. \param base [in] Base of parallelepiped bounding block. \param side1 [in] First side of parallelepiped bounding block. \param side2 [in] Second side of parallelepiped bounding block. \param side3 [in] Third side of parallelepiped bounding block. \param source [in] Object to be cloned. \remarks The default constructor constructs a parallelepiped reduced to the coordinate origin. A parallelepiped is a parallelogram extruded in an arbitrary direction. */ BBox() {} BBox( const BBox& source ) : OdGeBoundBlock3d( source ) {} BBox( const OdGePoint3d& base, const OdGeVector3d& side1, const OdGeVector3d& side2, const OdGeVector3d& side3 ) : OdGeBoundBlock3d( base, side1, side2, side3 ) { setToBoxOrtho(side1, side2, side3); } BBox( const OdGePoint3d& p1, const OdGePoint3d& p2 ) : OdGeBoundBlock3d( p1, p2 ){} }; } #endif