Salome HOME
BugID IPAL9186: Added a call to method initGeomGen
[modules/geom.git] / src / NMTAlgo / NMTAlgo_Splitter_1.cxx
index 2c057d7f06d1ee783f89983b2977b2886780c5d5..6bdd934d5c02033e0fedd180b59cfd35f6537480 100644 (file)
@@ -5,34 +5,73 @@
 
 
 #include <NMTAlgo_Splitter.ixx>
-#include <TopExp_Explorer.hxx>
+
+#include <Precision.hxx>
+
+#include <gp_Pnt.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Compound.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopExp.hxx>
-#include <TopoDS_Iterator.hxx>
 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <NMTAlgo_Loop3d.hxx>
-#include <Precision.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeShape.hxx>
+
 #include <BRep_Tool.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS_Solid.hxx>
+
 #include <NMTAlgo_Loop3d.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+//
+#include <BOPTools_Tools2D.hxx>
+#include <Geom_Curve.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <BOPTools_Tools3D.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+#include <gp_Pln.hxx>
+#include <TopAbs_State.hxx>
+
+//
+static 
+  void RefineShells(const TopoDS_Shape& ,
+                   TopTools_ListOfShape&);
+static 
+  void RefineSolids(const TopoDS_Shape& ,
+                   TopTools_ListOfShape&);
+
+//modified by NIZNHY-PKV Fri Feb 25 17:19:39 2005f XX
+static
+  void GetPlanes (const TopoDS_Edge& anEx,
+               const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
+               const TopoDS_Face& aF1,
+               TopAbs_State& aStPF1);
+//modified by NIZNHY-PKV Fri Feb 25 17:19:44 2005t XX
 
 //=======================================================================
 //function : ShellsAndSolids
 //purpose  : 
 //=======================================================================
 void NMTAlgo_Splitter::ShellsAndSolids()
+ void NMTAlgo_Splitter::ShellsAndSolids()
 {
   Standard_Boolean bMakeSolids;
   TopAbs_ShapeEnum aType;
@@ -42,6 +81,9 @@
   myAddedFacesMap.Clear();
   bMakeSolids=(myLimit==TopAbs_SHAPE || myLimit<TopAbs_SHELL);
   //
+  //modified by NIZNHY-PKV Thu Feb 24 17:22:32 2005 f XX
+  myInternalFaces.Clear(); // remove it after all modifs
+  //modified by NIZNHY-PKV Thu Feb 24 17:22:56 2005 t XX
   aItS.Initialize(myListShapes);
   for ( ;aItS.More(); aItS.Next()) {
     const TopoDS_Shape& aS=aItS.Value();
 //function : MakeShells
 //purpose  : split S into compound of shells
 //=======================================================================
-  void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
-                                   TopTools_ListOfShape& aLNS)
+void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
+                                 TopTools_ListOfShape& aLNS)
 {
   NMTAlgo_Loop3d aShellMaker;
   //
   //
   aLNS=aShellMaker.MakeShells(myAddedFacesMap);
   //
+  RefineShells(aS, aLNS);
+  //
   // Add faces added to new shell to myAddedFacesMap:
   // avoid rebuilding twice common part of 2 solids.
   
 //function : MakeSolids
 //purpose  : make solids out of Shells
 //=======================================================================
-  void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape&   theSolid,
-                                   TopTools_ListOfShape& theShellList)
+void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape&   theSolid,
+                                 TopTools_ListOfShape& theShellList)
 {
   // for a solid wrapping other shells or solids without intersection,
   // it is necessary to find shells making holes in it
       TopoDS_Solid Solid;
       myBuilder.MakeSolid( Solid );
       myBuilder.Add (Solid, aShell);
-
+      
       aNewSolids.Append (Solid);
     }
   }
       myBuilder.Add (aSolid, aHole);
     }
   }
+  //
   theShellList.Clear();
