mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
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.
185 lines
6.9 KiB
C++
185 lines
6.9 KiB
C++
// 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 face’s 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 |