]> OCCT Git - occt-copy.git/commitdiff
0026556: Infinite calculations of BRepOffset_MakeOffset
authoraml <aml@opencascade.com>
Thu, 20 Aug 2015 07:24:00 +0000 (10:24 +0300)
committerabv <abv@opencascade.com>
Wed, 2 Sep 2015 11:39:24 +0000 (14:39 +0300)
Method for pre-analysis of input data added (CheckInputData).
Now it is possible to work with Error() function, which return error code.

Tests corrected according to changed error appearance.

src/BRepOffset/BRepOffset.cdl
src/BRepOffset/BRepOffset_MakeOffset.cdl
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepTest/BRepTest_FeatureCommands.cxx
tests/bugs/modalg_2/bug21261_15
tests/bugs/modalg_2/bug21261_21
tests/offset/shape/A2
tests/offset/shape/A3

index 2147e086ba8e3609f44aabd8ee6f66b160d2667f..609b5893e954b0dd1938ef83acbd74abb3005bbd 100644 (file)
@@ -72,7 +72,11 @@ is
        UnCorrectClosingFace,
         ExtentFaceFailed,
        RadiusEqualOffset,
-       UnknownError
+       UnknownError,
+       BadNormalsOnGeometry,
+       C0Geometry,
+       NullOffset,
+       NotConnectedShell
     end Error;
     
     class MakeOffset;
index e37b08d567959a371b18b33f32a151bc5b9955b1..a14db04d686f44f9ec65bf30355cdfca06dfb845 100644 (file)
@@ -136,6 +136,19 @@ is
     returns IndexedMapOfShape from TopTools
     is static;
 
+    CheckInputData(me: in out) returns Boolean;
+        ---Purpose: Makes pre analysis of possibility offset perform. Use method Error() to get more information.
+        ---         Finds first error. List of checks:
+        ---         1) Check for existence object with non-null offset.
+        ---         2) Check for connectivity in offset shell.
+        ---         3) Check continuity of input surfaces.
+        ---         4) Check for normals existence on grid.
+        ---         @return 1 if possible make computations and 0 if not possible.
+
+    GetBadShape (me) returns Shape from TopoDS;
+        ---Purpose: Return bad shape, which obtained in CheckInputData.
+        ---C++: return const &
+
 ---Category: private methods
 
     BuildOffsetByArc ( me : in out )
@@ -224,5 +237,6 @@ fields
     myError          : Error    from BRepOffset;
     
     myMakeLoops      : MakeLoops from BRepOffset;
+    myBadShape       : Shape     from TopoDS;
     
 end MakeOffset;
index ce512d870b6c7a10bea283d6b94b148b502850eb..9907b57b36b07844efc0fc7d1d90a1339df2b4bc 100644 (file)
 #include <BRepGProp.hxx>
 // POP for NT
 #include <stdio.h>
+#include <NCollection_Vector.hxx>
 
 #ifdef DRAW
 
@@ -682,29 +683,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
     RemoveCorks (myShape,myFaces);
   }
 
-  if (! IsConnectedShell(myShape))
-    Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
-
-  if (Abs(myOffset) <= myTol)
+  if (!CheckInputData())
   {
-    // Check for face with non-null offset value.
-    Standard_Boolean isFound = Standard_False;
-    TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
-    for( ; anIter.More(); anIter.Next())
-    {
-      if (Abs(anIter.Value()) > myTol)
-      {
-        isFound = Standard_True;
-        break;
-      }
-    }
-
-    if (!isFound)
-    {
-      // No face with non-null offset found.
+    // There is error in input data.
+    // Check Error() method.
       return;
     }
-  }
 
   TopAbs_State       Side = TopAbs_IN;
   if (myOffset < 0.) Side = TopAbs_OUT;
@@ -3400,3 +3384,176 @@ void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
   }
   theSol = aNewSol;
 }
