Salome HOME
[bos #37951][EDF 25230] SIGSEGV with MakeVertexInsideFace. Added check for an uniniti...
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShellSolid.cxx
index a92f8a776d054945cb8a4bed1519fa3b9a124770..863621166325301f6c8411f5dadf0ba633bc32c4 100644 (file)
@@ -1,29 +1,31 @@
-// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-// 
+//
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
-// version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// File:       GEOMAlgo_ShellSolid.cxx
-// Created:    Wed Jan 12 12:49:45 2005
-// Author:     Peter KURNEV
-//             <pkv@irinox>
-
 
-#include <GEOMAlgo_ShellSolid.ixx>
+// File:        GEOMAlgo_ShellSolid.cxx
+// Created:     Wed Jan 12 12:49:45 2005
+// Author:      Peter KURNEV
+//              <pkv@irinox>
+//
+#include <GEOMAlgo_ShellSolid.hxx>
 
 #include <Standard_Failure.hxx>
 
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopExp_Explorer.hxx>
 
-#include <BRepClass3d_SolidClassifier.hxx>
+#include <BOPTools_AlgoTools.hxx>
 
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <IntTools_Context.hxx>
-#include <BOPTColStd_Dump.hxx>
-#include <BooleanOperations_ShapesDataStructure.hxx>
+#include <BOPDS_DS.hxx>
+#include <BOPAlgo_Builder.hxx>
 
-#include <BOPTools_PaveFiller.hxx>
-#include <BOPTools_SolidStateFiller.hxx>
-#include <BOPTools_PCurveMaker.hxx>
-#include <BOPTools_DEProcessor.hxx>
-#include <BOPTools_InterferencePool.hxx>
-#include <BOPTools_CArray1OfSSInterference.hxx>
-#include <BOPTools_ListOfPaveBlock.hxx>
-#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
-#include <BOPTools_PaveBlock.hxx>
-#include <BOPTools_SSInterference.hxx>
-#include <BOPTools_SequenceOfCurves.hxx>
-#include <BOPTools_Curve.hxx>
-#include <BOPTools_PaveFiller.hxx>
-#include <BOPTools_SplitShapesPool.hxx>
-#include <BOPTools_Tools3D.hxx>
-#include <BOPTools_DSFiller.hxx>
+#include <GEOMAlgo_AlgoTools.hxx>
 
-#include <BOP_WireEdgeSet.hxx>
-#include <BOP_SDFWESFiller.hxx>
-#include <BOP_FaceBuilder.hxx>
+#include <Basics_OCCTVersion.hxx>
 
+/////////////////////////////////////////////////////////////////////////
 //=======================================================================
-//function : GEOMAlgo_ShellSolid
+//class : GEOMAlgo_ShellSolidBuilder
 //purpose  : 
 //=======================================================================
+class GEOMAlgo_ShellSolidBuilder : public BOPAlgo_Builder {
+ public:
+  Standard_EXPORT
+    GEOMAlgo_ShellSolidBuilder();
+
+  Standard_EXPORT
+    virtual ~GEOMAlgo_ShellSolidBuilder();
+
+ protected:
+  Standard_EXPORT
+#if OCC_VERSION_LARGE < 0x07070000
+    virtual void PerformInternal(const BOPAlgo_PaveFiller& theFiller);
+#else
+    virtual void PerformInternal(const BOPAlgo_PaveFiller& theFiller,
+                                 const Message_ProgressRange& theRange);
+#endif
+};
+
+//=======================================================================
+//function : GEOMAlgo_ShellSolidBuilder
+//purpose  : 
+//=======================================================================
+GEOMAlgo_ShellSolidBuilder::GEOMAlgo_ShellSolidBuilder()
+:
+  BOPAlgo_Builder()
+{
+}
+//=======================================================================
+//function : ~GEOMAlgo_ShellSolidBuilder
+//purpose  : 
+//=======================================================================
+GEOMAlgo_ShellSolidBuilder::~GEOMAlgo_ShellSolidBuilder()
+{
+}
+//=======================================================================
+//function : PerformInternal
+//purpose  : 
+//=======================================================================
+#if OCC_VERSION_LARGE < 0x07070000
+void GEOMAlgo_ShellSolidBuilder::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
+#else
+void GEOMAlgo_ShellSolidBuilder::PerformInternal(const BOPAlgo_PaveFiller& theFiller,
+                                                 const Message_ProgressRange& theRange)
+#endif
+{
+  myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
+  myDS=myPaveFiller->PDS();
+  myContext=myPaveFiller->Context();
+  //
+  // 1. CheckData
+  CheckData();
+  if (HasErrors()) {
+    return;
+  }
+  //
+  // 2. Prepare
+  Prepare();
+  if (HasErrors()) {
+    return;
+  }
+
+#if OCC_VERSION_LARGE >= 0x07070000
+  Message_ProgressScope aPS(theRange, "Building the result of Boolean operation", 100);
+  //
+  BOPAlgo_PISteps aSteps (PIOperation_Last);
+  analyzeProgress (100, aSteps);
+#endif
+
+  // 3. Fill Images
+  // 3.1 Vertice
+#if OCC_VERSION_LARGE < 0x07070000
+  FillImagesVertices();
+#else
+  FillImagesVertices(aPS.Next(aSteps.GetStep(PIOperation_TreatVertices)));
+#endif
+  if (HasErrors()) {
+    return;
+  }
+  //
+  BuildResult(TopAbs_VERTEX);
+  if (HasErrors()) {
+    return;
+  }
+  // 3.2 Edges
+#if OCC_VERSION_LARGE < 0x07070000
+  FillImagesEdges();
+#else
+  FillImagesEdges(aPS.Next(aSteps.GetStep(PIOperation_TreatEdges)));
+#endif
+  if (HasErrors()) {
+    return;
+  }
+  //
+  BuildResult(TopAbs_EDGE);
+  if (HasErrors()) {
+    return;
+  } 
+  //
+  // 3.3 Wires
+#if OCC_VERSION_LARGE < 0x07070000
+  FillImagesContainers(TopAbs_WIRE);
+#else
+  FillImagesContainers(TopAbs_WIRE, aPS.Next(aSteps.GetStep(PIOperation_TreatWires)));
+#endif
+  if (HasErrors()) {
+    return;
+  }
+  //
+  BuildResult(TopAbs_WIRE);
+  if (HasErrors()) {
+    return;
+  }
+  
+  // 3.4 Faces
+#if OCC_VERSION_LARGE < 0x07070000
+  FillImagesFaces();
+#else
+  FillImagesFaces(aPS.Next(aSteps.GetStep(PIOperation_TreatFaces)));
+#endif
+  if (HasErrors()) {
+    return;
+  }
+  //
+  BuildResult(TopAbs_FACE);
+  if (HasErrors()) {
+    return;
+  }
+}
+/////////////////////////////////////////////////////////////////////////
+//=======================================================================
+//function : GEOMAlgo_ShellSolid
+//purpose  :
+//=======================================================================
 GEOMAlgo_ShellSolid::GEOMAlgo_ShellSolid()
 :
   GEOMAlgo_ShapeSolid()
@@ -82,288 +203,139 @@ GEOMAlgo_ShellSolid::GEOMAlgo_ShellSolid()
 }
 //=======================================================================
 //function : ~
