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

0032424: [Regression] Mesh - Slow triangulation of a simple shape.

This commit is contained in:
rnv
2021-07-22 13:33:11 +03:00
parent 33d9a6fa21
commit 5457eade20

View File

@@ -34,7 +34,9 @@ public:
//! Constructor. //! Constructor.
BRepMesh_DelaunayDeflectionControlMeshAlgo() BRepMesh_DelaunayDeflectionControlMeshAlgo()
: myMaxSqDeflection(-1.), : myMaxSqDeflection(-1.),
myIsAllDegenerated(Standard_False) mySqMinSize(-1.),
myIsAllDegenerated(Standard_False),
myCircles(NULL)
{ {
} }
@@ -65,6 +67,7 @@ protected:
Handle(NCollection_IncAllocator) aTmpAlloc = Handle(NCollection_IncAllocator) aTmpAlloc =
new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE); new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
mySqMinSize = this->getParameters().MinSize * this->getParameters().MinSize;
myCouplesMap = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc); myCouplesMap = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc);
myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc); myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
myCircles = &theMesher.Circles(); myCircles = &theMesher.Circles();
@@ -318,22 +321,38 @@ private:
if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point, if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point,
theNodesInfo[j].Point))) theNodesInfo[j].Point)))
{ {
if (!checkLinkEndsForAngularDeviation(theNodesInfo[i], if (!rejectSplitLinksForMinSize (theNodesInfo[i],
theNodesInfo[j], theNodesInfo[j],
aMidPnt2d)) aMidPnt2d))
{ {
myControlNodes->Append(aMidPnt2d); if (!checkLinkEndsForAngularDeviation (theNodesInfo[i],
theNodesInfo[j],
aMidPnt2d))
{
myControlNodes->Append(aMidPnt2d);
}
} }
} }
} }
} }
} }
//! Checks that two links produced as the result of a split of
//! the given link by the middle point fit MinSize requirement.
Standard_Boolean rejectSplitLinksForMinSize (const TriangleNodeInfo& theNodeInfo1,
const TriangleNodeInfo& theNodeInfo2,
const gp_XY& theMidPoint)
{
const gp_Pnt aPnt = getPoint3d (theMidPoint);
return ((theNodeInfo1.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize ||
(theNodeInfo2.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize);
}
//! Checks the given point (located between the given nodes) //! Checks the given point (located between the given nodes)
//! for specified angular deviation. //! for specified angular deviation.
Standard_Boolean checkLinkEndsForAngularDeviation(const TriangleNodeInfo& theNodeInfo1, Standard_Boolean checkLinkEndsForAngularDeviation(const TriangleNodeInfo& theNodeInfo1,
const TriangleNodeInfo& theNodeInfo2, const TriangleNodeInfo& theNodeInfo2,
const gp_XY& /*theMidPoint*/) const gp_XY& /*theMidPoint*/)
{ {
gp_Dir aNorm1, aNorm2; gp_Dir aNorm1, aNorm2;
const Handle(Geom_Surface)& aSurf = const Handle(Geom_Surface)& aSurf =
@@ -344,7 +363,9 @@ private:
{ {
Standard_Real anAngle = aNorm1.Angle(aNorm2); Standard_Real anAngle = aNorm1.Angle(aNorm2);
if (anAngle > this->getParameters().AngleInterior) if (anAngle > this->getParameters().AngleInterior)
{
return Standard_False; return Standard_False;
}
} }
#if 0 #if 0
else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0) else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0)
@@ -360,6 +381,14 @@ private:
return Standard_True; return Standard_True;
} }
//! Returns 3d point corresponding to the given one in 2d space.
gp_Pnt getPoint3d (const gp_XY& thePnt2d)
{
gp_Pnt aPnt;
this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
return aPnt;
}
//! Computes deflection of the given point and caches it for //! Computes deflection of the given point and caches it for
//! insertion in case if it overflows deflection. //! insertion in case if it overflows deflection.
//! @return True if point has been cached for insertion. //! @return True if point has been cached for insertion.
@@ -368,8 +397,7 @@ private:
const gp_XY& thePnt2d, const gp_XY& thePnt2d,
const DeflectionFunctor& theDeflectionFunctor) const DeflectionFunctor& theDeflectionFunctor)
{ {
gp_Pnt aPnt; const gp_Pnt aPnt = getPoint3d (thePnt2d);
this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt))) if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
{ {
myControlNodes->Append(thePnt2d); myControlNodes->Append(thePnt2d);
@@ -401,14 +429,14 @@ private:
return rejectByMinSize(thePnt2d, thePnt3d); return rejectByMinSize(thePnt2d, thePnt3d);
} }
//! Checks the given node for //! Checks distance between the given node and nodes of triangles
//! shot by it for MinSize criteria.
//! This check is expected to roughly estimate and prevent
//! generation of triangles with sides smaller than MinSize.
Standard_Boolean rejectByMinSize( Standard_Boolean rejectByMinSize(
const gp_XY& thePnt2d, const gp_XY& thePnt2d,
const gp_Pnt& thePnt3d) const gp_Pnt& thePnt3d)
{ {
const Standard_Real aSqMinSize =
this->getParameters().MinSize * this->getParameters().MinSize;
IMeshData::MapOfInteger aUsedNodes; IMeshData::MapOfInteger aUsedNodes;
IMeshData::ListOfInteger& aCirclesList = IMeshData::ListOfInteger& aCirclesList =
const_cast<BRepMesh_CircleTool&>(*myCircles).Select( const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
@@ -430,7 +458,7 @@ private:
const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]); const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d()); const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
if (thePnt3d.SquareDistance(aPoint) < aSqMinSize) if (thePnt3d.SquareDistance(aPoint) < mySqMinSize)
{ {
return Standard_True; return Standard_True;
} }
@@ -443,6 +471,7 @@ private:
private: private:
Standard_Real myMaxSqDeflection; Standard_Real myMaxSqDeflection;
Standard_Real mySqMinSize;
Standard_Boolean myIsAllDegenerated; Standard_Boolean myIsAllDegenerated;
Handle(IMeshData::MapOfOrientedEdges) myCouplesMap; Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
Handle(IMeshData::ListOfPnt2d) myControlNodes; Handle(IMeshData::ListOfPnt2d) myControlNodes;