+
+//=======================================================================
+//function : CheckInputData
+//purpose  : Check input data for possiblity of offset perform.
+//=======================================================================
+Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
+{
+  // Set initial error state.
+  myError = BRepOffset_NoError;
+  TopoDS_Shape aTmpShape;
+  myBadShape = aTmpShape;
+
+  // Non-null offset.
+  if (Abs(myOffset) <= myTol)
+  {
+    Standard_Boolean isFound = Standard_False;
+    TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
+    for( ; anIter.More(); anIter.Next())
+    {
+      if (Abs(anIter.Value()) > myTol)
+      {
+        isFound = Standard_True;
+        break;
+      }
+    }
+
+    if (!isFound)
+    {
+      // No face with non-null offset found.
+      myError = BRepOffset_NullOffset;
+      return Standard_False;
+    }
+  }
+
+  // Connectivity of input shape.
+  if (!IsConnectedShell(myShape))
+  {
+    myError = BRepOffset_NotConnectedShell;
+    return Standard_False;
+  }
+
+
+  // Normals check and continuity check.
+  const Standard_Integer aPntPerDim = 20; // 21 points on each dimension.
+  Standard_Real aUmin, aUmax, aVmin, aVmax;
+  TopExp_Explorer anExpSF(myShape, TopAbs_FACE);
+  TopLoc_Location L;
+  gp_Pnt2d aPnt2d;
+  gp_Pnt aPnt;
+  gp_Vec aD1U, aD1V;
+  for( ; anExpSF.More(); anExpSF.Next())
+  {
+    const TopoDS_Face& aF = TopoDS::Face(anExpSF.Current());
+    const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aF, L);
+    BRepTools::UVBounds(aF, aUmin, aUmax, aVmin, aVmax);
+
+    // Continuity check.
+    if (aSurf->Continuity() == GeomAbs_C0)
+    {
+      myError = BRepOffset_C0Geometry;
+      return Standard_False;
+    }
+
+    // Get degenerated points, to avoid check them.
+    NCollection_Vector<gp_Pnt> aBad3dPnts;
+    TopExp_Explorer anExpFE(aF, TopAbs_EDGE);
+    for( ; anExpFE.More(); anExpFE.Next())
+    {
+      const TopoDS_Edge &aE = TopoDS::Edge(anExpFE.Current());
+      if (BRep_Tool::Degenerated(aE))
+      {
+        aBad3dPnts.Append(BRep_Tool::Pnt((TopExp::FirstVertex(aE))));
+      }
+    }
+
+    // Geometry grid check.
+    for(Standard_Integer i = 0; i <= aPntPerDim; i++)
+    {
+      Standard_Real aUParam = aUmin + (aUmax - aUmin) * i / aPntPerDim;
+      for(Standard_Integer j = 0; j <= aPntPerDim; j++)
+      {
+        Standard_Real aVParam = aVmin + (aVmax - aVmin) * j / aPntPerDim;
+
+        aSurf->D1(aUParam, aVParam, aPnt, aD1U, aD1V);
+
+        if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
+            aD1V.SquareMagnitude() < Precision::SquareConfusion() )
+        {
+          Standard_Boolean isKnownBadPnt = Standard_False;
+          for(Standard_Integer anIdx  = aBad3dPnts.Lower();
+                               anIdx <= aBad3dPnts.Upper();
+                             ++anIdx)
+          {
+            if (aPnt.SquareDistance(aBad3dPnts(anIdx)) < Precision::SquareConfusion())
+            {
+              isKnownBadPnt = Standard_True;
+              break;
+            }
+          } // for(Standard_Integer anIdx  = aBad3dPnts.Lower();
+
+          if (!isKnownBadPnt)
+          {
+            myError = BRepOffset_BadNormalsOnGeometry;
+            return Standard_False;
+          }
+          else
+            continue;
+        } //  if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
+
+
+        Standard_Real anAngle = aD1U.Angle(aD1V);
+        if (Abs (anAngle) < Precision::Confusion())
+        {
+          myError = BRepOffset_BadNormalsOnGeometry;
+          return Standard_False;
+        }
+      }
+    }
+
+    // Vertex list check.
+    TopExp_Explorer anExpFV(aF, TopAbs_VERTEX);
+    for( ; anExpFV.More(); anExpFV.Next())
+    {
+      const TopoDS_Vertex &aV = TopoDS::Vertex(anExpFV.Current());
+
+      aPnt2d = BRep_Tool::Parameters(aV, aF);
+      aSurf->D1(aPnt2d.X(), aPnt2d.Y(), aPnt, aD1U, aD1V);
+
+      if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
+          aD1V.SquareMagnitude() < Precision::SquareConfusion() )
+      {
+        Standard_Boolean isKnownBadPnt = Standard_False;
+        for(Standard_Integer anIdx  = aBad3dPnts.Lower();
+          anIdx <= aBad3dPnts.Upper();
+          ++anIdx)
+        {
+          if (aPnt.SquareDistance(aBad3dPnts(anIdx)) < Precision::SquareConfusion())
+          {
+            isKnownBadPnt = Standard_True;
+            break;
+          }
+        } // for(Standard_Integer anIdx  = aBad3dPnts.Lower();
+
+        if (!isKnownBadPnt)
+        {
+          myError = BRepOffset_BadNormalsOnGeometry;
+          return Standard_False;
+        }
+        else
+          continue;
+      } //  if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
+
+      Standard_Real anAngle = aD1U.Angle(aD1V);
+      if ( Abs (anAngle) < Precision::Confusion())
+      {
+        myError = BRepOffset_BadNormalsOnGeometry;
+        return Standard_False;
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
+
+//=======================================================================
+//function : CheckInputData
+//purpose  : Check input data for possiblity of offset perform.
+//=======================================================================
+const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const
+{
+  return myBadShape;
+}
index 97acc216d067368dece91cdadfaa99e3442876ae..987ce26f3c6439c0c6c7b4f1b293cf6d2e5e9f23 100644 (file)
@@ -1031,7 +1031,38 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
     }
   else
     {
-    theCommands << "ERROR. offsetperform operation not done.";
+      // Return state of problem.
+      BRepOffset_Error anError = TheOffset.Error();
+
+      switch(anError)
+      {
+      case BRepOffset_BadNormalsOnGeometry:
+        {
+          theCommands << "ERROR. Degenerated normal on input data.";
+          break;
+        }
+      case BRepOffset_C0Geometry:
+        {
+          theCommands << "ERROR. C0 continuity of input data.";
+          break;
+        }
+      case BRepOffset_NullOffset:
+        {
+          theCommands << "ERROR. Null offset of all faces.";
+          break;
+        }
+      case BRepOffset_NotConnectedShell:
+        {
+          theCommands << "ERROR. Incorrect set of faces to remove, the remaining shell is not connected.";
+          break;
+        }
+
+      default:
+        {
+          theCommands << "ERROR. offsetperform operation not done.";
+          break;
+        }
+      }
     return 1;
     }
 
