]> OCCT Git - occt-copy.git/commitdiff
Implementation of the Oriented Bounding Boxes using PCA-based algorithm to use in... CR0-720-FixAS_OBB
authoremv <emv@opencascade.com>
Wed, 1 Nov 2017 08:30:30 +0000 (11:30 +0300)
committeremv <emv@opencascade.com>
Thu, 2 Nov 2017 11:39:00 +0000 (14:39 +0300)
OBB is implemented in IntTools_OBB class, and is represented as center, axes and half-size dimensions.

The method IntTools_OBB::IsOut(theOther) is based on the Separated Axes theorem for Oriented Bounding Boxes.
According to this theorem it is necessary to consider 15 separating axes.

By default the OBB are not used. To enable the OBB usage in Boolean Operations it is necessary to call the method BOPAlgo_PaveFiller::SetUseOBB(const Standard_Boolean theFlag) with TRUE value.
To enable OBB usage in DRAW it is necessary to use the command:
buseobb 1

31 files changed:
src/BOPAlgo/BOPAlgo_BOP.cxx
src/BOPAlgo/BOPAlgo_Builder.cxx
src/BOPAlgo/BOPAlgo_CheckerSI.cxx
src/BOPAlgo/BOPAlgo_MakerVolume.cxx
src/BOPAlgo/BOPAlgo_Options.cxx
src/BOPAlgo/BOPAlgo_Options.hxx
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_Splitter.cxx
src/BOPDS/BOPDS_Iterator.cxx
src/BOPDS/BOPDS_Iterator.hxx
src/BOPDS/BOPDS_IteratorSI.cxx
src/BOPDS/BOPDS_IteratorSI.hxx
src/BOPTest/BOPTest_APICommands.cxx
src/BOPTest/BOPTest_BOPCommands.cxx
src/BOPTest/BOPTest_CellsCommands.cxx
src/BOPTest/BOPTest_DebugCommands.cxx
src/BOPTest/BOPTest_Objects.cxx
src/BOPTest/BOPTest_Objects.hxx
src/BOPTest/BOPTest_OptionCommands.cxx
src/BOPTest/BOPTest_PartitionCommands.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx
src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx
src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Splitter.cxx
src/IntTools/FILES
src/IntTools/IntTools_Context.cxx
src/IntTools/IntTools_Context.hxx
src/IntTools/IntTools_OBB.cxx [new file with mode: 0644]
src/IntTools/IntTools_OBB.hxx [new file with mode: 0644]
src/IntTools/IntTools_Tools.cxx
src/IntTools/IntTools_Tools.hxx

index 7004b3ac3b92c12eb9279dd287cc16992481552e..82bb2e103c4629c3276d1107bdd5fe4296442772 100644 (file)
@@ -411,6 +411,7 @@ void BOPAlgo_BOP::Perform()
   pPF->SetFuzzyValue(myFuzzyValue);
   pPF->SetNonDestructive(myNonDestructive);
   pPF->SetGlue(myGlue);
+  pPF->SetUseOBB(myUseOBB);
   //
   pPF->Perform();
   //
index 9b2302f5547777ac2623265e3036d51921c7d45f..20f74f4362a321fdb0219ed45f3c4dcc1357aa24 100644 (file)
@@ -286,6 +286,7 @@ void BOPAlgo_Builder::Perform()
   pPF->SetFuzzyValue(myFuzzyValue);
   pPF->SetNonDestructive(myNonDestructive);
   pPF->SetGlue(myGlue);
+  pPF->SetUseOBB(myUseOBB);
   //
   pPF->Perform();
   //
@@ -303,6 +304,7 @@ void BOPAlgo_Builder::PerformWithFiller(const BOPAlgo_PaveFiller& theFiller)
   myNonDestructive = theFiller.NonDestructive();
   myFuzzyValue = theFiller.FuzzyValue();
   myGlue = theFiller.Glue();
+  myUseOBB = theFiller.UseOBB();
   PerformInternal(theFiller);
 }
 //=======================================================================
index 35dfe50e7be47c50d1569de758f89dfe9256dca8..f1f448503e6c8763e897589afece728e1c4ed588 100644 (file)
@@ -159,16 +159,16 @@ void BOPAlgo_CheckerSI::Init()
   myDS->SetArguments(myArguments);
   myDS->Init(myFuzzyValue);
   //
-  // 2.myIterator 
+  // 2 myContext
+  myContext=new IntTools_Context;
+  //
+  // 3.myIterator 
   BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
   theIterSI->SetDS(myDS);
-  theIterSI->Prepare();
+  theIterSI->Prepare(myContext, myUseOBB);
   theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
   //
   myIterator=theIterSI;
-  //
-  // 3 myContext
-  myContext=new IntTools_Context;
 }
 //=======================================================================
 //function : Perform
index 695118a3976b96f36a5e48e338ee576faf610d69..31777c2a7248532ce95ed790fe2c4314ed2e490f 100644 (file)
@@ -94,6 +94,7 @@ void BOPAlgo_MakerVolume::Perform()
   pPF->SetFuzzyValue(myFuzzyValue);
   pPF->SetNonDestructive(myNonDestructive);
   pPF->SetGlue(myGlue);
+  pPF->SetUseOBB(myUseOBB);
   pPF->Perform();
   //
   myEntryPoint = 1;
index ac5445b4d02a19c3d7c1e6339083b5231a0d8150..a8864186d2d51fb8d75c682065ce6cc5fcfc3b24 100644 (file)
@@ -51,7 +51,8 @@ BOPAlgo_Options::BOPAlgo_Options()
   myReport(new Message_Report),
   myRunParallel(myGlobalRunParallel),
   myFuzzyValue(Precision::Confusion()),
-  myCheckInverted(Standard_True)
+  myCheckInverted(Standard_True),
+  myUseOBB(Standard_False)
 {
   BOPAlgo_LoadMessages();
 }
@@ -67,7 +68,8 @@ BOPAlgo_Options::BOPAlgo_Options
   myReport(new Message_Report),
   myRunParallel(myGlobalRunParallel),
   myFuzzyValue(Precision::Confusion()),
-  myCheckInverted(Standard_True)
+  myCheckInverted(Standard_True),
+  myUseOBB(Standard_False)
 {
   BOPAlgo_LoadMessages();
 }
