0030052: Data Exchange - STEP import missing surfaces
[occt.git] / src / ShapeFix / ShapeFix_Face.cxx
index 9ebadf5..32dede1 100644 (file)
@@ -348,7 +348,7 @@ static Standard_Boolean SplitWire(const TopoDS_Face &face, const TopoDS_Wire& wi
 
   if(aResWires.Length()>1) {
 #ifdef OCCT_DEBUG
-    cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< endl;
+    std::cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< std::endl;
 #endif
   }
 
@@ -995,7 +995,7 @@ Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
   
 /**/
 #ifdef OCCT_DEBUG
-  cout<<"Natural bound on sphere or torus with holes added"<<endl; // mise au point !
+  std::cout<<"Natural bound on sphere or torus with holes added"<<std::endl; // mise au point !
 #endif
   SendWarning ( myFace, Message_Msg ( "FixAdvFace.FixOrientation.MSG0" ) );// Face created with natural bounds
   return Standard_True;
@@ -1106,7 +1106,7 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
       SendWarning ( sbdw->Wire(), Message_Msg ( "FixAdvFace.FixOrientation.MSG5" ) );// Wire on face was reversed
       done = Standard_True;
 #ifdef OCCT_DEBUG
-      cout<<"Wire reversed"<<endl; // mise au point !
+      std::cout<<"Wire reversed"<<std::endl; // mise au point !
 #endif
     }
   }
@@ -1156,6 +1156,10 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
       for(;ew.More(); ew.Next()) {
         TopoDS_Edge ed = TopoDS::Edge (ew.Value());
         Handle(Geom2d_Curve) cw = BRep_Tool::CurveOnSurface (ed,myFace,cf,cl);
+        if (cw.IsNull ())
+        {
+          continue;
+        }
         Geom2dAdaptor_Curve gac;
         Standard_Real aFirst = cw->FirstParameter();
         Standard_Real aLast = cw->LastParameter();
@@ -1403,7 +1407,7 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
     for( ; k <= aSeqReversed.Length(); k++ )
     {
 #ifdef OCCT_DEBUG
-      cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<endl; // mise au point !
+      std::cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<std::endl; // mise au point !
 #endif
     }
       
@@ -1567,18 +1571,18 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
         else {
           w2.Reverse();
 #ifdef OCCT_DEBUG
-          if ( ! isdeg2 ) cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << endl;
+          if ( ! isdeg2 ) std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << std::endl;
 #endif
         }
       }
 #ifdef OCCT_DEBUG
-      else cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires" << endl;
+      else std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires" << std::endl;
 #endif
     }
 //    else return Standard_False; //  abort
     else {
 #ifdef OCCT_DEBUG
-      cout << "Warning: ShapeFix_Face::FixMissingSeam(): more than two open wires detected!" << endl;
+      std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): more than two open wires detected!" << std::endl;
 #endif
       //:abv 30.08.09: if more than one open wires and more than two of them are
       // completely degenerated, remove any of them
@@ -1588,7 +1592,7 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
         w2.Nullify();
         i = 0;
 #ifdef OCCT_DEBUG
-        cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed" << endl;
+        std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed" << std::endl;
 #endif
         continue;
       }
@@ -1859,13 +1863,56 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
   mySurf = new ShapeAnalysis_Surface ( RTS );
 
   myResult = CompShell.Result();
-//  if ( myFace.Orientation() == TopAbs_REVERSED ) res.Reverse();
   Context()->Replace ( myFace, myResult );
+
+  // Remove small wires and / or faces that can be generated by ComposeShell
+  // (see tests bugs step bug30052_4, de step_3 E6)
+  Standard_Integer nbFaces = 0;
+  TopExp_Explorer expF ( myResult, TopAbs_FACE );
+  for (; expF.More(); expF.Next() )
+  {
+    TopoDS_Face aFace = TopoDS::Face(expF.Value());
+    TopExp_Explorer aExpW(aFace, TopAbs_WIRE);
+    Standard_Integer nbWires = 0;
+    for( ;aExpW.More(); aExpW.Next() )
+    {
+      ShapeFix_Wire aSfw(TopoDS::Wire(aExpW.Value()), aFace, Precision());
+      aSfw.SetContext(Context());
+      if(aSfw.NbEdges())
+        aSfw.FixSmall (Standard_True, Precision());
+      if(!aSfw.NbEdges())
+      {
+        Context()->Remove(aExpW.Value());
+        continue;
+      }
+      nbWires++;
+    }
+    if(!nbWires)
+    {
+      Context()->Remove(aFace);
+      continue;
+    }
+    nbFaces++;
+  }
+   
+  myResult = Context()->Apply(myResult);
   for (TopExp_Explorer exp ( myResult, TopAbs_FACE ); exp.More(); exp.Next() ) {
-    myFace = TopoDS::Face ( exp.Current() );
+    myFace = TopoDS::Face ( Context()->Apply(exp.Current() ));
+    if( myFace.IsNull())
+      continue;
+    if(nbFaces > 1)
+    {
+      FixSmallAreaWire(Standard_True);
+      TopoDS_Shape aShape = Context()->Apply(myFace);
+      if(aShape.IsNull() )
+        continue;
+      myFace = TopoDS::Face(aShape);
+    }
     BRepTools::Update(myFace); //:p4
   }
-
+  myResult = Context()->Apply(myResult);
+  
   SendWarning ( Message_Msg ( "FixAdvFace.FixMissingSeam.MSG0" ) );// Missing seam-edge added
   return Standard_True;
 }
@@ -1888,6 +1935,7 @@ Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRem
 
   TopoDS_Shape anEmptyCopy = myFace.EmptyCopied();
   TopoDS_Face  aFace = TopoDS::Face(anEmptyCopy);
+  aFace.Orientation (TopAbs_FORWARD);
 
   const Standard_Real aTolerance3d = ShapeFix_Root::Precision();
   for (TopoDS_Iterator aWIt(myFace, Standard_False); aWIt.More(); aWIt.Next())
@@ -1921,7 +1969,7 @@ Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRem
   if ( nbWires <= 0 )
   {
 #ifdef OCCT_DEBUG
-    cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched" << endl;
+    std::cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched" << std::endl;
 #endif
     if ( theIsRemoveSmallFace && !Context().IsNull() )
       Context()->Remove(myFace);
@@ -1929,10 +1977,11 @@ Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRem
     return Standard_False;
   }
 #ifdef OCCT_DEBUG
-  cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed" << endl;
+  std::cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed" << std::endl;
 #endif
-  if ( !Context().IsNull() )
-    Context()->Replace(myFace, aFace);
+  aFace.Orientation (myFace.Orientation ());
+  if (!Context ().IsNull ())
+    Context ()->Replace (myFace, aFace);
 
   myFace = aFace;
   return Standard_True;
@@ -2146,7 +2195,7 @@ Standard_Boolean ShapeFix_Face::FixLoopWire(TopTools_SequenceOfShape& aResWires)
   if(isDone && aResWires.Length() >1)
   {
 #ifdef OCCT_DEBUG
-    cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< endl;
+    std::cout<<"Wire was splitted on "<<aResWires.Length()<<" wires"<< std::endl;
 #endif
   }
 
@@ -2421,7 +2470,7 @@ Standard_Boolean ShapeFix_Face::FixSplitFace(const TopTools_DataMapOfShapeListOf
       V2=sae.LastVertex(E2);
       if(!V1.IsSame(V2)) {
 #ifdef OCCT_DEBUG
-        cout<<"wire not closed --> stop split"<<endl;
+        std::cout<<"wire not closed --> stop split"<<std::endl;
 #endif
         return Standard_False;
       }