index c52710dab7b6481139346826f8fc0e2c1798ce22..b9a0b681afbacf871a6068bf98693c2774154e31 100755 (executable)
@@ -1,5 +1,5 @@
-puts "TODO OCC25916 ALL: \\*\\* Exception"
-puts "TODO OCC25916 ALL: An exception was caught"
+puts "TODO OCC25916 ALL: result is not a topological shape!!!"
+puts "TODO OCC25916 ALL: Error: object with name 'result' does not exist!"
 puts "TODO OCC25916 ALL: TEST INCOMPLETE"
 puts "========"
 puts "OCC21261"
index 40f2e6134fdc69d792c99eec58d16e3ab3c74522..ce0ba688016c752eeb9b7c7bfde1a644375744a6 100755 (executable)
@@ -1,5 +1,5 @@
-puts "TODO OCC25916 ALL: \\*\\* Exception"
-puts "TODO OCC25916 ALL: An exception was caught"
+puts "TODO OCC25916 ALL: result is not a topological shape!!!"
+puts "TODO OCC25916 ALL: Error: object with name 'result' does not exist!"
 puts "TODO OCC25916 ALL: TEST INCOMPLETE"
 puts "========"
 puts "OCC21261"
index 4c9ee74456ee8eaace41626830bd2d37b8709236..20a39da1a3305706f3b1b9456784954f5ff4626d 100644 (file)
@@ -1,5 +1,4 @@
-puts "TODO OCC23190 ALL: An exception was caugh.*Offset with no C1 Surface"
-puts "TODO OCC23190 ALL: \\*\\* Exception \\*\\*.*Offset with no C1 Surface"
+puts "TODO OCC23190 ALL: result is not a topological shape!!!"
 puts "TODO OCC23068 ALL: TEST INCOMPLETE"
 # Original bug : hkg60144/pro15325
 # Date : 17Juillet98
index 4d94a3b9bbf506872b1e8ba81ad8a8fb7561d332..f86361f201788b6d00f857593c250a69070f74dd 100644 (file)
@@ -1,5 +1,4 @@
-puts "TODO OCC23190 ALL: An exception was caught.*Offset with no C1 Surface"
-puts "TODO OCC23190 ALL: \\*\\* Exception \\*\\*.*Offset with no C1 Surface"
+puts "TODO OCC23190 ALL: result is not a topological shape!!!"
 puts "TODO OCC23068 ALL: TEST INCOMPLETE"
 # Original bug : cts21271
 # Date : 11Sept98