-  theShellList.Append( aNewSolids );
+  //
+  RefineSolids(theSolid, aNewSolids);
+  //
+  theShellList.Append(aNewSolids);
 }
  
 //=======================================================================
                                                const Standard_Boolean All)
 {
   TopExp_Explorer expl;
+  TopAbs_State aState;
   //
   // ================================================
   // check if internal faces have been already found
   // ===========================
   // find faces inside theShape
   // ===========================
+  Standard_Boolean sameDom1, sameDom2;
   Standard_Boolean skipAlreadyAdded = Standard_False;
   Standard_Boolean GoodOri, inside;
   Standard_Real dot;
   // iterate on section edges, check faces of other shapes
   // sharing section edges and put internal faces to KeepFaces
   Mapit.Initialize(DMSEFP);
-  for (; Mapit.More() ; Mapit.Next() ) {
+  for (; Mapit.More() ; Mapit.Next()) {
     // a new edge of theShape
     const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
-    // an original edge of which E is a split
-    //const TopoDS_Edge& OrigE = TopoDS::Edge (myImagesEdges.Root(E));
-    // does OrigE itself splits a face
-    Standard_Boolean isSectionE=IsSectionEdge(E);//(OrigE);  
-
+    //
+    //Standard_Boolean isSectionE=IsSectionEdge(E);//(OrigE);  
+    //
     // split faces of other shapes sharing E
     TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
+    //
     itl.Initialize( LSF );
     while (itl.More()) {
       // a split faces of other shape
       TopoDS_Face aFace1 = TopoDS::Face(itl.Value());
       // remove aFace1 form DMSEFP and MFP
       LSF.Remove( itl ); // == itl.Next();
-      if (!MFP.Remove( aFace1 ))
-       continue; // was not is MFP ( i.e already checked)
+      if (!MFP.Remove(aFace1))
+       continue; // was not is MFP (i.e already checked)
+      //
       // check if aFace1 was already added to 2 shells
       if (!All &&
          myAddedFacesMap.Contains(aFace1) &&
          myAddedFacesMap.Contains(aFace1.Reversed())) {
        skipAlreadyAdded = Standard_True;
-       //modified by NIZNHY-PKV Wed Feb 11 16:11:53 2004 f
-       //continue;
-       //modified by NIZNHY-PKV Wed Feb 11 16:35:48 2004 t
       }
       //
-      // find another face which originates from the same face as aFace1:
-      // usually aFace2 is internal if aFace1 is not and vice versa
       TopoDS_Shape anOrigFace = aFace1;
       if (myImagesFaces.IsImage(aFace1)){
         anOrigFace = myImagesFaces.Root(aFace1);
       }
       //
-      TopoDS_Shape aFace2;
-      if ( !isSectionE ) {
-        while (itl.More()) {
-          aFace2 = itl.Value();
-         //
-          TopoDS_Shape anOrigFace2 = aFace2;
-         if (myImagesFaces.IsImage(aFace2)) {
-           anOrigFace2 = myImagesFaces.Root(aFace2);
-         }
-         //
-          if (!MFP.Contains( aFace2 )) {
-            LSF.Remove( itl );
-            continue;
-          }
-          //if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
-          if (anOrigFace.IsSame(anOrigFace2)) {
-            break;
-         }
-          itl.Next();
-        }
-        if (itl.More()) { // aFace2 found, remove it from maps
-          LSF.Remove( itl );
-          MFP.Remove(aFace2);
-        }
-        else{
-          aFace2.Nullify();
-       }
-        itl.Initialize( LSF );
-      } 
-
+      // <- A was here
+      //
       // check that anOrigFace is not same domain with CSF faces it intersects
-
+      //
       const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E
-      
+      //
       const TopoDS_Shape& origF1 = myImagesFaces.IsImage(FL.First()) ?
        myImagesFaces.Root(FL.First()) : FL.First();
+      //
       const TopoDS_Shape& origF2 = myImagesFaces.IsImage(FL.Last()) ?
        myImagesFaces.Root(FL.Last()) : FL.Last();
       //
-      Standard_Boolean sameDom1 = anOrigFace.IsSame( origF1 );
-      Standard_Boolean sameDom2 = anOrigFace.IsSame( origF2 );
-
+      sameDom1 = anOrigFace.IsSame( origF1 );
+      sameDom2 = anOrigFace.IsSame( origF2 );
+      //
       if (!(sameDom1 || sameDom2) && HasSameDomainF( TopoDS::Face(anOrigFace) )) {       
        sameDom1 = IsSameDomainF( TopoDS::Face(anOrigFace), TopoDS::Face(origF1));
         if (origF1 == origF2) {
           sameDom2 = sameDom1;
        }
-        else{
-          IsSameDomainF( TopoDS::Face(anOrigFace), TopoDS::Face(origF2));                   
-       }
       }
       if (sameDom1 && sameDom2){
        continue;
       }
+      //
       if (sameDom1 || sameDom2) {
        inside = NMTAlgo_Loop3d::IsInside (E,
                                           TopoDS::Face(FL.First()),
                                           TopoDS::Face(FL.Last()),
                                           1, dot, GoodOri);
-       if (inside || (dot + Precision::Angular() >= 1.0))
+       if (inside || (dot + Precision::Angular() >= 1.0)) {
          continue; // E is convex between origF1 and origF2 or they are tangent
-      }
-      //
-      // keep one of found faces
-
-      //face of CSF sharing E
-      const TopoDS_Shape& aShapeFace = sameDom1 ? FL.Last() : FL.First();
-      // analyse aFace1 state
-      inside = NMTAlgo_Loop3d::IsInside (E, TopoDS::Face(aShapeFace), aFace1,
-                                          1, dot, GoodOri);
-//      if (inside && isSectionE) {
-      if (inside) { //IFV 27.08.04
-        // aFace1 must be tested with both adjacent faces of CSF
-        const TopoDS_Shape& aShapeFace2 = sameDom1 ? FL.First() : FL.Last();
-        if (aShapeFace2 != aShapeFace){
-          inside = NMTAlgo_Loop3d::IsInside (E, TopoDS::Face(aShapeFace2), aFace1,
-                                               1, dot, GoodOri);
        }
       }
       //
-      // store internal face
-      if (inside)
-        KeepFaces.Append(aFace1);
-
-      else if (!aFace2.IsNull()) {
-        if (dot + Precision::Angular() >= 1.0) {
-          // aFace2 state is not clear, it will be analysed alone,
-          // put it back to the maps
-          MFP.Add( aFace2 );
-          LSF.Append( aFace2 );
-        }
-        else
-          KeepFaces.Append(aFace2);
+      GetPlanes(E, DMEF, aFace1, aState);
+      if (aState==TopAbs_IN) {
+       KeepFaces.Append(aFace1);
       }
-    }
-  }
+    } //while (itl.More()) {
+  } //for (; Mapit.More() ; Mapit.Next() )
 
   // ===================================================
   // add not distributed faces connected with KeepFaces
 //purpose  : Return True if the first vertex of S1 inside S2.
 //           If S1.IsNull(), check infinite point against S2.
 //=======================================================================
-  Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
-                                              const TopoDS_Shape& theS2)
+Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
+                                            const TopoDS_Shape& theS2)
 {
   BRepClass3d_SolidClassifier aClassifier( theS2 );
   //
   //
   return ( aClassifier.State() == TopAbs_IN );
 }
