1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/BRepMesh/BRepMesh_ModelHealer.hxx
emv c2a25d522b 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.
2019-06-20 15:20:51 +03:00

185 lines
6.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Created on: 2016-06-23
// Copyright (c) 2016 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_ModelHealer_HeaderFile
#define _BRepMesh_ModelHealer_HeaderFile
#include <IMeshTools_ModelAlgo.hxx>
#include <IMeshTools_Parameters.hxx>
#include <IMeshData_Types.hxx>
#include <IMeshData_Model.hxx>
#include <TopoDS_Vertex.hxx>
//! Class implements functionality of model healer tool.
//! Iterates over model's faces and checks consistency of their wires,
//! i.e.whether wires are closed and do not contain self - intersections.
//! In case if wire contains disconnected parts, ends of adjacent edges
//! forming the gaps are connected in parametric space forcibly. The notion
//! of this operation is to create correct discrete model defined relatively
//! parametric space of target face taking into account connectivity and
//! tolerances of 3D space only. This means that there are no specific
//! computations are made for the sake of determination of U and V tolerance.
//! Registers intersections on edges forming the faces shape and tries to
//! amplify discrete represenation by decreasing of deflection for the target edge.
//! Checks can be performed in parallel mode.
class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_ModelHealer();
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_ModelHealer();
//! Functor API to discretize the given edge.
inline void operator() (const Standard_Integer theEdgeIndex) const {
process(theEdgeIndex);
}
//! Functor API to discretize the given edge.
inline void operator() (const IMeshData::IFaceHandle& theDFace) const {
process(theDFace);
}
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.
inline void process(const Standard_Integer theFaceIndex) const
{
const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
process(aDFace);
}
//! Checks existing discretization of the face and updates data model.
void process(const IMeshData::IFaceHandle& theDFace) const;
//! Amplifies discretization of edges in case if self-intersection problem has been found.
void amplifyEdges();
//! Returns common vertex of two edges or null ptr in case if there is no such vertex.
TopoDS_Vertex getCommonVertex(
const IMeshData::IEdgeHandle& theEdge1,
const IMeshData::IEdgeHandle& theEdge2) const;
//! Connects pcurves of previous and current edge on the specified face
//! according to topological connectivity. Uses next edge in order to
//! identify closest point in case of signle vertex shared between both
//! ends of edge (degenerative edge)
Standard_Boolean connectClosestPoints(
const IMeshData::IPCurveHandle& thePrevDEdge,
const IMeshData::IPCurveHandle& theCurrDEdge,
const IMeshData::IPCurveHandle& theNextDEdge) const;
//! Chooses the most closest point to reference one from the given pair.
//! Returns square distance between reference point and closest one as
//! well as pointer to closest point.
inline Standard_Real closestPoint(
gp_Pnt2d& theRefPnt,
gp_Pnt2d& theFristPnt,
gp_Pnt2d& theSecondPnt,
gp_Pnt2d*& theClosestPnt) const
{
// Find the most closest end-points.
const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
if (aSqDist1 < aSqDist2)
{
theClosestPnt = &theFristPnt;
return aSqDist1;
}
theClosestPnt = &theSecondPnt;
return aSqDist2;
}
//! Chooses the most closest points among the given to reference one from the given pair.
//! Returns square distance between reference point and closest one as
//! well as pointer to closest point.
inline Standard_Real closestPoints(
gp_Pnt2d& theFirstPnt1,
gp_Pnt2d& theSecondPnt1,
gp_Pnt2d& theFirstPnt2,
gp_Pnt2d& theSecondPnt2,
gp_Pnt2d*& theClosestPnt1,
gp_Pnt2d*& theClosestPnt2) const
{
gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL;
const Standard_Real aSqDist1 = closestPoint(theFirstPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
if (aSqDist1 - aSqDist2 < gp::Resolution())
{
theClosestPnt1 = &theFirstPnt1;
theClosestPnt2 = aCurrPrevUV1;
return aSqDist1;
}
theClosestPnt1 = &theSecondPnt1;
theClosestPnt2 = aCurrPrevUV2;
return aSqDist2;
}
//! Adjusts the given pair of points supposed to be the same.
//! In addition, adjusts another end-point of an edge in order
//! to perform correct matching in case of gap.
inline void adjustSamePoints(
gp_Pnt2d*& theMajorSamePnt1,
gp_Pnt2d*& theMinorSamePnt1,
gp_Pnt2d*& theMajorSamePnt2,
gp_Pnt2d*& theMinorSamePnt2,
gp_Pnt2d& theMajorFirstPnt,
gp_Pnt2d& theMajorLastPnt,
gp_Pnt2d& theMinorFirstPnt,
gp_Pnt2d& theMinorLastPnt) const
{
if (theMajorSamePnt2 == theMajorSamePnt1)
{
theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
}
*theMajorSamePnt1 = *theMinorSamePnt1;
*theMajorSamePnt2 = *theMinorSamePnt2;
}
//! Connects ends of pcurves of face's wires according to topological coherency.
void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
//! Returns True if check can be done in parallel.
inline Standard_Boolean isParallel() const
{
return (myParameters.InParallel && myModel->FacesNb() > 1);
}
//! Collects unique edges to be updated from face map. Clears data stored in face map.
Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
private:
Handle(IMeshData_Model) myModel;
IMeshTools_Parameters myParameters;
Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs) myFaceIntersectingEdges;
};
#endif