0024597: Missing internal vertex in the result of General Fuse Operation
[occt.git] / src / BOPDS / BOPDS_DS.cxx
index 61d46f0..0023f46 100644 (file)
@@ -1,21 +1,16 @@
 // Created by: Peter KURNEV
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public 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.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <BOPDS_DS.ixx>
 //
@@ -90,7 +85,11 @@ BOPDS_DS::BOPDS_DS()
   myInterfVF(myAllocator),
   myInterfEE(myAllocator),
   myInterfEF(myAllocator),
-  myInterfFF(myAllocator)
+  myInterfFF(myAllocator),
+  myInterfVZ(myAllocator),
+  myInterfEZ(myAllocator),
+  myInterfFZ(myAllocator),
+  myInterfZZ(myAllocator)
 {
   myNbShapes=0;
   myNbSourceShapes=0;
@@ -116,7 +115,11 @@ BOPDS_DS::BOPDS_DS(const Handle(NCollection_BaseAllocator)& theAllocator)
   myInterfVF(myAllocator),
   myInterfEE(myAllocator),
   myInterfEF(myAllocator),
-  myInterfFF(myAllocator)
+  myInterfFF(myAllocator),
+  myInterfVZ(myAllocator),
+  myInterfEZ(myAllocator),
+  myInterfFZ(myAllocator),
+  myInterfZZ(myAllocator)
 {
   myNbShapes=0;
   myNbSourceShapes=0;
@@ -153,6 +156,10 @@ void BOPDS_DS::Clear()
   myInterfEE.Clear();
   myInterfEF.Clear();
   myInterfFF.Clear();
+  myInterfVZ.Clear();
+  myInterfEZ.Clear();
+  myInterfFZ.Clear();
+  myInterfZZ.Clear();
 }
 //=======================================================================
 //function : SetArguments
@@ -312,8 +319,10 @@ Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS)const
 void BOPDS_DS::Init()
 {
   Standard_Integer i1, i2, j, aI, aNb, aNbS, aNbE, aNbSx, nV, nW, nE, aNbF;
+  Standard_Integer n1, n2, n3;
   Standard_Real aTol;
   TopAbs_ShapeEnum aTS;
+  TopoDS_Iterator aItS;
   BOPCol_ListIteratorOfListOfInteger aIt1, aIt2, aIt3;
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPDS_IndexRange aR;
@@ -514,6 +523,16 @@ void BOPDS_DS::Init()
         }
       }//for (; aIt1.More(); aIt1.Next()) {
       //
+      // pure internal vertices on the face
+      aItS.Initialize(aS);
+      for (; aItS.More(); aItS.Next()) {
+       const TopoDS_Shape& aSx=aItS.Value();
+       if (aSx.ShapeType()==TopAbs_VERTEX){
+         nV=Index(aSx);
+         aMI.Add(nV);
+       }
+      }
+      //
       //
       // For a Face: change wires for BRep sub-shapes
       aLW.Clear();
@@ -527,6 +546,59 @@ void BOPDS_DS::Init()
     }//if (aTS==TopAbs_FACE) {
   }//for (j=0; j<myNbSourceShapes; ++j) {
   //
+  // 2.4 Solids
+  for (j=0; j<myNbSourceShapes; ++j) {
+    BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
+    //
+    aTS=aSI.ShapeType();
+    if (aTS!=TopAbs_SOLID) {
+      continue;
+    }
+    Bnd_Box& aBox=aSI.ChangeBox();
+    BuildBndBoxSolid(j, aBox); 
+    //
+    //
+    // update sub-shapes by BRep comprising ones
+    aMI.Clear();
+    BOPCol_ListOfInteger& aLI1=aSI.ChangeSubShapes();
+    //
+    aIt1.Initialize(aLI1);
+    for (; aIt1.More(); aIt1.Next()) {
+      n1=aIt1.Value();
+      BOPDS_ShapeInfo& aSI1=ChangeShapeInfo(n1);
+      if (aSI1.ShapeType()!=TopAbs_SHELL) {
+       continue;
+      }
+      //
+      const BOPCol_ListOfInteger& aLI2=aSI1.SubShapes(); 
+      aIt2.Initialize(aLI2);
+      for (; aIt2.More(); aIt2.Next()) {
+       n2=aIt2.Value();
+       BOPDS_ShapeInfo& aSI2=ChangeShapeInfo(n2);
+       if (aSI2.ShapeType()!=TopAbs_FACE) {
+         continue;
+       }
+       //
+       aMI.Add(n2);
+       //
+       const BOPCol_ListOfInteger& aLI3=aSI2.SubShapes(); 
+       aIt3.Initialize(aLI3);
+       for (; aIt3.More(); aIt3.Next()) {
+         n3=aIt3.Value();
+         aMI.Add(n3);
+       }
+      }
+    }
+    //
+    aLI1.Clear();
+    aItMI.Initialize(aMI);
+    for (; aItMI.More(); aItMI.Next()) {
+      n1=aItMI.Value();
+      aLI1.Append(n1);
+    }
+    aMI.Clear();
+  }//for (j=0; j<myNbSourceShapes; ++j) {
+  //
   aMI.Clear();
   aAllocator.Nullify();
   //-----------------------------------------------------scope_1 t
@@ -609,13 +681,14 @@ Standard_Boolean BOPDS_DS::HasInterf(const Standard_Integer theI) const
   //
   return bRet;
 }