index e10cf0e1ec4b9aa258828c71f50889eef6c8dc51..4b61ff602ffa7d56c8bcdf453837ca457d33294a 100644 (file)
@@ -36,6 +36,8 @@ class Message_ProgressIndicator;
 //!                          for inverted status (holes in the space). The default value is TRUE,
 //!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
 //!                          most likely will lead to incorrect results.
+//! - *Using the Oriented Bounding Boxes* - Allows using the Oriented Bounding Boxes of the shapes
+//!                          for filtering the intersections.
 //!
 class BOPAlgo_Options
 {
@@ -176,6 +178,21 @@ public:
     return myCheckInverted;
   }
 
+public:
+  //!@name Usage of Oriented Bounding boxes
+
+  //! Enables/Disables the usage of OBB
+  void SetUseOBB(const Standard_Boolean theUseOBB)
+  {
+    myUseOBB = theUseOBB;
+  }
+
+  //! Returns the flag defining usage of OBB
+  Standard_Boolean UseOBB() const
+  {
+    return myUseOBB;
+  }
+
 protected:
 
   //! Breaks the execution if the break signal
@@ -190,6 +207,7 @@ protected:
   Standard_Real myFuzzyValue;
   Handle(Message_ProgressIndicator) myProgressIndicator;
   Standard_Boolean myCheckInverted;
+  Standard_Boolean myUseOBB;
 
 };
 
index 5867221f5e96d1c5267aacd2a237ca07cbf048a2..00e89a19bf20b916bf0675e4ff6f57cfd8df78d4 100644 (file)
@@ -211,14 +211,14 @@ void BOPAlgo_PaveFiller::Init()
   myDS->SetArguments(myArguments);
   myDS->Init(myFuzzyValue);
   //
-  // 2.myIterator 
+  // 2 myContext
+  myContext=new IntTools_Context;
+  //
+  // 3.myIterator 
   myIterator=new BOPDS_Iterator(myAllocator);
   myIterator->SetRunParallel(myRunParallel);
   myIterator->SetDS(myDS);
-  myIterator->Prepare();
-  //
-  // 3 myContext
-  myContext=new IntTools_Context;
+  myIterator->Prepare(myContext, myUseOBB);
   //
   // 4 NonDestructive flag
   SetNonDestructive();
index 0d073b08c8e17a9261ad8b192820242b81f06847..8c4a4720b1a83b065e4591db9f0d154c3af2ba1b 100644 (file)
@@ -131,6 +131,7 @@ void BOPAlgo_Splitter::Perform()
   pPF->SetFuzzyValue(myFuzzyValue);
   pPF->SetNonDestructive(myNonDestructive);
   pPF->SetGlue(myGlue);
+  pPF->SetUseOBB(myUseOBB);
   //
   pPF->Perform();
   //
index d3e80582ad6c2ba92aff1f12cee85af4a2812b54..b8c4fc78ef3409854632d65705e99553967dca83 100644 (file)
 #include <NCollection_UBTreeFiller.hxx>
 #include <TopoDS_Shape.hxx>
 #include <algorithm>
