0028284: Avoid classification of sub-shapes of arguments of BOPs relatively solids...
[occt.git] / src / BOPDS / BOPDS_Iterator.cxx
index 4ad8589..d3e8058 100644 (file)
 #include <BOPDS_DS.hxx>
 #include <BOPDS_IndexRange.hxx>
 #include <BOPDS_Iterator.hxx>
-#include <BOPDS_MapOfPassKeyBoolean.hxx>
-#include <BOPDS_PassKeyBoolean.hxx>
+#include <BOPDS_Pair.hxx>
+#include <BOPDS_MapOfPair.hxx>
 #include <BOPDS_Tools.hxx>
 #include <NCollection_UBTreeFiller.hxx>
 #include <TopoDS_Shape.hxx>
+#include <algorithm>
 
-//
-//
-//
-//
-//
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
 //class    : BOPDS_TreeSelector
@@ -195,8 +191,11 @@ void BOPDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
   myLength=0;
   iX=BOPDS_Tools::TypeToInteger(aType1, aType2);
   if (iX>=0) {
-    myIterator.Initialize(myLists(iX));
-    myLength=myLists(iX).Extent();
+    // sort interfering pairs for constant order of intersection
+    std::stable_sort(myLists(iX).begin(), myLists(iX).end());
+    // initialize iterator to access the pairs
+    myIterator.Init(myLists(iX));
+    myLength = myLists(iX).Extent();
   }
 }
 //=======================================================================
@@ -219,15 +218,13 @@ void BOPDS_Iterator::Next()
 // function: Value
 // purpose: 
 //=======================================================================
-void BOPDS_Iterator::Value
-  (Standard_Integer& theI1,
-   Standard_Integer& theI2,
-   Standard_Boolean& theWithSubShape) const
+void BOPDS_Iterator::Value(Standard_Integer& theI1,
+                           Standard_Integer& theI2) const
 {
   Standard_Integer iT1, iT2, n1, n2;
   //
-  const BOPDS_PassKeyBoolean& aPKB=myIterator.Value();
-  aPKB.Ids(n1, n2);
+  const BOPDS_Pair& aPair = myIterator.Value();
+  aPair.Indices(n1, n2);
   //
   iT1=(Standard_Integer)(myDS->ShapeInfo(n1).ShapeType());
   iT2=(Standard_Integer)(myDS->ShapeInfo(n2).ShapeType());
@@ -238,8 +235,6 @@ void BOPDS_Iterator::Value
     theI1=n2;
     theI2=n1;
   }
-  //
-  theWithSubShape=aPKB.Flag();
 }
 //=======================================================================
 // function: Prepare
