0030785: Mesh - protect BRepMesh_IncrementalMesh::Perform from raising exception
authoremv <emv@opencascade.com>
Mon, 17 Jun 2019 13:26:45 +0000 (16:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 20 Jun 2019 12:20:51 +0000 (15:20 +0300)
IMeshTools_ModelAlgo and IMeshTools_ModelBuilder have been changed to provide exception protected interfaces for performing the operations.
Protect single Edge/Face discretization methods from raising exceptions to skip broken Edges/Faces and allow mesh construction on the whole model.

17 files changed:
src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx
src/BRepMesh/BRepMesh_EdgeDiscret.cxx
src/BRepMesh/BRepMesh_EdgeDiscret.hxx
src/BRepMesh/BRepMesh_FaceDiscret.cxx
src/BRepMesh/BRepMesh_FaceDiscret.hxx
src/BRepMesh/BRepMesh_ModelBuilder.cxx
src/BRepMesh/BRepMesh_ModelBuilder.hxx
src/BRepMesh/BRepMesh_ModelHealer.cxx
src/BRepMesh/BRepMesh_ModelHealer.hxx
src/BRepMesh/BRepMesh_ModelPostProcessor.cxx
src/BRepMesh/BRepMesh_ModelPostProcessor.hxx
src/BRepMesh/BRepMesh_ModelPreProcessor.cxx
src/BRepMesh/BRepMesh_ModelPreProcessor.hxx
src/BRepMeshData/BRepMeshData_PCurve.cxx
src/IMeshTools/IMeshTools_ModelAlgo.hxx
src/IMeshTools/IMeshTools_ModelBuilder.hxx
tests/bugs/mesh/bug30785 [new file with mode: 0644]

index 8d4fd16..dce927a 100644 (file)
@@ -65,7 +65,7 @@ void BRepMesh_BaseMeshAlgo::Perform(
       commitSurfaceTriangulation();
     }
   }
-  catch (Standard_Failure& /*theExeption*/)
+  catch (Standard_Failure const& /*theExeption*/)
   {
   }
 