-
 //=======================================================================
 //function : HasInterfShapeSubShapes
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPDS_DS::HasInterfShapeSubShapes(const Standard_Integer theI1,
-                                                  const Standard_Integer theI2)const
+Standard_Boolean BOPDS_DS::HasInterfShapeSubShapes
+  (const Standard_Integer theI1,
+   const Standard_Integer theI2,
+   const Standard_Boolean theFlag)const
 {
   Standard_Boolean bRet;
   Standard_Integer n2;
@@ -628,13 +701,19 @@ Standard_Boolean BOPDS_DS::HasInterfShapeSubShapes(const Standard_Integer theI1,
   for (; aIt.More(); aIt.Next()) {
     n2=aIt.Value();
     bRet=HasInterf(theI1, n2);
-    if(bRet) {
-      break;
+    if (theFlag) {
+      if(bRet) {
+       break;
+      }
+    }
+    else {
+      if(!bRet) {
+       break;
+      }
     }
   }
   return bRet;
 }
-
 //=======================================================================
 //function : HasInterfSubShapes
 //purpose  : 
@@ -1204,9 +1283,25 @@ void BOPDS_DS::FaceInfoIn(const Standard_Integer theF,
                          BOPDS_IndexedMapOfPaveBlock& theMPB,
                          BOPCol_MapOfInteger& theMI)
 {
-  Standard_Integer i, aNbVF, aNbEF, nV, nE;
+  Standard_Integer i, aNbVF, aNbEF, nV, nE, nVSD;
+  TopoDS_Iterator aItS;
   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
   //
+  // 1. Pure internal vertices on the face
+  const TopoDS_Shape& aF=Shape(theF);
+  aItS.Initialize(aF);
+  for (; aItS.More(); aItS.Next()) {
+    const TopoDS_Shape& aSx=aItS.Value();
+    if (aSx.ShapeType()==TopAbs_VERTEX){
+      nV=Index(aSx);
+      if (HasShapeSD(nV, nVSD)) {
+       nV=nVSD;
+      }
+      theMI.Add(nV);
+    }
+  }
+  //
+  // 2. aVFs
   BOPDS_VectorOfInterfVF& aVFs=InterfVF();
   aNbVF=aVFs.Extent();
   for (i=0; i<aNbVF; ++i) {
@@ -1217,6 +1312,7 @@ void BOPDS_DS::FaceInfoIn(const Standard_Integer theF,
     }
   }
   //
+  // 3. aEFs
   BOPDS_VectorOfInterfEF& aEFs=InterfEF();
   aNbEF=aEFs.Extent();
   for (i=0; i<aNbEF; ++i) {
@@ -1837,3 +1933,79 @@ void SortShell(const int n, BOPDS_Pave *a)
     }//for (i=0; i<nd; ++i) 
   }//while (1)
 }
+//=======================================================================
+//function : BuildBndBoxSolid
+//purpose  : 
+//=======================================================================
+void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
+                               Bnd_Box& aBoxS)
+{
+  Standard_Boolean bIsOpenBox, bIsInverted;
+  Standard_Integer nSh, nFc;
+  Standard_Real aTolS, aTolFc;
+  BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
+  //
+  const BOPDS_ShapeInfo& aSI=ShapeInfo(theIndex);
+  const TopoDS_Shape& aS=aSI.Shape();
+  const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
+  //
+  bIsOpenBox=Standard_False;
+  //
+  aTolS=0.;
+  const BOPCol_ListOfInteger& aLISh=aSI.SubShapes();
+  aItLI.Initialize(aLISh);
+  for (; aItLI.More(); aItLI.Next()) {
+    nSh=aItLI.Value();
+    const BOPDS_ShapeInfo& aSISh=ShapeInfo(nSh);
+    if (aSISh.ShapeType()!=TopAbs_SHELL) {
+      continue;
+    }
+    //
+    const BOPCol_ListOfInteger& aLIFc=aSISh.SubShapes();
+    aItLI1.Initialize(aLIFc);
+    for (; aItLI1.More(); aItLI1.Next()) {
+      nFc=aItLI1.Value();
+      const BOPDS_ShapeInfo& aSIFc=ShapeInfo(nFc);
+      if (aSIFc.ShapeType()!=TopAbs_FACE) {
+       continue;
+      }
+      //
+      const Bnd_Box& aBFc=aSIFc.Box();
+      aBoxS.Add(aBFc);
+      //
+      if (!bIsOpenBox) {
+       bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() ||
+                   aBFc.IsOpenYmin() || aBFc.IsOpenYmax() ||
+                   aBFc.IsOpenZmin() || aBFc.IsOpenZmax()); 
+       if (bIsOpenBox) {
+         break;
+       }
+      }
+      //
+      const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape());
+      aTolFc=BRep_Tool::Tolerance(aFc);
+      if (aTolFc>aTolS) {
+       aTolS=aTolFc;
+      }
+    }//for (; aItLI1.More(); aItLI1.Next()) {
+    if (bIsOpenBox) {
+      break;
+    }
+    //
+    const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape());
+    bIsOpenBox=BOPTools_AlgoTools::IsOpenShell(aSh);
+    if (bIsOpenBox) {
+      break;
+    }
+  }//for (; aItLI.More(); aItLI.Next()) {
+  //
+  if (bIsOpenBox) {
+    aBoxS.SetWhole();
+  }
+  else {
+    bIsInverted=BOPTools_AlgoTools::IsInvertedSolid(aSolid);
+    if (bIsInverted) {
+      aBoxS.SetWhole(); 
+    }
+  }
+}