@@ -267,33 +262,24 @@ void BOPDS_Iterator::Prepare()
 //=======================================================================
 void BOPDS_Iterator::Intersect()
 {
-  Standard_Boolean bFlag;
-  Standard_Integer aNb, i, aNbR, iTi, iTj;
-  Standard_Integer i1, i2, aNbSD, iX, j, iR;
+  Standard_Integer i, j, iX, i1, i2, iR, aNb, aNbR;
+  Standard_Integer iTi, iTj;
   TopAbs_ShapeEnum aTi, aTj;
-  Handle(NCollection_BaseAllocator) aAllocator;
-  BOPCol_ListIteratorOfListOfInteger aIt;
-  //
-  //-----------------------------------------------------scope_1 f
-  aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
-  //
-  BOPDS_MapOfPassKeyBoolean aMPKXB(100, aAllocator);
-  BOPDS_PassKeyBoolean aPKXB; 
   //
   BOPCol_BoxBndTree aBBTree;
   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
   //
-  aNb=myDS->NbSourceShapes();
-  BOPDS_VectorOfTSR aVTSR(aNb, aAllocator);
+  aNb = myDS->NbSourceShapes();
+  BOPDS_VectorOfTSR aVTSR(aNb);
   //
   for (i=0; i<aNb; ++i) {
     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
-    bFlag=aSI.IsInterfering();
+    Standard_Boolean bHasBrep = aSI.IsInterfering() && !(aSI.ShapeType() == TopAbs_SOLID);
     //
     BOPDS_TSR& aTSR=aVTSR.Append1();
     //
-    aTSR.SetHasBRep(bFlag);
-    if (!bFlag) {
+    aTSR.SetHasBRep(bHasBrep);
+    if (!bHasBrep) {
       continue;
     }
     //
@@ -310,68 +296,57 @@ void BOPDS_Iterator::Intersect()
   BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
   //===========================================
   //
-  aNbR=myDS->NbRanges()-1;
-  for (iR=0; iR<aNbR; ++iR) {
-    const BOPDS_IndexRange& aR=myDS->Range(iR);
-    i1=aR.First();
-    i2=aR.Last();
-    for (i=i1; i<=i2; ++i) {
-      const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
+  BOPDS_MapOfPair aMPFence;
+  //
+  aNbR = myDS->NbRanges() - 1;
+  for (iR = 0; iR < aNbR; ++iR) {
+    const BOPDS_IndexRange& aR = myDS->Range(iR);
+    i1 = aR.First();
+    i2 = aR.Last();
+    for (i = i1; i <= i2; ++i) {
+      const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
       //
-      if (!aSI.IsInterfering()){
+      if (!aSI.IsInterfering() || (aSI.ShapeType() == TopAbs_SOLID)) {
         continue;
       }
       //
-      aTi=aSI.ShapeType();
-      const Bnd_Box& aBoxi=aSI.Box();
-      //
-      BOPDS_TSR& aTSRi=aVTSR(i);
-      const BOPCol_ListOfInteger& aLI=aTSRi.Indices();
-      aNbSD=aLI.Extent();
-      if (!aNbSD){
+      BOPDS_TSR& aTSRi = aVTSR(i);
+      const BOPCol_ListOfInteger& aLI = aTSRi.Indices();
+      Standard_Integer aNbSD = aLI.Extent();
+      if (!aNbSD) {
         continue;
       }
       //
-      aIt.Initialize(aLI);
+      aTi = aSI.ShapeType();
+      iTi = BOPDS_Tools::TypeToInteger(aTi);
+      //
+      BOPCol_ListIteratorOfListOfInteger aIt(aLI);
       for (; aIt.More(); aIt.Next()) {
-        j=aIt.Value(); // DS index
-        if (j>=i1 && j<=i2) {
+        j = aIt.Value(); // DS index
+        if (j >= i1 && j <= i2) {
           continue;// same range
         }
         //
-        const BOPDS_ShapeInfo& aSIj=myDS->ShapeInfo(j);
-        aTj=aSIj.ShapeType();
-        iTi=BOPDS_Tools::TypeToInteger(aTi);
-        iTj=BOPDS_Tools::TypeToInteger(aTj);
+        const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j);
+        aTj = aSJ.ShapeType();
+        iTj = BOPDS_Tools::TypeToInteger(aTj);
         //
-        bFlag=Standard_False;
-        if (iTi<iTj) {
-          bFlag=aSI.HasSubShape(j);
-        } 
-        else if (iTj<iTi) {
-          bFlag=aSIj.HasSubShape(i);
-        }
-        if (bFlag) {
-          continue; 
+        // avoid interfering of the same shapes and shape with its sub-shapes
+        if (((iTi < iTj) && aSI.HasSubShape(j)) ||
+            ((iTi > iTj) && aSJ.HasSubShape(i))) {
+          continue;
         }
         //
-        aPKXB.SetIds(i, j);
-        if (aMPKXB.Add(aPKXB)) {
-          bFlag=Standard_False;// Bounding boxes are intersected
-          const Bnd_Box& aBoxj=aSIj.Box();
-          if (aBoxi.IsOut(aBoxj)) {
-            bFlag=!bFlag; //Bounding boxes of Sub-shapes are intersected
-          }
-          //
-          iX=BOPDS_Tools::TypeToInteger(aTi, aTj);
-          aPKXB.SetFlag(bFlag);
-          myLists(iX).Append(aPKXB);
-        }// if (aMPKXB.Add(aPKXB)) {
+        BOPDS_Pair aPair(i, j);
+        if (aMPFence.Add(aPair)) {
+          iX = BOPDS_Tools::TypeToInteger(aTi, aTj);
+          myLists(iX).Append(aPair);
+        }// if (aMPFence.Add(aPair)) {
       }// for (; aIt.More(); aIt.Next()) {
     }//for (i=i1; i<=i2; ++i) {
   }//for (iR=1; iR<aNbR; ++iR) {
   //
-  aMPKXB.Clear();
+  aMPFence.Clear();
   aVTSR.Clear();
   //-----------------------------------------------------scope_1 t
 }