Salome HOME
Windows compatibility
[modules/geom.git] / src / ShHealOper / ShHealOper_FillHoles.cxx
index d80857e74870e08df6e81a05418e7727721733f6..d9adfbfabd65f43eab6b25085d0f1b302c3f348b 100644 (file)
@@ -1,60 +1,68 @@
-// File:      ShHealOper_FillHoles.cxx
-// Created:   26.04.04 17:35:30
-// Author:    Galina KULIKOVA
-//  < MODULE = KERNEL> <PACKAGE = ShHealOper> : <Shape Healing Operations>
-//  Copyright (C) 2003  CEA
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  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.
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-
-//  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.
+// 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, 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
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  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/ or email : webmaster.salome@opencascade.com
 //
 
+// File:      ShHealOper_FillHoles.cxx
+// Created:   26.04.04 17:35:30
+// Author:    Galina KULIKOVA
 
+#include <Basics_OCCTVersion.hxx>
+
+#include <ShapeFix_Shell.hxx>
+#include <ShapeFix_Face.hxx>
 #include <ShHealOper_FillHoles.hxx>
-#include <TopExp.hxx>
-#include <TopAbs_ShapeEnum.hxx>
 #include <ShapeAnalysis_FreeBounds.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <Geom_Curve.hxx>
+
 #include <BRep_Tool.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopTools_HSequenceOfShape.hxx>
-#include <TopoDS.hxx>
-#include <Geom_BSplineSurface.hxx>
-#include <GeomPlate_BuildPlateSurface.hxx>
-#include <TopoDS_Edge.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_HCurve.hxx>
-#include <GeomPlate_CurveConstraint.hxx>
-#include <GeomPlate_Surface.hxx>
-#include <TColgp_SequenceOfXY.hxx>
-#include <TColgp_SequenceOfXYZ.hxx>
 #include <BRep_Builder.hxx>
-#include <ShapeFix_Face.hxx>
-#include <BRep_Tool.hxx>
+#include <BRepFill_CurveConstraint.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
 #include <TopLoc_Location.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_HSequenceOfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
-#include <TopoDS_Shell.hxx>
-#include <ShapeFix_Shell.hxx>
-#include <GeomPlate_PlateG0Criterion.hxx>
+
+#include <Geom_Curve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <GeomPlate_Surface.hxx>
 #include <GeomPlate_MakeApprox.hxx>
-#include <Precision.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <BRepFill_CurveConstraint.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
+#include <GeomPlate_CurveConstraint.hxx>
+#include <GeomPlate_PlateG0Criterion.hxx>
+#include <GeomPlate_BuildPlateSurface.hxx>
 
+#include <TColgp_SequenceOfXY.hxx>
+#include <TColgp_SequenceOfXYZ.hxx>
+
+#include <Precision.hxx>
 
 //=======================================================================
 //function : ShHealOper_FillHoles()
@@ -67,33 +75,31 @@ ShHealOper_FillHoles::ShHealOper_FillHoles ()
 
 //=======================================================================
 //function : ShHealOper_FillHoles
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 ShHealOper_FillHoles::ShHealOper_FillHoles (const TopoDS_Shape& theShape)
 {
-  
   Init(theShape);
   InitParameters();
 }
+
 //=======================================================================
 //function : Init
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void ShHealOper_FillHoles::Init(const TopoDS_Shape& theShape)
 {
   ShHealOper_Tool::Init(theShape);
   TopExp::MapShapesAndAncestors( myInitShape, TopAbs_EDGE,TopAbs_SHELL   , myEdgeShells);
   TopExp::MapShapesAndAncestors ( myInitShape, TopAbs_EDGE,TopAbs_COMPOUND, myEdgeComps );
-  
+
   TopExp::MapShapesAndAncestors ( myInitShape, TopAbs_EDGE,TopAbs_FACE, myEdgeFaces );
 }
