File indexing completed on 2026-09-16 09:16:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _Bnd_OBB_HeaderFile
0016 #define _Bnd_OBB_HeaderFile
0017
0018 #include <Standard.hxx>
0019 #include <Standard_DefineAlloc.hxx>
0020 #include <Standard_Handle.hxx>
0021
0022 #include <Bnd_Box.hxx>
0023 #include <gp_Ax3.hxx>
0024 #include <gp_Dir.hxx>
0025 #include <gp_Pnt.hxx>
0026 #include <gp_XYZ.hxx>
0027 #include <NCollection_Array1.hxx>
0028
0029
0030
0031
0032
0033
0034
0035
0036 class Bnd_OBB
0037 {
0038 public:
0039 DEFINE_STANDARD_ALLOC
0040
0041
0042
0043
0044
0045
0046 struct HalfSizes
0047 {
0048 double X;
0049 double Y;
0050 double Z;
0051 };
0052
0053
0054 Bnd_OBB()
0055 : myIsAABox(false)
0056 {
0057 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
0058 }
0059
0060
0061 Bnd_OBB(const gp_Pnt& theCenter,
0062 const gp_Dir& theXDirection,
0063 const gp_Dir& theYDirection,
0064 const gp_Dir& theZDirection,
0065 const double theHXSize,
0066 const double theHYSize,
0067 const double theHZSize)
0068 : myCenter(theCenter.XYZ()),
0069 myIsAABox(false)
0070 {
0071 myAxes[0] = theXDirection.XYZ();
0072 myAxes[1] = theYDirection.XYZ();
0073 myAxes[2] = theZDirection.XYZ();
0074
0075 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
0076 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
0077 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
0078
0079 myHDims[0] = theHXSize;
0080 myHDims[1] = theHYSize;
0081 myHDims[2] = theHZSize;
0082 }
0083
0084
0085 Bnd_OBB(const Bnd_Box& theBox)
0086 : myIsAABox(true)
0087 {
0088 if (theBox.IsVoid())
0089 {
0090 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
0091 myIsAABox = false;
0092 return;
0093 }
0094
0095 double aX1, aY1, aZ1, aX2, aY2, aZ2;
0096 theBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);
0097
0098 myAxes[0].SetCoord(1.0, 0.0, 0.0);
0099 myAxes[1].SetCoord(0.0, 1.0, 0.0);
0100 myAxes[2].SetCoord(0.0, 0.0, 1.0);
0101
0102 myHDims[0] = 0.5 * (aX2 - aX1);
0103 myHDims[1] = 0.5 * (aY2 - aY1);
0104 myHDims[2] = 0.5 * (aZ2 - aZ1);
0105
0106 myCenter.SetCoord(0.5 * (aX2 + aX1), 0.5 * (aY2 + aY1), 0.5 * (aZ2 + aZ1));
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 Standard_EXPORT void ReBuild(const NCollection_Array1<gp_Pnt>& theListOfPoints,
0118 const NCollection_Array1<double>* theListOfTolerances = nullptr,
0119 const bool theIsOptimal = false);
0120
0121
0122 void SetCenter(const gp_Pnt& theCenter) { myCenter = theCenter.XYZ(); }
0123
0124
0125 void SetXComponent(const gp_Dir& theXDirection, const double theHXSize)
0126 {
0127 Standard_ASSERT_VOID(theHXSize >= 0.0, "Negative value of X-size");
0128
0129 myAxes[0] = theXDirection.XYZ();
0130 myHDims[0] = theHXSize;
0131 }
0132
0133
0134 void SetYComponent(const gp_Dir& theYDirection, const double theHYSize)
0135 {
0136 Standard_ASSERT_VOID(theHYSize >= 0.0, "Negative value of Y-size");
0137
0138 myAxes[1] = theYDirection.XYZ();
0139 myHDims[1] = theHYSize;
0140 }
0141
0142
0143 void SetZComponent(const gp_Dir& theZDirection, const double theHZSize)
0144 {
0145 Standard_ASSERT_VOID(theHZSize >= 0.0, "Negative value of Z-size");
0146
0147 myAxes[2] = theZDirection.XYZ();
0148 myHDims[2] = theHZSize;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158 [[nodiscard]] gp_Ax3 Position() const { return gp_Ax3(myCenter, ZDirection(), XDirection()); }
0159
0160
0161 [[nodiscard]] const gp_XYZ& Center() const noexcept { return myCenter; }
0162
0163
0164 [[nodiscard]] const gp_XYZ& XDirection() const noexcept { return myAxes[0]; }
0165
0166
0167 [[nodiscard]] const gp_XYZ& YDirection() const noexcept { return myAxes[1]; }
0168
0169
0170 [[nodiscard]] const gp_XYZ& ZDirection() const noexcept { return myAxes[2]; }
0171
0172
0173 [[nodiscard]] double XHSize() const noexcept { return myHDims[0]; }
0174
0175
0176 [[nodiscard]] double YHSize() const noexcept { return myHDims[1]; }
0177
0178
0179 [[nodiscard]] double ZHSize() const noexcept { return myHDims[2]; }
0180
0181
0182
0183
0184
0185
0186 [[nodiscard]] HalfSizes GetHalfSizes() const noexcept
0187 {
0188 return {myHDims[0], myHDims[1], myHDims[2]};
0189 }
0190
0191
0192 [[nodiscard]] bool IsVoid() const noexcept
0193 {
0194 return ((myHDims[0] < 0.0) || (myHDims[1] < 0.0) || (myHDims[2] < 0.0));
0195 }
0196
0197
0198 void SetVoid()
0199 {
0200 myHDims[0] = myHDims[1] = myHDims[2] = -1.0;
0201 myCenter = myAxes[0] = myAxes[1] = myAxes[2] = gp_XYZ();
0202 myIsAABox = false;
0203 }
0204
0205
0206 void SetAABox(const bool& theFlag) { myIsAABox = theFlag; }
0207
0208
0209 [[nodiscard]] bool IsAABox() const noexcept { return myIsAABox; }
0210
0211
0212 void Enlarge(const double theGapAdd)
0213 {
0214 const double aGap = std::abs(theGapAdd);
0215 myHDims[0] += aGap;
0216 myHDims[1] += aGap;
0217 myHDims[2] += aGap;
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 bool GetVertex(gp_Pnt theP[8]) const
0232 {
0233 if (IsVoid())
0234 return false;
0235
0236 theP[0].SetXYZ(myCenter - myHDims[0] * myAxes[0] - myHDims[1] * myAxes[1]
0237 - myHDims[2] * myAxes[2]);
0238 theP[1].SetXYZ(myCenter + myHDims[0] * myAxes[0] - myHDims[1] * myAxes[1]
0239 - myHDims[2] * myAxes[2]);
0240 theP[2].SetXYZ(myCenter - myHDims[0] * myAxes[0] + myHDims[1] * myAxes[1]
0241 - myHDims[2] * myAxes[2]);
0242 theP[3].SetXYZ(myCenter + myHDims[0] * myAxes[0] + myHDims[1] * myAxes[1]
0243 - myHDims[2] * myAxes[2]);
0244 theP[4].SetXYZ(myCenter - myHDims[0] * myAxes[0] - myHDims[1] * myAxes[1]
0245 + myHDims[2] * myAxes[2]);
0246 theP[5].SetXYZ(myCenter + myHDims[0] * myAxes[0] - myHDims[1] * myAxes[1]
0247 + myHDims[2] * myAxes[2]);
0248 theP[6].SetXYZ(myCenter - myHDims[0] * myAxes[0] + myHDims[1] * myAxes[1]
0249 + myHDims[2] * myAxes[2]);
0250 theP[7].SetXYZ(myCenter + myHDims[0] * myAxes[0] + myHDims[1] * myAxes[1]
0251 + myHDims[2] * myAxes[2]);
0252
0253 return true;
0254 }
0255
0256
0257 [[nodiscard]] double SquareExtent() const noexcept
0258 {
0259 return 4.0 * (myHDims[0] * myHDims[0] + myHDims[1] * myHDims[1] + myHDims[2] * myHDims[2]);
0260 }
0261
0262
0263 [[nodiscard]] Standard_EXPORT bool IsOut(const Bnd_OBB& theOther) const;
0264
0265
0266 [[nodiscard]] Standard_EXPORT bool IsOut(const gp_Pnt& theP) const;
0267
0268
0269 [[nodiscard]] bool Contains(const gp_Pnt& theP) const { return !IsOut(theP); }
0270
0271
0272 [[nodiscard]] bool Intersects(const Bnd_OBB& theOther) const { return !IsOut(theOther); }
0273
0274
0275 [[nodiscard]] Standard_EXPORT bool IsCompletelyInside(const Bnd_OBB& theOther) const;
0276
0277
0278
0279 Standard_EXPORT void Add(const Bnd_OBB& theOther);
0280
0281
0282
0283 Standard_EXPORT void Add(const gp_Pnt& theP);
0284
0285
0286 Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
0287
0288 protected:
0289 void ProcessOnePoint(const gp_Pnt& theP)
0290 {
0291 myIsAABox = true;
0292 myHDims[0] = myHDims[1] = myHDims[2] = 0.0;
0293 myAxes[0].SetCoord(1.0, 0.0, 0.0);
0294 myAxes[1].SetCoord(0.0, 1.0, 0.0);
0295 myAxes[2].SetCoord(0.0, 0.0, 1.0);
0296 myCenter = theP.XYZ();
0297 }
0298
0299 private:
0300
0301 gp_XYZ myCenter;
0302
0303
0304
0305 gp_XYZ myAxes[3];
0306
0307
0308 double myHDims[3];
0309
0310
0311 bool myIsAABox;
0312 };
0313
0314 #endif