index 0d3258d..d9e575a 100644 (file)
@@ -83,7 +83,7 @@ Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellation
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Standard_Boolean BRepMesh_EdgeDiscret::Perform (
+Standard_Boolean BRepMesh_EdgeDiscret::performInternal (
   const Handle (IMeshData_Model)& theModel,
   const IMeshTools_Parameters&    theParameters)
 {
@@ -108,69 +108,78 @@ Standard_Boolean BRepMesh_EdgeDiscret::Perform (
 void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
 {
   const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
-  BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
-
-  Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
-  if (!aDEdge->IsFree ())
+  try
   {
-    // Iterate over pcurves and check deflection on corresponding face.
-    Standard_Real    aMinDeflection = RealLast ();
-    Standard_Integer aMinPCurveIndex = -1;
-    for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
+    OCC_CATCH_SIGNALS
+
+    BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
+  
+    Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
+    if (!aDEdge->IsFree ())
     {
-      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
-      const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
-      if (aTmpDeflection < aMinDeflection)
+      // Iterate over pcurves and check deflection on corresponding face.
+      Standard_Real    aMinDeflection = RealLast ();
+      Standard_Integer aMinPCurveIndex = -1;
+      for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
       {
-        // Identify pcurve with the smallest deflection in order to
-        // retrieve polygon that represents the most smooth discretization.
-        aMinDeflection  = aTmpDeflection;
-        aMinPCurveIndex = aPCurveIt;
+        const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
+        const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
+        if (aTmpDeflection < aMinDeflection)
+        {
+          // Identify pcurve with the smallest deflection in order to
+          // retrieve polygon that represents the most smooth discretization.
+          aMinDeflection  = aTmpDeflection;
+          aMinPCurveIndex = aPCurveIt;
+        }
+  
+        BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
       }
-
-      BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
-    }
-
-    if (aMinPCurveIndex != -1)
-    {
-      aDEdge->SetDeflection (aMinDeflection);
-      const IMeshData::IFaceHandle aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace();
-      aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
-    }
-    else
-    {
-      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
-      const IMeshData::IFaceHandle    aDFace  = aPCurve->GetFace();
-      aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
-        aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
-    }
-  }
-  else
-  {
-    TopLoc_Location aLoc;
-    const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
-    if (!aPoly3D.IsNull ())
-    {
-      if (aPoly3D->HasParameters () &&
-          aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
+  
+      if (aMinPCurveIndex != -1)
       {
-        // Edge already has suitable 3d polygon.
-        aDEdge->SetStatus(IMeshData_Reused);
-        return;
+        aDEdge->SetDeflection (aMinDeflection);
+        const IMeshData::IFaceHandle aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace();
+        aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
       }
       else
       {
-        aDEdge->SetStatus(IMeshData_Outdated);
+        const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+        const IMeshData::IFaceHandle    aDFace  = aPCurve->GetFace();
+        aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+          aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
       }
     }
-
-    aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
+    else
+    {
+      TopLoc_Location aLoc;
+      const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
+      if (!aPoly3D.IsNull ())
+      {
+        if (aPoly3D->HasParameters () &&
+            aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
+        {
+          // Edge already has suitable 3d polygon.
+          aDEdge->SetStatus(IMeshData_Reused);
+          return;
+        }
+        else
+        {
+          aDEdge->SetStatus(IMeshData_Outdated);
+        }
+      }
+  
+      aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
+    }
+  
+    Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
+    if (!aDEdge->IsFree())
+    {
+      Tessellate2d(aDEdge, Standard_True);
+    }
   }
-
-  Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
-  if (!aDEdge->IsFree())
+  catch (Standard_Failure const&)
   {
-    Tessellate2d(aDEdge, Standard_True);
+    aDEdge->SetStatus (IMeshData_Failure);
   }
 }
 
index 0793d01..82ac8e4 100644 (file)
@@ -52,11 +52,6 @@ public:
     const IMeshData::IEdgeHandle& theDEdge,
     const IMeshData::IFaceHandle& theDFace);
 
-  //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform (
-    const Handle (IMeshData_Model)& theModel,
-    const IMeshTools_Parameters&    theParameters) Standard_OVERRIDE;
-
   //! Functor API to discretize the given edge.
   inline void operator() (const Standard_Integer theEdgeIndex) const {
     process (theEdgeIndex);
@@ -75,6 +70,13 @@ public:
 
   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
 
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) Standard_OVERRIDE;
+
 private:
 
   //! Checks existing discretization of the edge and updates data model.
index 5a0688b..ce6db21 100644 (file)
@@ -43,7 +43,7 @@ BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret()
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Standard_Boolean BRepMesh_FaceDiscret::Perform(
+Standard_Boolean BRepMesh_FaceDiscret::performInternal(
   const Handle(IMeshData_Model)& theModel,
   const IMeshTools_Parameters&   theParameters)
 {
@@ -73,14 +73,23 @@ void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
     return;
   }
 
-  Handle(IMeshTools_MeshAlgo) aMeshingAlgo = 
-    myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
+  try
+  {
+    OCC_CATCH_SIGNALS
 
-  if (aMeshingAlgo.IsNull())
+    Handle(IMeshTools_MeshAlgo) aMeshingAlgo = 
+      myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
+  
+    if (aMeshingAlgo.IsNull())
+    {
+      aDFace->SetStatus(IMeshData_Failure);
+      return;
+    }
+  
+    aMeshingAlgo->Perform(aDFace, myParameters);
+  }
+  catch (Standard_Failure const&)
   {
-    aDFace->SetStatus(IMeshData_Failure);
-    return;
+    aDFace->SetStatus (IMeshData_Failure);
   }
-
-  aMeshingAlgo->Perform(aDFace, myParameters);
 }
index cf706cb..9ca8680 100644 (file)
@@ -23,7 +23,7 @@
 
 //! Class implements functionality starting triangulation of model's faces.
 //! Each face is processed separately and can be executed in parallel mode.
-//! Uses mesh algo factory passed as initializer to create instace of triangulation 
+//! Uses mesh algo factory passed as initializer to create instance of triangulation 
 //! algorithm according to type of surface of target face.
 class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
 {
@@ -36,11 +36,6 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_FaceDiscret();
 
-  //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform(
-    const Handle(IMeshData_Model)& theModel,
-    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
-
   //! Functor API to discretize the given edge.
   inline void operator() (const Standard_Integer theFaceIndex) const {
     process(theFaceIndex);
@@ -48,6 +43,13 @@ public:
 
   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo)
 
+protected:
+
+  //! Performs processing of faces of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
 private:
 
   //! Checks existing discretization of the face and updates data model.
index dd9c3be..1a15482 100644 (file)
@@ -18,7 +18,6 @@
 #include <BRepMesh_ShapeVisitor.hxx>
 #include <BRepMesh_ShapeTool.hxx>
 #include <IMeshTools_ShapeExplorer.hxx>
-#include <Standard_ErrorHandler.hxx>
 
 #include <Bnd_Box.hxx>
 #include <BRepBndLib.hxx>
@@ -43,52 +42,42 @@ BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder ()
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
+Handle (IMeshData_Model) BRepMesh_ModelBuilder::performInternal (
   const TopoDS_Shape&          theShape,
   const IMeshTools_Parameters& theParameters)
 {
-  ClearStatus ();
-
   Handle (BRepMeshData_Model) aModel;
-  try
-  {
-    OCC_CATCH_SIGNALS
-
-    Bnd_Box aBox;
-    BRepBndLib::Add (theShape, aBox, Standard_False);
-
-    if (!aBox.IsVoid ())
-    {
-      // Build data model for further processing.
-      aModel = new BRepMeshData_Model (theShape);
 
-      if (theParameters.Relative)
-      {
-        Standard_Real aMaxSize;
-        BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
-        aModel->SetMaxSize(aMaxSize);
-      }
-      else
-      {
-        aModel->SetMaxSize(Max(theParameters.Deflection,
-                               theParameters.DeflectionInterior));
-      }
+  Bnd_Box aBox;
+  BRepBndLib::Add (theShape, aBox, Standard_False);
 
-      Handle (IMeshTools_ShapeVisitor) aVisitor =
-        new BRepMesh_ShapeVisitor (aModel);
+  if (!aBox.IsVoid ())
+  {
+    // Build data model for further processing.
+    aModel = new BRepMeshData_Model (theShape);
 
-      IMeshTools_ShapeExplorer aExplorer (theShape);
-      aExplorer.Accept (aVisitor);
-      SetStatus (Message_Done1);
+    if (theParameters.Relative)
+    {
+      Standard_Real aMaxSize;
+      BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
+      aModel->SetMaxSize(aMaxSize);
     }
     else
     {
-      SetStatus(Message_Fail1);
+      aModel->SetMaxSize(Max(theParameters.Deflection,
+                             theParameters.DeflectionInterior));
     }
+
+    Handle (IMeshTools_ShapeVisitor) aVisitor =
+      new BRepMesh_ShapeVisitor (aModel);
+
+    IMeshTools_ShapeExplorer aExplorer (theShape);
+    aExplorer.Accept (aVisitor);
+    SetStatus (Message_Done1);
   }
-  catch (Standard_Failure&)
+  else
   {
-    SetStatus (Message_Fail2);
+    SetStatus (Message_Fail1);
   }
 
   return aModel;
index aa1850a..56898a1 100644 (file)
@@ -36,13 +36,15 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_ModelBuilder ();
 
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
+
+protected:
+
   //! Creates discrete model for the given shape.
   //! Returns nullptr in case of failure.
-  Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+  Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
     const TopoDS_Shape&          theShape,
     const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
-
-  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
 };
 
 #endif
\ No newline at end of file
index 5450b31..76e6f7f 100644 (file)
@@ -115,7 +115,7 @@ BRepMesh_ModelHealer::~BRepMesh_ModelHealer()
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Standard_Boolean BRepMesh_ModelHealer::Perform(
+Standard_Boolean BRepMesh_ModelHealer::performInternal(
   const Handle(IMeshData_Model)& theModel,
   const IMeshTools_Parameters&   theParameters)
 {
@@ -226,22 +226,31 @@ Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate(
 //=======================================================================
 void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
 {
-  Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
-  aIntersections.Nullify();
-
-  fixFaceBoundaries(theDFace);
-
-  if (!theDFace->IsSet(IMeshData_Failure))
+  try
   {
-    BRepMesh_FaceChecker aChecker(theDFace, myParameters);
-    if (!aChecker.Perform())
+    OCC_CATCH_SIGNALS
+
+    Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
+    aIntersections.Nullify();
+  
+    fixFaceBoundaries(theDFace);
+  
+    if (!theDFace->IsSet(IMeshData_Failure))
     {
+      BRepMesh_FaceChecker aChecker(theDFace, myParameters);
+      if (!aChecker.Perform())
+      {
 #ifdef DEBUG_HEALER
-      std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
+        std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
 #endif
-      aIntersections = aChecker.GetIntersectingEdges();
+        aIntersections = aChecker.GetIntersectingEdges();
+      }
     }
   }
+  catch (Standard_Failure const&)
+  {
+    theDFace->SetStatus (IMeshData_Failure);
+  }
 }
 
 //=======================================================================
index 5fab250..14d804e 100644 (file)
@@ -44,11 +44,6 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_ModelHealer();
 
-  //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform(
-    const Handle(IMeshData_Model)& theModel,
-    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
-
   //! Functor API to discretize the given edge.
   inline void operator() (const Standard_Integer theEdgeIndex) const {
     process(theEdgeIndex);
@@ -61,6 +56,13 @@ public:
 
   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
 
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
 private:
 
   //! Checks existing discretization of the face and updates data model.
index 231558f..2315051 100644 (file)
@@ -177,7 +177,7 @@ BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Standard_Boolean BRepMesh_ModelPostProcessor::Perform(
+Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
   const Handle(IMeshData_Model)& theModel,
   const IMeshTools_Parameters&   /*theParameters*/)
 {
index d475369..129ba74 100644 (file)
@@ -32,12 +32,14 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor();
 
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
+
+protected:
+
   //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform(
+  Standard_EXPORT virtual Standard_Boolean performInternal (
     const Handle(IMeshData_Model)& theModel,
     const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
-
-  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
 };
 
 #endif
index 7ec3d40..c9d02d4 100644 (file)
@@ -242,7 +242,7 @@ BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
 // Function: Perform
 // Purpose : 
 //=======================================================================
-Standard_Boolean BRepMesh_ModelPreProcessor::Perform(
+Standard_Boolean BRepMesh_ModelPreProcessor::performInternal(
   const Handle(IMeshData_Model)& theModel,
   const IMeshTools_Parameters&   theParameters)
 {
index 213d8f8..031053a 100644 (file)
@@ -33,12 +33,14 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor();
 
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
+
+protected:
+
   //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform(
+  Standard_EXPORT virtual Standard_Boolean performInternal (
     const Handle(IMeshData_Model)& theModel,
     const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
-
-  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
 };
 
 #endif
index 53608a7..4c03911 100644 (file)
@@ -17,6 +17,7 @@
 #include <gp_Pnt2d.hxx>
 #include <BRepMesh_OrientedEdge.hxx>
 #include <BRepMesh_Vertex.hxx>
+#include <Standard_OutOfRange.hxx>
 
 //=======================================================================
 // Function: Constructor
@@ -74,6 +75,9 @@ void BRepMeshData_PCurve::AddPoint (
 //=======================================================================
 gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
 {
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myPoints2d.size()),
+    "BRepMeshData_PCurve::GetPoint");
   return myPoints2d[theIndex];
 }
 
@@ -83,6 +87,9 @@ gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
 //=======================================================================
 Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
 {
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myIndices.size()),
+    "BRepMeshData_PCurve::GetIndex");
   return myIndices[theIndex];
 }
 
@@ -92,6 +99,9 @@ Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
 //=======================================================================
 Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
 {
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= ParametersNb(),
+    "BRepMeshData_PCurve::GetParameter");
   return myParameters[theIndex];
 }
 
index 7e378dc..963c880 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef _IMeshTools_ModelAlgo_HeaderFile
 #define _IMeshTools_ModelAlgo_HeaderFile
 
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
 #include <Standard_Transient.hxx>
 #include <Standard_Type.hxx>
 
@@ -32,10 +34,22 @@ public:
   {
   }
 
-  //! Performs processing of edges of the given model.
-  Standard_EXPORT virtual Standard_Boolean Perform (
+  //! Exceptions protected processing of the given model.
+  Standard_Boolean Perform (
     const Handle (IMeshData_Model)& theModel,
-    const IMeshTools_Parameters&    theParameters) = 0;
+    const IMeshTools_Parameters&    theParameters)
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      return performInternal (theModel, theParameters);
+    }
+    catch (Standard_Failure const&)
+    {
+      return Standard_False;
+    }
+  }
 
   DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
 
@@ -45,6 +59,11 @@ protected:
   Standard_EXPORT IMeshTools_ModelAlgo()
   {
   }
+
+  //! Performs processing of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) = 0;
 };
 
 #endif
\ No newline at end of file
index 1dcdc3d..5d6d416 100644 (file)
@@ -17,6 +17,8 @@
 #define _IMeshTools_ModelBuilder_HeaderFile
 
 #include <Message_Algorithm.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
 #include <Standard_Type.hxx>
 #include <TopoDS_Shape.hxx>
 
@@ -38,11 +40,26 @@ public:
   {
   }
 
-  //! Creates discrete model for the given shape.
+  //! Exceptions protected method to create discrete model for the given shape.
   //! Returns nullptr in case of failure.
-  Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+  Handle (IMeshData_Model) Perform (
     const TopoDS_Shape&          theShape,
-    const IMeshTools_Parameters& theParameters) = 0;
+    const IMeshTools_Parameters& theParameters)
+  {
+    ClearStatus ();
+
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      return performInternal (theShape, theParameters);
+    }
+    catch (Standard_Failure const&)
+    {
+      SetStatus (Message_Fail2);
+      return NULL;
+    }
+  }
 
   DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
 
@@ -52,6 +69,12 @@ protected:
   Standard_EXPORT IMeshTools_ModelBuilder()
   {
   }
+
+  //! Creates discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters) = 0;
 };
 
 #endif
\ No newline at end of file
diff --git a/tests/bugs/mesh/bug30785 b/tests/bugs/mesh/bug30785
new file mode 100644 (file)
index 0000000..4280d91
--- /dev/null
@@ -0,0 +1,15 @@
+puts "========="
+puts "0030785: Mesh - protect BRepMesh_IncrementalMesh::Perform from crash"
+puts "========="
+puts ""
+
+puts "REQUIRED All: Failure"
+
+restore [locate_data_file bug30785.brep] s
+
+# just check if the exception is not raised
+if {[catch {incmesh s 0.1}]} {
+  puts "Error: Exception is raised by BRepMesh_IncrementalMesh"
+}
+
+checktrinfo s -tri