-//purpose  : 
+//purpose  :
 //=======================================================================
 GEOMAlgo_ShellSolid::~GEOMAlgo_ShellSolid()
 {
 }
 //=======================================================================
-// function: 
-// purpose: 
+// function:
+// purpose:
 //=======================================================================
-void GEOMAlgo_ShellSolid::Perform() 
+void GEOMAlgo_ShellSolid::Perform()
 {
-  myErrorStatus=0;
   //
   try {
+    Standard_Integer aNbArgs, iRank, iErr, iBeg, iEnd, i, aNbSp;
+    Standard_Real aTol;
+    TopAbs_ShapeEnum aType;
+    TopAbs_State aState;
+    gp_Pnt aP;
+    gp_Pnt2d aP2D;
+    TopoDS_Face aF;
+    //
+    myLSIN.Clear();
+    myLSOUT.Clear();
+    myLSON.Clear();
+    //
+    aTol=1.e-7;
+    //
     if (myDSFiller==NULL) {
       myErrorStatus=10;
       return;
     }
-    if(!myDSFiller->IsDone()) {
+    if(myDSFiller->HasErrors()) {
       myErrorStatus=11;
       return;
     }
     //
-    Standard_Boolean bIsNewFiller;
+    const BOPDS_DS& aDS=myDSFiller->DS();
+    BOPDS_DS* pDS=(BOPDS_DS*)&aDS;
+    const TopTools_ListOfShape& aLS=pDS->Arguments();
     //
-    bIsNewFiller=myDSFiller->IsNewFiller();
-    if (bIsNewFiller) {
-      Prepare();
-      myDSFiller->SetNewFiller(!bIsNewFiller);
+    aNbArgs=aLS.Extent();
+    if (aNbArgs!=2) {
+      myErrorStatus=13;
+      return;
     }
     //
-    myRank=(myDSFiller->DS().Object().ShapeType()==TopAbs_SHELL) ? 1 : 2;
-    BuildResult();
-  }
-  catch (Standard_Failure) {
-    myErrorStatus=12;
-  }
-}
-//=======================================================================
-// function: Prepare
-// purpose: 
-//=======================================================================
-void GEOMAlgo_ShellSolid::Prepare() 
-{
-  const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
-  // 
-  // 1 States
-  BOPTools_SolidStateFiller aStateFiller(aPaveFiller);
-  aStateFiller.Do();
-  //
-  // 2 Project section edges on corresp. faces -> P-Curves on edges.
-  BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
-  aPCurveMaker.Do();
-  //
-  // 3. Degenerated Edges Processing
-  BOPTools_DEProcessor aDEProcessor(aPaveFiller);
-  aDEProcessor.Do();
-  //
-  // 4. Detect Same Domain Faces
-  DetectSDFaces();
-}
-//=================================================================================
-// function: BuildResult
-// purpose: 
-//=================================================================================
-void GEOMAlgo_ShellSolid::BuildResult() 
-{
-  Standard_Boolean bIsTouchCase;
-  Standard_Integer i, j, nF1, nF2, aNbFFs, aNbS, aNbCurves, nSp, iRank1;
-  Standard_Integer nE, nF, aNbPB, iBeg, iEnd;
-  BooleanOperations_StateOfShape aState;
-  TopExp_Explorer anExp;
-  TopAbs_ShapeEnum aType;
-  gp_Pnt2d aP2D;
-  gp_Pnt aP3D;
-  //
-  const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
-  const BOPTools_InterferencePool& anInterfPool=myDSFiller->InterfPool();
-  BOPTools_InterferencePool* pInterfPool=(BOPTools_InterferencePool*) &anInterfPool;
-  BOPTools_CArray1OfSSInterference& aFFs=pInterfPool->SSInterferences();
-  const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
-  const BOPTools_SplitShapesPool& aSplitShapesPool=aPaveFiller.SplitShapesPool();
-  //
-  // 1. process pf non-interferring faces
-  iBeg=1;
-  iEnd=aDS.NumberOfShapesOfTheObject();
-  if (myRank==2) {
-    iBeg=iEnd+1;
-    iEnd=aDS.NumberOfSourceShapes();
-  }
-  //
-  for (i=iBeg; i<=iEnd; ++i) {
-    aType=aDS.GetShapeType(i);
-    if (aType!=TopAbs_FACE) {
-      continue;
+    iRank=-1;
+    const TopoDS_Shape& aObj=aLS.First();
+    if (aObj.ShapeType()==TopAbs_SHELL) {
+      iRank=0;
     }
-    //
-    const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(i));
-    aState=aDS.GetState(i);
-    if (aState==BooleanOperations_IN) {
-      myLSIN.Append(aF1);
+    const TopoDS_Shape& aTool=aLS.Last();
+    if (aTool.ShapeType()==TopAbs_SHELL) {
+      iRank=1;
     }
-    else if (aState==BooleanOperations_OUT) {
-      myLSOUT.Append(aF1);
+    //
+    if (iRank==-1) {
+      myErrorStatus=14;
+      return;
     }
-  }
-  //
-  // 2. process pf interferred faces
-  aNbFFs=aFFs.Extent();
-  for (i=1; i<=aNbFFs; ++i) {
-    BOPTools_SSInterference& aFFi=aFFs(i);
     //
-    nF1=aFFi.Index1();
-    nF2=aFFi.Index2();
-    iRank1=aDS.Rank(nF1);
-    nF=(iRank1==myRank) ? nF1 : nF2;
-    const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF));
+    Handle(IntTools_Context) aCtx=myDSFiller->Context();
+    const BOPDS_IndexRange& aRange=pDS->Range(iRank);
+    aRange.Indices(iBeg, iEnd);
+    const TopoDS_Solid& aSolid=(!iRank) ? *((TopoDS_Solid*)&aTool) : *((TopoDS_Solid*)&aObj);
+    //BRepClass3d_SolidClassifier& aSC=aCtx->SolidClassifier(aSolid);
     //
-    bIsTouchCase=aFFi.IsTangentFaces();
+    //------------------------------ShellSolidBuilder
+    GEOMAlgo_ShellSolidBuilder aSSB;
     //
-    if (bIsTouchCase) {
-      myLSON.Append(aF1);
-      continue;
+    aSSB.PerformWithFiller(*myDSFiller);
+    iErr=aSSB.HasErrors();
+    if (iErr) {
+      myErrorStatus=15;
+      return;
     }
     //
-    // Has section edges ?
-    aNbS=0;
-    BOPTools_SequenceOfCurves& aBCurves=aFFi.Curves();
-    aNbCurves=aBCurves.Length();
-    for (j=1; j<=aNbCurves; j++) {
-      BOPTools_Curve& aBC=aBCurves(j);
-      const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
-      aNbS=aSectEdges.Extent();
-      if (aNbS) {
-       break;
-      }
-    }
+    const TopTools_DataMapOfShapeListOfShape& aImages=aSSB.Images();
     //
-    if (aNbS) { // it has
-      continue;
-    }
-    //
-    anExp.Init(aF1, TopAbs_EDGE);
-    for (; anExp.More(); anExp.Next()) {
-      const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
-      if (BRep_Tool::Degenerated(aE)) {
-       continue;
+    //-------------------------------
+    for (i=iBeg; i<=iEnd; ++i) {
+      const TopoDS_Shape& aS=pDS->Shape(i);
+      aType=aS.ShapeType();
+      if (aType!=TopAbs_FACE) {
+        continue;
       }
       //
-      nE=aDS.ShapeIndex(aE, myRank);
-      const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(aDS.RefEdge(nE));
-      aNbPB=aLPB.Extent();
+      aState=TopAbs_UNKNOWN;
+      aF=*((TopoDS_Face*)&aS);
       //
-      if (aNbPB<2) {
-       nSp=nE;
-       if (aNbPB) {
-         const BOPTools_PaveBlock& aPB=aLPB.First();
-         nSp=aPB.Edge();
-       }
-       const TopoDS_Shape& aSp=aDS.Shape(nSp);
-       //
-       aState=aDS.GetState(nSp);
-       if (aState==BooleanOperations_IN) {
-         myLSIN.Append(aF1);
-       }
-       else if (aState==BooleanOperations_OUT) {
-         myLSOUT.Append(aF1);
-       }
-       else if (aState==BooleanOperations_ON) {
-         Standard_Real aTol;
-         TopAbs_State aSt;
-         //
-         //const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape((iRank1==myRank)? nF2 : nF1));
-         //aTol=BRep_Tool::Tolerance(aF2);
-         aTol=1.e-7;
-         //
-         BOPTools_Tools3D::PointNearEdge(aE, aF1, aP2D, aP3D);
-         const TopoDS_Solid& aRefSolid=(myRank==1) ? 
-           TopoDS::Solid(aDS.Tool()) : TopoDS::Solid(aDS.Object());
-         //
-         BOPTools_PaveFiller* pPF=(BOPTools_PaveFiller*)& aPaveFiller;
-         IntTools_Context& aCtx=pPF->ChangeContext();
-         //
-         BRepClass3d_SolidClassifier& aSC=aCtx.SolidClassifier(aRefSolid);
-         aSC.Perform(aP3D, aTol);
-         aSt=aSC.State();
-         if (aSt==TopAbs_IN) {
-           myLSIN.Append(aF1);
-         }
-         else if (aSt==TopAbs_OUT) {
-           myLSOUT.Append(aF1);
-         }
-       } 
-       break; 
-      } // if (aNbPB<2) { 
-    } //for (; anExp.More(); anExp.Next())
-  } 
-}
-//=======================================================================
-// function: DetectSDFaces
-// purpose: 
-//=======================================================================
-void GEOMAlgo_ShellSolid::DetectSDFaces()
-{
-  const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
-  BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
-  BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
-  //
-  Standard_Boolean bFlag;
-  Standard_Integer i, aNb, nF1, nF2,  iZone, aNbSps, iSenseFlag;
-  gp_Dir aDNF1, aDNF2;
-
-  aNb=aFFs.Extent();
-  for (i=1; i<=aNb; i++) {
-    bFlag=Standard_False;
-    
-    BOPTools_SSInterference& aFF=aFFs(i);
-    
-    nF1=aFF.Index1();
-    nF2=aFF.Index2();
-    const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
-    const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
-    //
-    // iSenseFlag;
-    const BOPTools_ListOfPaveBlock& aLPB=aFF.PaveBlocks();
-    aNbSps=aLPB.Extent();
-
-    if (!aNbSps) {
-      continue;
-    }
-    
-    const BOPTools_PaveBlock& aPB=aLPB.First();
-    const TopoDS_Edge& aSpE=TopoDS::Edge(aDS.Shape(aPB.Edge()));
-    
-    BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1); 
-    BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
-    iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
-    //
-    if (iSenseFlag==1 || iSenseFlag==-1) {
-    //
-    //
-      TopoDS_Face aF1FWD=aF1;
-      aF1FWD.Orientation (TopAbs_FORWARD);
-      
-      BOP_WireEdgeSet aWES (aF1FWD);
-      BOP_SDFWESFiller aWESFiller(nF1, nF2, *myDSFiller);
-      aWESFiller.SetSenseFlag(iSenseFlag);
-      aWESFiller.SetOperation(BOP_COMMON);
-      aWESFiller.Do(aWES);
-      
-      BOP_FaceBuilder aFB;
-      aFB.Do(aWES);
-      const TopTools_ListOfShape& aLF=aFB.NewFaces();
-
-      iZone=0;
-      TopTools_ListIteratorOfListOfShape anIt(aLF);
-      for (; anIt.More(); anIt.Next()) {
-       const TopoDS_Shape& aFR=anIt.Value();
-
-       if (aFR.ShapeType()==TopAbs_FACE) {
-         const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
-         //
-         Standard_Boolean bIsValidIn2D, bNegativeFlag;
-         bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
-         if (bIsValidIn2D) { 
-           //if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
-           iZone=1;
-           break;
-           //}
-         }
-         //
-       }
+      if (!aImages.IsBound(aS)) {
+        iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D);
+        if (iErr) {
+          myErrorStatus=16;
+          return;
+        }
+        //
+        aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx);
       }
-      
-      if (iZone) { 
-       bFlag=Standard_True;
-       aFF.SetStatesMap(aWESFiller.StatesMap());
+      else {
+        const TopTools_ListOfShape& aLSp=aImages.Find(aS);
+        aNbSp=aLSp.Extent();
+        if (aNbSp>0) {
+          continue;
+        }
+        //
+        if (aNbSp==1) {
+          aF=*((TopoDS_Face*)&aLSp.First());
+        }
+        //
+        iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D);
+        if (iErr) {
+          myErrorStatus=16;
+          return;
+        }
+        //
+        aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx);
       }
-      
-    }// if (iSenseFlag)
-  
-  aFF.SetTangentFacesFlag(bFlag);
-  aFF.SetSenseFlag (iSenseFlag);
-  }// end of for (i=1; i<=aNb; i++) 
+      //----------
+      if (aState==TopAbs_ON) {
+        myLSON.Append(aF);
+      }
+      else if (aState==TopAbs_OUT) {
+        myLSOUT.Append(aF);
+      }
+      else if (aState==TopAbs_IN) {
+        myLSIN.Append(aF);
+      } 
+      //----------
+    }//for (i=iBeg; i<=iEnd; ++i) {
+    
+  }// try
+  catch (Standard_Failure&) {
+    myErrorStatus=12;
+  }
 }