+#include <IntTools_Context.hxx>
+#include <IntTools_OBB.hxx>
+
+#ifdef DEBUG_OBB
+#include <IntTools_Tools.hxx>
+#endif
 
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
@@ -240,7 +246,8 @@ void BOPDS_Iterator::Value(Standard_Integer& theI1,
 // function: Prepare
 // purpose: 
 //=======================================================================
-void BOPDS_Iterator::Prepare()
+void BOPDS_Iterator::Prepare(Handle(IntTools_Context)& theCtx,
+                             const Standard_Boolean theCheckOBB)
 {
   Standard_Integer i, aNbInterfTypes;
   //
@@ -253,14 +260,15 @@ void BOPDS_Iterator::Prepare()
   if (myDS==NULL){
     return;
   }
-  Intersect();
+  Intersect(theCtx, theCheckOBB);
 }
 //
 //=======================================================================
 // function: Intersect
 // purpose: 
 //=======================================================================
-void BOPDS_Iterator::Intersect()
+void BOPDS_Iterator::Intersect(Handle(IntTools_Context)& theCtx,
+                               const Standard_Boolean theCheckOBB)
 {
   Standard_Integer i, j, iX, i1, i2, iR, aNb, aNbR;
   Standard_Integer iTi, iTj;
@@ -304,7 +312,7 @@ void BOPDS_Iterator::Intersect()
     i1 = aR.First();
     i2 = aR.Last();
     for (i = i1; i <= i2; ++i) {
-      const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+      BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
       //
       if (!aSI.IsInterfering() || (aSI.ShapeType() == TopAbs_SOLID)) {
         continue;
@@ -327,7 +335,7 @@ void BOPDS_Iterator::Intersect()
           continue;// same range
         }
         //
-        const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j);
+        BOPDS_ShapeInfo& aSJ = myDS->ChangeShapeInfo(j);
         aTj = aSJ.ShapeType();
         iTj = BOPDS_Tools::TypeToInteger(aTj);
         //
@@ -339,6 +347,19 @@ void BOPDS_Iterator::Intersect()
         //
         BOPDS_Pair aPair(i, j);
         if (aMPFence.Add(aPair)) {
+          if (theCheckOBB)
+          {
+            IntTools_OBB& anOBBi = theCtx->OBB(aSI.Shape(), aSI.Box().GetGap());
+            IntTools_OBB& anOBBj = theCtx->OBB(aSJ.Shape(), aSJ.Box().GetGap());
+
+#ifdef DEBUG_OBB
+            TopoDS_Shape aBox1 = IntTools_Tools::GetOBBShapeBox(anOBBi);
+            TopoDS_Shape aBox2 = IntTools_Tools::GetOBBShapeBox(anOBBj);
+#endif
+            if (anOBBi.IsOut(anOBBj))
+              continue;
+          }
+
           iX = BOPDS_Tools::TypeToInteger(aTi, aTj);
           myLists(iX).Append(aPair);
         }// if (aMPFence.Add(aPair)) {
index 9e3313092b2d002454720bae8a7c7fb4411dcb99..848ed566083341eb23b8883a9a1b751216acf5f5 100644 (file)
@@ -30,7 +30,7 @@
 #include <Standard_Boolean.hxx>
 #include <TopAbs_ShapeEnum.hxx>
 class BOPDS_DS;
-
+class IntTools_Context;
 
 
 //! The class BOPDS_Iterator is
@@ -81,7 +81,8 @@ public:
 
   //! Perform the intersection algorithm and prepare
   //! the results to be used
-  Standard_EXPORT virtual void Prepare();
+  Standard_EXPORT virtual void Prepare(Handle(IntTools_Context)& theCtx,
+                                       const Standard_Boolean theCheckOBB = Standard_False);
 
   //! Returns the number of intersections founded
   Standard_EXPORT Standard_Integer ExpectedLength() const;
@@ -99,7 +100,8 @@ public:
 
 protected:
 
-  Standard_EXPORT virtual void Intersect();
+  Standard_EXPORT virtual void Intersect(Handle(IntTools_Context)& theCtx,
+                                         const Standard_Boolean theCheckOBB = Standard_False);
 
   BOPCol_BaseAllocator myAllocator;
   Standard_Integer myLength;
index 2feaa9b761d0642a76c286d9abdfda6502c69c33..c35ed5357d867a00595e357689b4e6d3f2f5dce7 100644 (file)
@@ -33,6 +33,8 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <IntTools_Context.hxx>
+#include <IntTools_OBB.hxx>
 
 //
 //=======================================================================
@@ -78,7 +80,8 @@ void BOPDS_IteratorSI::UpdateByLevelOfCheck(const Standard_Integer theLevel)
 // function: Intersect
 // purpose: 
 //=======================================================================
-void BOPDS_IteratorSI::Intersect()
+void BOPDS_IteratorSI::Intersect(Handle(IntTools_Context)& theCtx,
+                                 const Standard_Boolean theCheckOBB)
 {
   Standard_Integer i, j, iX, aNbS;
   Standard_Integer iTi, iTj;
@@ -138,6 +141,15 @@ void BOPDS_IteratorSI::Intersect()
       //
       BOPDS_Pair aPair(i, j);
       if (aMPFence.Add(aPair)) {
+        if (theCheckOBB)
+        {
+          IntTools_OBB& anOBBi = theCtx->OBB(aSI.Shape(), aSI.Box().GetGap());
+          IntTools_OBB& anOBBj = theCtx->OBB(aSJ.Shape(), aSJ.Box().GetGap());
+
+          if (anOBBi.IsOut(anOBBj))
+            continue;
+        }
+
         iX = BOPDS_Tools::TypeToInteger(aTi, aTj);
         myLists(iX).Append(aPair);
       }// if (aMPKXB.Add(aPKXB)) {
index a0d9b9ab455eb660521f5e716b70279417d6d337..3783e43c4aa3cf7b36069b4db0fed95a43391d10 100644 (file)
@@ -68,7 +68,8 @@ Standard_EXPORT virtual ~BOPDS_IteratorSI();
 protected:
 
   
-  Standard_EXPORT virtual void Intersect() Standard_OVERRIDE;
+  Standard_EXPORT virtual void Intersect(Handle(IntTools_Context)& theCtx,
+                                         const Standard_Boolean theCheckOBB = Standard_False) Standard_OVERRIDE;
 
 
 
index 4096800bdfee1d18fa9b438265bd67bae37abb2c..b6ce3f102b783f17b153898fbc536c7a8096dfea 100644 (file)
@@ -134,6 +134,7 @@ Standard_Integer bapibop(Draw_Interpretor& di,
   pBuilder->SetNonDestructive(bNonDestructive);
   pBuilder->SetGlue(aGlue);
   pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
+  pBuilder->SetUseOBB(BOPTest_Objects::UseOBB());
   //
   pBuilder->Build(); 
   //
@@ -195,6 +196,7 @@ Standard_Integer bapibuild(Draw_Interpretor& di,
   aBuilder.SetNonDestructive(bNonDestructive);
   aBuilder.SetGlue(aGlue);
   aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
+  aBuilder.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   aBuilder.Build(); 
   //
@@ -260,6 +262,7 @@ Standard_Integer bapisplit(Draw_Interpretor& di,
   aSplitter.SetNonDestructive(BOPTest_Objects::NonDestructive());
   aSplitter.SetGlue(BOPTest_Objects::Glue());
   aSplitter.SetCheckInverted(BOPTest_Objects::CheckInverted());
+  aSplitter.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   // performing operation
   aSplitter.Build();
index 427f052cab30b6706b71a74e7660981e03369760..bb1e09c1869204475af7bd9ec35dbcb9b7bf943d 100644 (file)
@@ -158,6 +158,7 @@ Standard_Integer bop(Draw_Interpretor& di,
   pPF->SetRunParallel(bRunParallel);
   pPF->SetNonDestructive(bNonDestructive);
   pPF->SetGlue(aGlue);
+  pPF->SetUseOBB(BOPTest_Objects::UseOBB());
   //
   pPF->Perform();
   BOPTest::ReportAlerts(*pPF);
@@ -427,6 +428,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
   aSec.SetRunParallel(bRunParallel);
   aSec.SetNonDestructive(bNonDestructive);
   aSec.SetGlue(aGlue);
+  aSec.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   aSec.Build();
   //
@@ -496,6 +498,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
   aPF.SetRunParallel(bRunParallel);
   aPF.SetNonDestructive(bNonDestructive);
   aPF.SetGlue(aGlue);
+  aPF.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   aPF.Perform();
   BOPTest::ReportAlerts(aPF);
@@ -818,6 +821,7 @@ Standard_Integer mkvolume(Draw_Interpretor& di, Standard_Integer n, const char**
   aMV.SetNonDestructive(bNonDestructive);
   aMV.SetAvoidInternalShapes(bAvoidInternal);
   aMV.SetGlue(aGlue);
+  aMV.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   aMV.Perform();
   BOPTest::ReportAlerts(aMV);
index 037305314611d5963d60d4594427bde18207ff43..87b09cc28148b88de44631bc35be09fdbf0d5a18 100644 (file)
@@ -112,6 +112,7 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
   aCBuilder.SetNonDestructive(bNonDestructive);
   aCBuilder.SetGlue(aGlue);
   aCBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
+  aCBuilder.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   aCBuilder.PerformWithFiller(aPF); 
   BOPTest::ReportAlerts(aCBuilder);
index f5b5279e40ced73e813cfbc8e1d7be32432e638c..0b42c4b196477b9d8005fa0feeab3ed054a03968 100644 (file)
@@ -40,6 +40,7 @@
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
 
+#include <IntTools_Context.hxx>
 
 static
   void GetTypeByName(const char* theName,
@@ -239,9 +240,11 @@ Standard_Integer bopiterator (Draw_Interpretor& di,
   char buf[64], aST1[10], aST2[10];
   BOPDS_Iterator aIt;
   //
+  Handle(IntTools_Context) aCtx = new IntTools_Context();
+
   BOPDS_DS& aDS = *pDS;
   aIt.SetDS(&aDS);
-  aIt.Prepare();
+  aIt.Prepare(aCtx, BOPTest_Objects::UseOBB());
   //
   if (n == 1) {
     // type has not been defined. show all pairs
index 61c3416fa2386c24f17bf59f984245db7a1fabcb..401b6d735a2314162afd19e4077c02caa2a06a87 100644 (file)
@@ -56,6 +56,7 @@ class BOPTest_Session {
     myGlue = BOPAlgo_GlueOff;
     myDrawWarnShapes = Standard_False;
     myCheckInverted = Standard_True;
+    myUseOBB = Standard_False;
   };
   //
   // Clear
@@ -151,6 +152,13 @@ class BOPTest_Session {
     return myCheckInverted;
   };
   //
+  void SetUseOBB(const Standard_Boolean bUse) {
+    myUseOBB = bUse;
+  };
+  //
+  Standard_Boolean UseOBB() const {
+    return myUseOBB;
+  };
 protected:
   //
   BOPTest_Session(const BOPTest_Session&);
@@ -170,6 +178,7 @@ protected:
   BOPAlgo_GlueEnum myGlue;
   Standard_Boolean myDrawWarnShapes;
   Standard_Boolean myCheckInverted;
+  Standard_Boolean myUseOBB;
 };
 //
 //=======================================================================
@@ -396,6 +405,22 @@ Standard_Boolean BOPTest_Objects::CheckInverted()
   return GetSession().CheckInverted();
 }
 //=======================================================================
+//function : SetUseOBB
+//purpose  : 
+//=======================================================================
+void BOPTest_Objects::SetUseOBB(const Standard_Boolean bUseOBB)
+{
+  GetSession().SetUseOBB(bUseOBB);
+}
+//=======================================================================
+//function : UseOBB
+//purpose  : 
+//=======================================================================
+Standard_Boolean BOPTest_Objects::UseOBB()
+{
+  return GetSession().UseOBB();
+}
+//=======================================================================
 //function : Allocator1
 //purpose  : 
 //=======================================================================
index 02911bc0d0df3c0f8bb2eb5f92fbd3685cf2eac7..221f0e66d860a55cfb740807b8e095e5a16b124b 100644 (file)
@@ -91,6 +91,10 @@ public:
 
   Standard_EXPORT static Standard_Boolean CheckInverted();
 
+  Standard_EXPORT static void SetUseOBB(const Standard_Boolean bUseOBB);
+
+  Standard_EXPORT static Standard_Boolean UseOBB();
+
 protected:
 
 private:
index b90a40f5ec564ae7f6951cd3825700c8358fa7ff..be4b06330c8354cc8edd97281cbe07e876f35e6b 100644 (file)
@@ -28,6 +28,7 @@ static Standard_Integer bfuzzyvalue(Draw_Interpretor&, Standard_Integer, const c
 static Standard_Integer bGlue(Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer bdrawwarnshapes(Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer bcheckinverted(Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer buseobb(Draw_Interpretor&, Standard_Integer, const char**);
 
 //=======================================================================
 //function : OptionCommands
@@ -51,6 +52,8 @@ void BOPTest::OptionCommands(Draw_Interpretor& theCommands)
                   __FILE__, bdrawwarnshapes, g);
   theCommands.Add("bcheckinverted", "Defines whether to check the input solids on inverted status or not\n"
                                      "Usage: bcheckinverted [0 (off) / 1 (on)]", __FILE__, bcheckinverted, g);
+  theCommands.Add("buseobb", "Enables/disables the usage of OBB\n"
+                                     "Usage: buseobb [0 (off) / 1 (on)]", __FILE__, buseobb, g);
 }
 //=======================================================================
 //function : boptions
@@ -76,6 +79,7 @@ Standard_Integer boptions(Draw_Interpretor& di,
   aGlue = BOPTest_Objects::Glue();
   Standard_Boolean bDrawWarnShapes = BOPTest_Objects::DrawWarnShapes();
   Standard_Boolean bCheckInverted = BOPTest_Objects::CheckInverted();
+  Standard_Boolean bUseOBB = BOPTest_Objects::UseOBB();
   //
   Sprintf(buf, " RunParallel: %d\n",  bRunParallel);
   di << buf;
@@ -90,6 +94,8 @@ Standard_Integer boptions(Draw_Interpretor& di,
   di << buf;
   Sprintf(buf, " Check for inverted solids: %s\n", bCheckInverted ? "Yes" : "No");
   di << buf;
+  Sprintf(buf, " Use OBB:%s\n", bUseOBB ? "Yes" : "No");
+  di << buf;
   //
   return 0;
 }
@@ -233,3 +239,21 @@ Standard_Integer bcheckinverted(Draw_Interpretor& di,
   BOPTest_Objects::SetCheckInverted(iCheck != 0);
   return 0;
 }
+
+//=======================================================================
+//function : buseobb
+//purpose  : 
+//=======================================================================
+Standard_Integer buseobb(Draw_Interpretor& di,
+                         Standard_Integer n,
+                         const char** a)
+{
+  if (n != 2) {
+    di.PrintHelp(a[0]);
+    return 1;
+  }
+  //
+  Standard_Integer iUse = Draw::Atoi(a[1]);
+  BOPTest_Objects::SetUseOBB(iUse != 0);
+  return 0;
+}
index 9cc1cea800da7e6f4bf7a8e2c494f9c90feb4aff..148f3d1266088624fdcdbd1c276432c567a1a441 100644 (file)
@@ -115,6 +115,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   aPF.SetNonDestructive(bNonDestructive);
   aPF.SetFuzzyValue(aTol);
   aPF.SetGlue(aGlue);
+  aPF.SetUseOBB(BOPTest_Objects::UseOBB());
   //
   OSD_Timer aTimer;
   aTimer.Start();
index 1850e0e7dc7e8cd52a22c781d12ccb99c15d0f5f..ef65c4939bce5cb97632433cd8c21d0ddee5788b 100644 (file)
@@ -56,6 +56,7 @@ public:
   using BOPAlgo_Options::GetReport;
   using BOPAlgo_Options::SetProgressIndicator;
   using BOPAlgo_Options::SetCheckInverted;
+  using BOPAlgo_Options::SetUseOBB;
 
 protected:
 
index dbddf3dd9363bd94e8c3341d1551fe12c540180c..e3b9205824b1c811d2c17cc00bca4b814a038b0f 100644 (file)
@@ -311,6 +311,7 @@ void BRepAlgoAPI_BooleanOperation::Build()
     myDSFiller->SetFuzzyValue(myFuzzyValue);
     myDSFiller->SetNonDestructive(myNonDestructive);
     myDSFiller->SetGlue(myGlue);
+    myDSFiller->SetUseOBB(myUseOBB);
     //
     SetAttributes();
     //
index f0c565f770c07e1e6a8ca3c08476c0fcf3918636..e746b5bac1352de5aa02856056cd2c4586f64e7f 100644 (file)
@@ -143,6 +143,7 @@ void BRepAlgoAPI_BuilderAlgo::Build()
     myDSFiller->SetFuzzyValue(myFuzzyValue);
     myDSFiller->SetNonDestructive(myNonDestructive);
     myDSFiller->SetGlue(myGlue);
+    myDSFiller->SetUseOBB(myUseOBB);
     //
     myDSFiller->Perform();
     //
index b28fb2f37331cd95b090c2841bc4a80d78a8ba09..97b75ff7d8c8ebf66e3689d5ef1c0d39c8d0b8b0 100644 (file)
@@ -98,6 +98,7 @@ void BRepAlgoAPI_Splitter::Build()
     myDSFiller->SetFuzzyValue(myFuzzyValue);
     myDSFiller->SetNonDestructive(myNonDestructive);
     myDSFiller->SetGlue(myGlue);
+    myDSFiller->SetUseOBB(myUseOBB);
     //
     myDSFiller->Perform();
     //
index e5290ffb49a3892fcd7fc122ece819260c6744ed..6649e5f24ba53a97ec62d49a8d4f5364ec10afc4 100644 (file)
@@ -55,6 +55,8 @@ IntTools_MapOfSurfaceSample.hxx
 IntTools_MarkedRangeSet.cxx
 IntTools_MarkedRangeSet.hxx
 IntTools_MarkedRangeSet.lxx
+IntTools_OBB.cxx
+IntTools_OBB.hxx
 IntTools_PntOn2Faces.cxx
 IntTools_PntOn2Faces.hxx
 IntTools_PntOnFace.cxx
index 903a0e38f99c5cb8ccd28e7cdeee5b03c7c5e148..a9700fc721ed75121a5c6a8347f0bba3d6699961 100644 (file)
@@ -35,6 +35,7 @@
 #include <IntTools_FClass2d.hxx>
 #include <IntTools_SurfaceRangeLocalizeData.hxx>
 #include <IntTools_Tools.hxx>
+#include <IntTools_OBB.hxx>
 #include <Precision.hxx>
 #include <Standard_Type.hxx>
 #include <TopAbs_State.hxx>
@@ -65,6 +66,7 @@ IntTools_Context::IntTools_Context()
   myProjSDataMap(100, myAllocator),
   myBndBoxDataMap(100, myAllocator),
   mySurfAdaptorMap(100, myAllocator),
+  myOBBMap(100, myAllocator),
   myCreateFlag(0),
   myPOnSTolerance(1.e-12)
 {
@@ -86,6 +88,7 @@ IntTools_Context::IntTools_Context
   myProjSDataMap(100, myAllocator),
   myBndBoxDataMap(100, myAllocator),
   mySurfAdaptorMap(100, myAllocator),
+  myOBBMap(100, myAllocator),
   myCreateFlag(1),
   myPOnSTolerance(1.e-12)
 {
@@ -183,6 +186,16 @@ IntTools_Context::~IntTools_Context()
     myAllocator->Free(anAdr);
   }
   mySurfAdaptorMap.Clear();
+  //
+  IntTools_OBB* pOBB;
+  aIt.Initialize(myOBBMap);
+  for (; aIt.More(); aIt.Next()) {
+    anAdr=aIt.Value();
+    pOBB=(IntTools_OBB*)anAdr;
+    (*pOBB).~IntTools_OBB();
+    myAllocator->Free(anAdr);
+  }
+  myOBBMap.Clear();
 }
 //=======================================================================
 //function : BndBox
@@ -472,6 +485,35 @@ Geom2dHatch_Hatcher& IntTools_Context::Hatcher(const TopoDS_Face& aF)
   return *pHatcher;
 }
 
+//=======================================================================
+//function : OBB
+//purpose  : 
+//=======================================================================
+IntTools_OBB& IntTools_Context::OBB(const TopoDS_Shape& aS,
+                                    const Standard_Real theFuzzy)
+{
+  Standard_Address anAdr;
+  IntTools_OBB* pBox;
+  //
+  if (!myOBBMap.IsBound(aS))
+  {
+    pBox = (IntTools_OBB*)myAllocator->Allocate(sizeof(IntTools_OBB));
+    new (pBox) IntTools_OBB();
+    //
+    IntTools_OBB &aBox = *pBox;
+    IntTools_Tools::BuildOBB(aS, theFuzzy, aBox);
+    //
+    anAdr = (Standard_Address)pBox;
+    myOBBMap.Bind(aS, anAdr);
+  }
+  else
+  {
+    anAdr = myOBBMap.Find(aS);
+    pBox = (IntTools_OBB*)anAdr;
+  }
+  return *pBox;
+}
+
 //=======================================================================
 //function : SurfaceData
 //purpose  : 
index 0da262e92e82607696fc06c85ee4c47ee9366a67..923b784276205c1c4a933db8c3c6a40b977d422f 100644 (file)
@@ -44,7 +44,7 @@ class gp_Pnt2d;
 class IntTools_Curve;
 class Bnd_Box;
 class TopoDS_Shape;
-
+class IntTools_OBB;
 
 //! The intersection Context contains geometrical
 //! and topological toolkit (classifiers, projectors, etc).
@@ -98,6 +98,10 @@ Standard_EXPORT virtual  ~IntTools_Context();
   //! Returns a reference to surface adaptor for given face
   Standard_EXPORT BRepAdaptor_Surface& SurfaceAdaptor (const TopoDS_Face& theFace);
 
+  //! Returns a reference to surface adaptor for given face
+  Standard_EXPORT IntTools_OBB& OBB(const TopoDS_Shape& theShape,
+                                    const Standard_Real theFuzzy = Precision::Confusion());
+
   //! Computes the boundaries of the face using surface adaptor
   Standard_EXPORT void UVBounds (const TopoDS_Face& theFace,
                                  Standard_Real& UMin,
@@ -250,6 +254,7 @@ protected:
   BOPCol_DataMapOfShapeAddress myProjSDataMap;
   BOPCol_DataMapOfShapeAddress myBndBoxDataMap;
   BOPCol_DataMapOfShapeAddress mySurfAdaptorMap;
+  BOPCol_DataMapOfShapeAddress myOBBMap; //! Map of oriented bounding boxes
   Standard_Integer myCreateFlag;
   Standard_Real myPOnSTolerance;
 
diff --git a/src/IntTools/IntTools_OBB.cxx b/src/IntTools/IntTools_OBB.cxx
new file mode 100644 (file)
index 0000000..bd108bd
--- /dev/null
@@ -0,0 +1,125 @@
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <IntTools_OBB.hxx>
+
+#include <Bnd_B3d.hxx>
+
+// =======================================================================
+// function : IsOut
+// purpose  : 
+// =======================================================================
+Standard_Boolean IntTools_OBB::IsOut(const IntTools_OBB& theOther) const
+{
+  if (IsVoid() || theOther.IsVoid())
+    return Standard_False;
+
+  if (myIsAABox && theOther.myIsAABox)
+  {
+    // Both boxes are axis aligned - PMax points should be defined in this case.
+    // Use Bnd_B3d::IsOut method to check if the boxes are interfering
+    Bnd_B3d myB3d(myCenter, gp_Vec(myPMin, myCenter).XYZ());
+    Bnd_B3d otherB3d(theOther.myCenter, gp_Vec(theOther.myPMin, theOther.myCenter).XYZ());
+    return myB3d.IsOut(otherB3d);
+  }
+
+  // According to the Separating Axis Theorem for Oriented Bounding Boxes
+  // it is necessary to check the 15 separating axes:
+  // - 6 axes of the boxes;
+  // - 9 cross products of the axes of the boxes.
+  // If any of these axes is valid, the boxes do not interfere.
+
+  // The algorithm is following:
+  // 1. For the analyzed axis L:
+  // 2. Half of boxes vertices are projected onto the axis.
+  // 3. The projection segments for each box are computed.
+  //    The length of the segment will be:
+  //    Abs((HDimX*DirX).Dot(L)) + Abs((HDimY*DirY).Dot(L)) + Abs((HDimZ*DirZ).Dot(L))
+  // 3. It is necessary to check if the distance between centers of the boxes
+  //    projected onto the axis is more than the sum of the lengths
+  //    of the projection segments:
+  //    isOut = (theCenter2 - theCenter1).Dot(L) > (Length1 + Length2);
+
+
+  // Precomputed difference between centers
+  gp_XYZ D = theOther.myCenter - myCenter;
+
+  // Check the axes of the this box, i.e. L is one of myAxes
+  // Since the Dot product of two of these directions is null, it could be skipped:
+  // myXDirection.Dot(myYDirection) = 0
+
+  for (Standard_Integer i = 0; i < 3; ++i)
+  {
+    // Length of the first segment
+    Standard_Real aLSegm1 = myHDims[i];
+
+    // Length of the second segment
+    Standard_Real aLSegm2 = 0;
+    for (Standard_Integer j = 0; j < 3; ++j)
+      aLSegm2 += Abs(theOther.myAxesMultiplied[j].Dot(myAxes[i]));
+
+    // Distance between projected centers
+    Standard_Real aDistCC = Abs(D.Dot(myAxes[i]));
+
+    if (aDistCC > aLSegm1 + aLSegm2)
+      return Standard_True;
+  }
+
+  // Check the axes of the Other box, i.e. L is one of theOther.myAxes
+
+  for (Standard_Integer i = 0; i < 3; ++i)
+  {
+    // Length of the first segment
+    Standard_Real aLSegm1 = 0.;
+    for (Standard_Integer j = 0; j < 3; ++j)
+      aLSegm1 += Abs(myAxesMultiplied[j].Dot(theOther.myAxes[i]));
+
+    // Length of the second segment
+    Standard_Real aLSegm2 = theOther.myHDims[i];
+
+    // Distance between projected centers
+    Standard_Real aDistCC = Abs(D.Dot(theOther.myAxes[i]));
+
+    if (aDistCC > aLSegm1 + aLSegm2)
+      return Standard_True;
+  }
+
+  // Check the axes produced by the cross products
+  for (Standard_Integer i = 0; i < 3; ++i)
+  {
+    for (Standard_Integer j = 0; j < 3; ++j)
+    {
+      // Separating axis
+      gp_XYZ L = myAxes[i].Crossed(theOther.myAxes[j]);
+
+      // Length of the first segment
+      Standard_Real aLSegm1 = 0.;
+      for (Standard_Integer k = 0; k < 3; ++k)
+        aLSegm1 += Abs(myAxesMultiplied[k].Dot(L));
+
+      // Length of the second segment
+      Standard_Real aLSegm2 = 0.;
+      for (Standard_Integer k = 0; k < 3; ++k)
+        aLSegm2 += Abs(theOther.myAxesMultiplied[k].Dot(L));
+
+      // Distance between projected centers
+      Standard_Real aDistCC = Abs(D.Dot(L));
+
+      if (aDistCC > aLSegm1 + aLSegm2)
+        return Standard_True;
+    }
+  }
+
+  return Standard_False;
+}
diff --git a/src/IntTools/IntTools_OBB.hxx b/src/IntTools/IntTools_OBB.hxx
new file mode 100644 (file)
index 0000000..5eb28c2
--- /dev/null
@@ -0,0 +1,199 @@
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IntTools_OBB_HeaderFile
+#define _IntTools_OBB_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Real.hxx>
+#include <Standard_Boolean.hxx>
+
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_XYZ.hxx>
+
+//! The class describes the Oriented Bounding Box (OBB).
+//! It is defined by a center of the box, the axes and the halves
+//! of its three dimensions.
+//! The OBB are used as a second step, after intersection of the
+//! axes aligned boxes, for filtering the time-consuming interfering pairs
+//! in Boolean Operations.
+class IntTools_OBB
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Empty constructor
+  IntTools_OBB()
+  :
+  myIsAABox(Standard_False)
+  {
+     myHDims[0] = 0.;
+     myHDims[1] = 0.;
+     myHDims[2] = 0.;
+  }
+
+  //! Constructor taking all defining parameters
+  IntTools_OBB(const gp_Pnt& theCenter,
+               const gp_Dir& theXDirection,
+               const gp_Dir& theYDirection,
+               const gp_Dir& theZDirection,
+               const Standard_Real theHXSize,
+               const Standard_Real theHYSize,
+               const Standard_Real theHZSize)
+  :
+  myCenter (theCenter.XYZ()),
+  myIsAABox(Standard_False)
+  {
+    myAxes[0] = theXDirection.XYZ();
+    myAxes[1] = theYDirection.XYZ();
+    myAxes[2] = theZDirection.XYZ();
+
+    myHDims[0] = theHXSize;
+    myHDims[1] = theHYSize;
+    myHDims[2] = theHZSize;
+
+    myAxesMultiplied[0] = myAxes[0].Multiplied(myHDims[0]);
+    myAxesMultiplied[1] = myAxes[1].Multiplied(myHDims[1]);
+    myAxesMultiplied[2] = myAxes[2].Multiplied(myHDims[2]);
+  }
+
+  //! Sets the center of OBB
+  void SetCenter(const gp_Pnt& theCenter)
+  {
+    myCenter = theCenter.XYZ();
+  }
+
+  //! Returns the center of OBB
+  const gp_XYZ& Center() const
+  {
+    return myCenter;
+  }
+
+  //! Sets the X component of OBB - direction and size
+  void SetXComponent(const gp_Dir& theXDirection,
+                     const Standard_Real theHXSize)
+  {
+    myAxes[0] = theXDirection.XYZ();
+    myHDims[0] = theHXSize;
+
+    myAxesMultiplied[0] = myAxes[0].Multiplied(myHDims[0]);
+  }
+
+  //! Returns the X Direction of OBB
+  const gp_XYZ& XDirection() const
+  {
+    return myAxes[0];
+  }
+
+  //! Returns the X Dimension of OBB
+  Standard_Real HXSize() const
+  {
+    return myHDims[0];
+  }
+
+  //! Sets the Y component of OBB - direction and size
+  void SetYComponent(const gp_Dir& theYDirection,
+                     const Standard_Real theHYSize)
+  {
+    myAxes[1] = theYDirection.XYZ();
+    myHDims[1] = theHYSize;
+
+    myAxesMultiplied[1] = myAxes[1].Multiplied(myHDims[1]);
+  }
+
+  //! Returns the Y Direction of OBB
+  const gp_XYZ& YDirection() const
+  {
+    return myAxes[1];
+  }
+
+  //! Returns the Y Dimension of OBB
+  Standard_Real HYSize() const
+  {
+    return myHDims[1];
+  }
+
+  //! Sets the Z component of OBB - direction and size
+  void SetZComponent(const gp_Dir& theZDirection,
+                     const Standard_Real theHZSize)
+  {
+    myAxes[2] = theZDirection.XYZ();
+    myHDims[2] = theHZSize;
+
+    myAxesMultiplied[2] = myAxes[2].Multiplied(myHDims[2]);
+  }
+
+  //! Returns the Z Direction of OBB
+  const gp_XYZ& ZDirection() const
+  {
+    return myAxes[2];
+  }
+
+  //! Returns the Z Dimension of OBB
+  Standard_Real HZSize() const
+  {
+    return myHDims[2];
+  }
+
+  //! Checks if the box is empty.
+  Standard_Boolean IsVoid() const
+  {
+    return (((myHDims[0] + myHDims[1] + myHDims[2]) < gp::Resolution()) && !myIsAABox);
+  }
+
+  //! Sets the flag for axes aligned box
+  void SetAABox(const Standard_Boolean& theFlag)
+  {
+    myIsAABox = theFlag;
+  }
+
+  //! Returns TRUE if the box is axes aligned
+  Standard_Boolean IsAABox() const
+  {
+    return myIsAABox;
+  }
+
+  //! Sets the min point
+  void SetMinPoint(const gp_Pnt& theMin)
+  {
+    myPMin = theMin.XYZ();
+  }
+
+  //! Returns the min point of the box
+  const gp_XYZ& MinPoint() const
+  {
+    return myPMin;
+  }
+
+  //! Check if the box do not interfere the other box.
+  Standard_EXPORT Standard_Boolean IsOut(const IntTools_OBB& theOther) const;
+
+private:
+
+  // OBB definition
+  gp_XYZ myCenter;            //! Center of the OBB
+  gp_XYZ myAxes[3];           //! The axes of the box
+  Standard_Real myHDims[3];   //! Half-size dimensions of the OBB
+
+  gp_XYZ myAxesMultiplied[3]; //! Multiplied axes to avoid their recalculation in IsOut method
+
+  Standard_Boolean myIsAABox; //! To be set if the OBB is axis aligned box;
+  gp_XYZ myPMin;              //! Min point of the box.
+};
+
+#endif
index 46c891d3957fc543988ec04def0b1cb6672ee887..9aa753db376fb4fe139da0b7ba8273461493b85f 100644 (file)
 #include <TopoDS_Wire.hxx>
 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
 
+#include <gp_Ax3.hxx>
+#include <BRepGProp.hxx>
+#include <BRepBndLib.hxx>
+#include <GProp_GProps.hxx>
+#include <GProp_PrincipalProps.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <IntTools_OBB.hxx>
+
+#ifdef DEBUG_OBB
+#include <BRepPrimAPI_MakeBox.hxx>
+#endif
+
 static
   void ParabolaTolerance(const Handle(Geom_Curve)& ,
     const Standard_Real ,
@@ -840,3 +852,113 @@ Standard_Real IntTools_Tools::ComputeIntRange(const Standard_Real theTol1,
   //
   return aDt;
 }
+
+//=======================================================================
+// Function : BuildOBB
+// purpose : 
+//=======================================================================
+void IntTools_Tools::BuildOBB(const TopoDS_Shape& theS,
+                              const Standard_Real theFuzzy,
+                              IntTools_OBB& theOBB)
+{
+  // Compute the transformation matrix to obtain more tight bounding box
+  GProp_GProps G;
+  switch (theS.ShapeType())
+  {
+    case TopAbs_VERTEX:
+    {
+      // Just make the AA box
+      const gp_Pnt& aP = BRep_Tool::Pnt(TopoDS::Vertex(theS));
+      Bnd_Box aBox;
+      aBox.Add(aP);
+      aBox.SetGap(BRep_Tool::Tolerance(TopoDS::Vertex(theS)) + theFuzzy);
+
+      theOBB.SetCenter(aP);
+      theOBB.SetXComponent(gp_Dir(1, 0, 0), aBox.GetGap());
+      theOBB.SetYComponent(gp_Dir(0, 1, 0), aBox.GetGap());
+      theOBB.SetZComponent(gp_Dir(0, 0, 1), aBox.GetGap());
+
+      theOBB.SetAABox(Standard_True);
+      theOBB.SetMinPoint(aBox.CornerMin());
+      return;
+    }
+    case TopAbs_EDGE:
+      BRepGProp::LinearProperties(theS, G, Standard_True);
+      break;
+    case TopAbs_FACE:
+      BRepGProp::SurfaceProperties(theS, G, Standard_True);
+      break;
+    case TopAbs_SOLID:
+      BRepGProp::VolumeProperties(theS, G, Standard_True);
+      break;
+    default:
+      break;
+  }
+
+  // Coordinate system in which the shape will have the optimal bounding box
+  gp_Ax3 aLocCoordSys(G.CentreOfMass(),
+                      G.PrincipalProperties().ThirdAxisOfInertia(),
+                      G.PrincipalProperties().FirstAxisOfInertia());
+
+  // Transform the shape to the local coordinate system
+  gp_Trsf aTrsf;
+  aTrsf.SetTransformation(aLocCoordSys);
+
+  BRepBuilderAPI_Transform aTransformer(theS, aTrsf);
+  if (aTransformer.IsDone())
+  {
+    const TopoDS_Shape& aST = aTransformer.Shape();
+
+    // Build the bounding box for oriented shape
+    Bnd_Box anOBB;
+    BRepBndLib::Add(aST, anOBB);
+    anOBB.SetGap(theFuzzy);
+
+    // Create the OBB box
+    gp_Pnt aPMin = anOBB.CornerMin();
+    gp_Pnt aPMax = anOBB.CornerMax();
+
+    // Compute the center of the box
+    gp_XYZ aCenter = (aPMin.XYZ() + aPMax.XYZ()) / 2.;
+    aTrsf.Inverted().Transforms(aCenter);
+
+    // Compute the half diagonal size of the box
+    gp_XYZ anOBBHSize  = (aPMax.XYZ() - aPMin.XYZ()) / 2.;
+    // Make transformation
+    const Standard_Real * aMat = &aTrsf.Inverted().HVectorialPart().Value(1, 1);
+    // Compute axes directions of the box
+    gp_XYZ aXDir(aMat[0], aMat[3], aMat[6]);
+    gp_XYZ aYDir(aMat[1], aMat[4], aMat[7]);
+    gp_XYZ aZDir(aMat[2], aMat[5], aMat[8]);
+
+    theOBB.SetCenter(aCenter);
+    theOBB.SetXComponent(aXDir, anOBBHSize.X());
+    theOBB.SetYComponent(aYDir, anOBBHSize.Y());
+    theOBB.SetZComponent(aZDir, anOBBHSize.Z());
+
+    gp_XYZ aPMinXYZ = aPMin.XYZ();
+    aTrsf.Inverted().Transforms(aPMinXYZ);
+    theOBB.SetMinPoint(aPMinXYZ);
+#ifdef DEBUG_OBB
+    // Get the obtained box
+    GetOBBShapeBox(theOBB);
+#endif
+  }
+}
+
+
+#ifdef DEBUG_OBB
+//=======================================================================
+// Function : GetOBBShapeBox
+// purpose : 
+//=======================================================================
+TopoDS_Shape IntTools_Tools::GetOBBShapeBox(const IntTools_OBB& theOBB)
+{
+  gp_Ax2 axis(theOBB.MinPoint(), theOBB.ZDirection());
+  axis.SetXDirection(theOBB.XDirection());
+  BRepPrimAPI_MakeBox aSMaker(axis, 2 * theOBB.HXSize(), 2 * theOBB.HYSize(), 2 * theOBB.HZSize());
+  const TopoDS_Shape& aSolid = aSMaker.Solid();
+
+  return aSolid;
+}
+#endif
index 5e828548a01e130364a7d80f065fdc5e5108bac1..dbd4557cc1b6112c86bd46bd6612f6a076613620 100644 (file)
@@ -42,7 +42,7 @@ class gp_Lin;
 class gp_Pln;
 class Geom2d_Curve;
 class Geom_Surface;
-
+class IntTools_OBB;
 
 
 //! The class contains handy static functions
@@ -183,6 +183,16 @@ public:
                                                        const Standard_Real theAngle);
 
 
+  //! Computes the Oriented Bounding box for the shape
+  Standard_EXPORT static void BuildOBB(const TopoDS_Shape& theS,
+                                       const Standard_Real theFuzzy,
+                                       IntTools_OBB& theOBB);
+
+#ifdef DEBUG_OBB
+  //! Get the solid built from the OBB box
+  Standard_EXPORT static TopoDS_Shape GetOBBShapeBox(const IntTools_OBB& theOBB);
+#endif
+
 protected: