1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0030785: Mesh - protect BRepMesh_IncrementalMesh::Perform from raising exception

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.
This commit is contained in:
emv
2019-06-17 16:26:45 +03:00
committed by bugmaster
parent fe525c6f7c
commit c2a25d522b
17 changed files with 235 additions and 140 deletions

View File

@@ -65,7 +65,7 @@ void BRepMesh_BaseMeshAlgo::Perform(
commitSurfaceTriangulation();
}
}
catch (Standard_Failure& /*theExeption*/)
catch (Standard_Failure const& /*theExeption*/)
{
}

View 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);
}
}

View 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.

View 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);
if (aMeshingAlgo.IsNull())
try
{
aDFace->SetStatus(IMeshData_Failure);
return;
}
OCC_CATCH_SIGNALS
aMeshingAlgo->Perform(aDFace, myParameters);
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);
}
}

View 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.

View 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
Bnd_Box aBox;
BRepBndLib::Add (theShape, aBox, Standard_False);
if (!aBox.IsVoid ())
{
OCC_CATCH_SIGNALS
// Build data model for further processing.
aModel = new BRepMeshData_Model (theShape);
Bnd_Box aBox;
BRepBndLib::Add (theShape, aBox, Standard_False);
if (!aBox.IsVoid ())
if (theParameters.Relative)
{
// 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));
}
Handle (IMeshTools_ShapeVisitor) aVisitor =
new BRepMesh_ShapeVisitor (aModel);
IMeshTools_ShapeExplorer aExplorer (theShape);
aExplorer.Accept (aVisitor);
SetStatus (Message_Done1);
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;

View 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

View 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);
}
}
//=======================================================================

View 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.

View 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*/)
{

View 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

View 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)
{

View 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