-
 //=======================================================================
 //function : GetOriginalShape
 //purpose  : Return the  shape  aShape  originates from. aShape
 //           should be a face or more complex result shape
 //=======================================================================
-  TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
+TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
 {
   TopoDS_Shape anOrigShape;
 
   }
   return anOrigShape;
 }
+//=======================================================================
+//function :RefineShells 
+//purpose  : 
+//=======================================================================
+void RefineShells(const TopoDS_Shape& aS,
+                 TopTools_ListOfShape& aLNS)
+{
+  Standard_Boolean bFound;
+  Standard_Integer iS, jS, aNbSOrs, aNbSIms, aNbFOrs, aNbFIms, kFOrs, aNb;
+  TopTools_ListIteratorOfListOfShape aIt;
+  TopTools_IndexedMapOfShape aMSOrs, aMSIms, aMFOrs, aMFIms;
+  TopTools_IndexedDataMapOfShapeShape aMImOr;
+  TopTools_ListOfShape aLS;
+  //
+  TopExp::MapShapes(aS, TopAbs_SHELL, aMSOrs);
+  aIt.Initialize(aLNS);
+  for (;aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aSh=aIt.Value();
+    aMSIms.Add(aSh);
+  }
+  //
+  aNbSOrs=aMSOrs.Extent();
+  aNbSIms=aMSIms.Extent();
+  //
+  for (iS=1; iS<=aNbSOrs; ++iS) {
+    const TopoDS_Shape& aSOr=aMSOrs(iS);
+    aMFOrs.Clear();
+    TopExp::MapShapes(aSOr, TopAbs_FACE, aMFOrs);
+    aNbFOrs=aMFOrs.Extent();
+    //
+    for (jS=1; jS<=aNbSIms; ++jS) {
+      const TopoDS_Shape& aSIm=aMSIms(jS);
+      if (aMImOr.Contains(aSIm)) {
+       continue;
+      }
+      //
+      aMFIms.Clear();
+      TopExp::MapShapes(aSIm, TopAbs_FACE, aMFIms);
+      aNbFIms=aMFIms.Extent();
+      //
+      if (aNbFIms==aNbFOrs) {
+       bFound=Standard_True;
+       for (kFOrs=1; kFOrs<=aNbFOrs; ++kFOrs) {
+         const TopoDS_Shape& aFOr=aMFOrs(kFOrs);
+         if (!aMFIms.Contains(aFOr)) {
+           bFound=Standard_False;
+           break; //next aSIm
+         }
+       }
+       if (bFound){
+         aMImOr.Add(aSIm, aSOr);
+         break; //next aSOr
+       }
+      } //if (aNbFIms==aNbFOrs)
+    }
+  }
+  //
+  aNb=aMImOr.Extent();
+  aIt.Initialize(aLNS);
+  for (;aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aSh=aIt.Value();
+    if (aMImOr.Contains(aSh)) {
+      const TopoDS_Shape& aSOr=aMImOr.FindFromKey(aSh);
+      aLS.Append(aSOr);
+    }
+    else {
+      aLS.Append(aSh);
+    }
+  }
+  //
+  aLNS.Clear();
+  aLNS.Append(aLS);
+}
+
+//=======================================================================
+//function :RefineSolids 
+//purpose  : 
+//=======================================================================
+void RefineSolids(const TopoDS_Shape& aSolidOr,
+                 TopTools_ListOfShape& aLNS)
+{
+  Standard_Integer aNb, iS,  aNbSOrs, aNbSIms;
+  TopoDS_Shape aSolidIm;
+  TopTools_IndexedMapOfShape aMSOrs, aMSIms;
+  //
+  aNb=aLNS.Extent();
+  if (aNb!=1) {
+    return;
+  }
+  //
+  aSolidIm=aLNS.First();
+  
+  TopExp::MapShapes(aSolidOr, TopAbs_SHELL, aMSOrs);
+  TopExp::MapShapes(aSolidIm, TopAbs_SHELL, aMSIms);
+  aNbSOrs=aMSOrs.Extent();
+  aNbSIms=aMSIms.Extent();
+  if (aNbSOrs!=aNbSIms) {
+    return;
+  }
+  //
+  for (iS=1; iS<=aNbSOrs; ++iS) {
+    const TopoDS_Shape& aSOr=aMSOrs(iS);
+    if (!aMSIms.Contains(aSOr)) {
+      return;
+    }
+  }
+  //
+  aLNS.Clear();
+  aLNS.Append(aSolidOr);
+}
+//modified by NIZNHY-PKV Fri Feb 25 16:59:57 2005f XX
+//=======================================================================
+//function : GetPlanes
+//purpose  :
+//=======================================================================
+void GetPlanes (const TopoDS_Edge& anEx,
+               const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
+               const TopoDS_Face& aF1,
+               TopAbs_State& aStPF1)
+               
+{
+  Standard_Boolean bIsAdjExists;
+  Standard_Real aT, aT1, aT2;
+  TopAbs_Orientation anOrEx, anOr;
+  gp_Dir aDNFx1, aDNFx2, aDNF1; 
+  gp_Pnt aPx, aPx1, aPx2, aPF1;
+  TopoDS_Edge aERight, aSpxSimm;
+  TopoDS_Face aFx1, aFx2, aFF1;
+  TopTools_ListIteratorOfListOfShape anIt;
+  //
+  // Point on Edge
+  Handle(Geom_Curve)aC3D =BRep_Tool::Curve(anEx, aT1, aT2);
+  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
+  
+  aC3D->D0(aT, aPx);
+  //
+  anOrEx=anEx.Orientation();
+  
+  aSpxSimm=anEx;
+  if (anOrEx==TopAbs_FORWARD) {
+    aSpxSimm.Orientation(TopAbs_REVERSED);
+  }
+  else if (anOrEx==TopAbs_REVERSED){
+    aSpxSimm.Orientation(TopAbs_FORWARD);
+  }
+  //
+  const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
+  anIt.Initialize(aLF);
+  for (; anIt.More(); anIt.Next()) {
+    const TopoDS_Shape& aFE=anIt.Value();
+    aFx1=TopoDS::Face(aFE);
+    anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
+    if (anOr==anOrEx){
+      break;
+    }
+  }
+  //
+  BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
+  //
+  bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
+  if (!bIsAdjExists) {
+    BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2); 
+  }
+  else {
+    BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
+  }
+  //
+  aFF1=aF1;
+  aFF1.Orientation(TopAbs_FORWARD);
+  BOPTools_Tools3D::OrientEdgeOnFace (anEx, aFF1, aERight);
+  BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aERight, aFF1, aT, aPF1, aDNF1);
+  //
+  {
+    Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
+    
+    aTwoPI=Standard_PI+Standard_PI;
+    
+    gp_Vec aVx1(aPx, aPx1);
+    gp_Dir aDBx1 (aVx1);
+    gp_Pln aPlnToCompare (aPx, aDNFx1);
+    
+    gp_Vec aVx2(aPx, aPx2);
+    gp_Dir aDBx2 (aVx2);
+    
+    anAlfa12=aDBx1.Angle(aDBx2);
+    d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
+    if (d12 < 0.) {
+      anAlfa12=aTwoPI-anAlfa12;
+    }
+    
+    gp_Vec aVF1(aPx, aPF1);
+    gp_Dir aDBF1 (aVF1);
+    anAlfa1=aDBx1.Angle(aDBF1);
+    d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
+    if (d1 < 0.) {
+      anAlfa1=aTwoPI-anAlfa1;
+    }
+    
+    aStPF1=TopAbs_OUT;
+    if (anAlfa1 > anAlfa12) {
+      aStPF1=TopAbs_IN;
+    }
+  }
+}
+//modified by NIZNHY-PKV Fri Feb 25 17:00:03 2005t XX 
+/*
+        A
+      //
+      TopoDS_Shape aFace2;
+      if ( !isSectionE ) {
+        while (itl.More()) {
+          aFace2 = itl.Value();
+         //
+          TopoDS_Shape anOrigFace2 = aFace2;
+         if (myImagesFaces.IsImage(aFace2)) {
+           anOrigFace2 = myImagesFaces.Root(aFace2);
+         }
+         //
+          if (!MFP.Contains( aFace2 )) {
+            LSF.Remove( itl );
+            continue;
+          }
+          //if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
+          if (anOrigFace.IsSame(anOrigFace2)) {
+            break;
+         }
+          itl.Next();
+        }
+        if (itl.More()) { // aFace2 found, remove it from maps
+          LSF.Remove( itl );
+          MFP.Remove(aFace2);
+        }
+        else{
+          aFace2.Nullify();
+       }
+        itl.Initialize( LSF );
+      } 
+      */