+
 //=======================================================================
 //function : InitParameters
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void ShHealOper_FillHoles::InitParameters(Standard_Integer theDegree,
                                           Standard_Integer theNbPtsOnCur,
                                           Standard_Integer theNbIter,
@@ -116,9 +122,8 @@ void ShHealOper_FillHoles::InitParameters(Standard_Integer theDegree,
 }
 //=======================================================================
 //function : Fill
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 Standard_Boolean ShHealOper_FillHoles::Fill()
 {
   ShapeAnalysis_FreeBounds sab(myInitShape);
@@ -128,17 +133,17 @@ Standard_Boolean ShHealOper_FillHoles::Fill()
   if(!aCompClosed.IsNull()) {
     TopoDS_Iterator aIt(aCompClosed);
 
-    for( ; aIt.More(); aIt.Next()) 
+    for( ; aIt.More(); aIt.Next())
       aFillWires.Append(aIt.Value());
   }
   if(!aCompOpen.IsNull()) {
     TopoDS_Iterator aIt(aCompOpen);
-    for(  ; aIt.More(); aIt.Next()) 
+    for(  ; aIt.More(); aIt.Next())
       aFillWires.Append(aIt.Value());
   }
-  
+
   TopExp_Explorer aExp(myInitShape,TopAbs_EDGE,TopAbs_FACE);
-  
+
   for( ; aExp.More(); aExp.Next())
     aFillWires.Append(aExp.Current());
 
@@ -147,9 +152,8 @@ Standard_Boolean ShHealOper_FillHoles::Fill()
 
 //=======================================================================
 //function : Fill
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 Standard_Boolean ShHealOper_FillHoles::Fill(const TopTools_SequenceOfShape& theFillShapes)
 {
   myDone = Standard_False;
@@ -178,36 +182,39 @@ Standard_Boolean ShHealOper_FillHoles::Fill(const TopTools_SequenceOfShape& theF
     Handle(Geom_Surface) aSurf = buildSurface(aWire,aCurves2d,aOrders,aSenses);
     if(aSurf.IsNull())
       myErrorStatus = ShHealOper_ErrorExecution;
-    else 
+    else
       myDone = (addFace(aSurf,aWire,aCurves2d,aOrders,aSenses) || myDone);
   }
   if(myDone)
+  {
     myResultShape = myContext->Apply(myResultShape);
+    myStatistics.AddModif( "Face created to fill hole" , aSeqWires->Length() );
+  }
   return myDone;
 }
+
 //=======================================================================
 //function : isCircle
-//purpose  : 
+//purpose  :
 //=======================================================================
 static Standard_Boolean isCircle(const TopoDS_Edge theEdge)
 {
   Standard_Real aFirst, aLast;
   Handle(Geom_Curve) aC3D = BRep_Tool::Curve(theEdge,aFirst, aLast );
   if(aC3D.IsNull()) return Standard_False;
-  Standard_Boolean isCirc = (aC3D->Value(aFirst).Distance(aC3D->Value(aLast)) < 
+  Standard_Boolean isCirc = (aC3D->Value(aFirst).Distance(aC3D->Value(aLast)) <
      aC3D->Value(aFirst).Distance(aC3D->Value((aFirst +aLast)/2)));
   return isCirc;
 }
 //=======================================================================
 //function : prepareWires
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Standard_Boolean ShHealOper_FillHoles::prepareWires(const TopTools_SequenceOfShape& theFillShapes,
                                                     Handle(TopTools_HSequenceOfShape)& theSeqWires)
 {
   Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
-  BRep_Builder aB;
   Standard_Integer i =1;
   for( ; i <= theFillShapes.Length(); i++) {
     TopExp_Explorer aExp;
@@ -225,10 +232,10 @@ Standard_Boolean ShHealOper_FillHoles::prepareWires(const TopTools_SequenceOfSha
       if (!BRep_Tool::Degenerated (TopoDS::Edge (aExp.Current())))
         if(myEdgeFaces.Contains(aExp.Current()) && myEdgeFaces.FindFromKey(aExp.Current()).Extent() >1)
           continue;
-       aSeqEdges->Append(aExp.Current());
+        aSeqEdges->Append(aExp.Current());
     }
   }
-  
+
   if(aSeqEdges->Length())
   {
     Standard_Real aTol = 0.;
@@ -238,23 +245,21 @@ Standard_Boolean ShHealOper_FillHoles::prepareWires(const TopTools_SequenceOfSha
     Handle(TopTools_HSequenceOfShape) anWiresClosed = new TopTools_HSequenceOfShape,
     anWiresOpen   = new TopTools_HSequenceOfShape;
     ShapeAnalysis_FreeBounds::SplitWires(aTmpWires, aTol, aShared, anWiresClosed, anWiresOpen);
-    
+
     for (i = 1; i <= anWiresClosed->Length(); i++)
       theSeqWires->Append (anWiresClosed->Value (i));
     for (i = 1; i <= anWiresOpen->Length(); i++)
       theSeqWires->Append (anWiresOpen->Value (i));
   }
-  
 
   for( i =1; i <= theSeqWires->Length(); i++) {
     TopoDS_Wire aWire = TopoDS::Wire(theSeqWires->Value(i));
-    
+
     TopoDS_Iterator aIt(aWire);
     Standard_Integer ne =0;
     TopoDS_Edge ae;
     for( ; aIt.More(); aIt.Next(), ne++)
-      ae = TopoDS::Edge(aIt.Value()); 
+      ae = TopoDS::Edge(aIt.Value());
     if((ne == 1) && ( !isCircle(ae))) {
       theSeqWires->Remove(i--);
       continue;
@@ -264,7 +269,7 @@ Standard_Boolean ShHealOper_FillHoles::prepareWires(const TopTools_SequenceOfSha
 }
 //=======================================================================
 //function : buildSurface
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Handle(Geom_Surface) ShHealOper_FillHoles::buildSurface(const TopoDS_Wire& theWire,
@@ -274,9 +279,8 @@ Handle(Geom_Surface) ShHealOper_FillHoles::buildSurface(const TopoDS_Wire& theWi
 {
   Handle(Geom_BSplineSurface) aSurf;
   try {
-    
       GeomPlate_BuildPlateSurface aBuilder(myDegree, myNbPtsOnCur, myNbIter,
-                                                myTol2d, myTol3d, myTolAng, myTolCrv);
+                                                 myTol2d, myTol3d, myTolAng, myTolCrv);
       TopoDS_Iterator aIter;
       for(aIter.Initialize (theWire); aIter.More(); aIter.Next()) {
 
@@ -284,10 +288,10 @@ Handle(Geom_Surface) ShHealOper_FillHoles::buildSurface(const TopoDS_Wire& theWi
         BRepAdaptor_Curve adC(ae);
         Handle(BRepAdaptor_HCurve) aHAD= new BRepAdaptor_HCurve(adC);
         Handle(BRepFill_CurveConstraint) aConst =
-           new BRepFill_CurveConstraint (aHAD, (Standard_Integer) GeomAbs_C0, myNbPtsOnCur, myTol3d);
-        //Handle(GeomPlate_CurveConstraint) aConst = 
+            new BRepFill_CurveConstraint (Handle(Adaptor3d_HCurve)::DownCast(aHAD), (Standard_Integer) GeomAbs_C0, myNbPtsOnCur, myTol3d);
+        //Handle(GeomPlate_CurveConstraint) aConst =
          // new GeomPlate_CurveConstraint(aHAD, (Standard_Integer) GeomAbs_C0, myNbPtsOnCur, myTol3d);
-        aBuilder.Add (aConst);
+        aBuilder.Add (Handle(GeomPlate_CurveConstraint)::DownCast(aConst));
       }
       aBuilder.Perform();
       if(!aBuilder.IsDone())
@@ -305,17 +309,16 @@ Handle(Geom_Surface) ShHealOper_FillHoles::buildSurface(const TopoDS_Wire& theWi
       S3d.Clear();
       aBuilder.Disc2dContour(4,S2d);
       aBuilder.Disc3dContour(4,0,S3d);
-      Standard_Real amaxTol = Max( myTol3d, 10* aDist); 
+      Standard_Real amaxTol = Max( myTol3d, 10* aDist);
       GeomPlate_PlateG0Criterion Criterion( S2d, S3d, amaxTol );
       GeomPlate_MakeApprox Approx( aPlSurf, Criterion, myTol3d, myMaxSeg, myMaxDeg );
       aSurf = Approx.Surface();
       if(aSurf.IsNull())
         return aSurf;
-      
+
       theCurves2d = aBuilder.Curves2d();
       theOrders    = aBuilder.Order();
       theSenses    = aBuilder.Sense();
-      
     }
 
   catch (Standard_Failure) {
@@ -327,7 +330,7 @@ Handle(Geom_Surface) ShHealOper_FillHoles::buildSurface(const TopoDS_Wire& theWi
 
 //=======================================================================
 //function : addFace
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Standard_Boolean ShHealOper_FillHoles::addFace(const Handle(Geom_Surface)& theSurf,
@@ -336,10 +339,9 @@ Standard_Boolean ShHealOper_FillHoles::addFace(const Handle(Geom_Surface)& theSu
                                                const Handle(TColStd_HArray1OfInteger)& theOrders,
                                                const Handle(TColStd_HArray1OfInteger)& theSenses)
 {
-  BRepBuilderAPI_MakeFace aMakeFace (theSurf);
+  BRepBuilderAPI_MakeFace aMakeFace (theSurf, Precision::Confusion());
   TopoDS_Face aFace = aMakeFace.Face();
   aFace.EmptyCopy();
-  
 
   TopoDS_Wire aWire;
   BRep_Builder aB;
@@ -355,9 +357,9 @@ Standard_Boolean ShHealOper_FillHoles::addFace(const Handle(Geom_Surface)& theSu
     BRep_Tool::Range (anEdge, aF, aL);
     TopLoc_Location aLoc;
     aB.UpdateEdge (anEdge, theCurves2d->Value (aInd),aFace, 0.);
-    
+
     aB.Range (anEdge, aFace, aF, aL);
-    
+
     // Set orientation of the edge: orientation should be changed
     // if its orientation does not make sence with curve orientation
     // recommended by GeomPlate
@@ -367,7 +369,6 @@ Standard_Boolean ShHealOper_FillHoles::addFace(const Handle(Geom_Surface)& theSu
     }
     aB.SameParameter(anEdge,Standard_False);
     aB.Add (aWire, anEdge);
-    Standard_Boolean isAdd = Standard_False;
     TopoDS_Shape aParent;
     if(!myEdgeFaces.Contains(anEdge))
       continue;
@@ -407,7 +408,7 @@ Standard_Boolean ShHealOper_FillHoles::addFace(const Handle(Geom_Surface)& theSu
 
 //=======================================================================
 //function : getResShape
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void ShHealOper_FillHoles::getResShape(const TopoDS_Shape& theAddShape,
@@ -430,7 +431,6 @@ void ShHealOper_FillHoles::getResShape(const TopoDS_Shape& theAddShape,
   aB.MakeShell(aTmpShell);
   TopTools_SequenceOfShape aseqShells;
   if(anhasShell) {
-    
     aB.Add(aTmpShell,theAddShape);
     Standard_Integer i =1;
     for( ; i <= aMapParent.Extent(); i++) {
@@ -450,9 +450,8 @@ void ShHealOper_FillHoles::getResShape(const TopoDS_Shape& theAddShape,
     TopoDS_Shape anshape = asfs->Shape();
     myContext->Replace(aseqShells.Value(1),anshape);
     Standard_Integer i =2;
-    for( ; i<= aseqShells.Length(); i++) 
+    for( ; i<= aseqShells.Length(); i++)
       myContext->Remove(aseqShells.Value(i));
-    
   }
   else {
     TopoDS_Compound aComp;
@@ -463,6 +462,5 @@ void ShHealOper_FillHoles::getResShape(const TopoDS_Shape& theAddShape,
       aB.Add(aComp,aIt.Value());
     aB.Add(aComp,theAddShape);
     myContext->Replace( oldshape,aComp);
-                        
   }
 }