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

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

Check links produced by splitting of an initial link by the middle point for MinSize requirement.
This commit is contained in:
oan
2021-07-08 13:07:05 +03:00
committed by bugmaster
parent 06d40093b7
commit 9ee9e5ec34
20 changed files with 78 additions and 32 deletions

View File

@@ -34,6 +34,7 @@ public:
//! Constructor.
BRepMesh_DelaunayDeflectionControlMeshAlgo()
: myMaxSqDeflection(-1.),
mySqMinSize(-1.),
myIsAllDegenerated(Standard_False),
myCircles(NULL)
{
@@ -77,10 +78,11 @@ protected:
Handle(NCollection_IncAllocator) aTmpAlloc =
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);
myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
myCircles = &theMesher.Circles();
const Standard_Integer aIterationsNb = 11;
Standard_Boolean isInserted = Standard_True;
Message_ProgressScope aPS(theRange, "Iteration", aIterationsNb);
@@ -339,22 +341,38 @@ private:
if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point,
theNodesInfo[j].Point)))
{
if (!checkLinkEndsForAngularDeviation(theNodesInfo[i],
theNodesInfo[j],
aMidPnt2d))
if (!rejectSplitLinksForMinSize (theNodesInfo[i],
theNodesInfo[j],
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)
//! for specified angular deviation.
Standard_Boolean checkLinkEndsForAngularDeviation(const TriangleNodeInfo& theNodeInfo1,
const TriangleNodeInfo& theNodeInfo2,
const gp_XY& /*theMidPoint*/)
const gp_XY& /*theMidPoint*/)
{
gp_Dir aNorm1, aNorm2;
const Handle(Geom_Surface)& aSurf = this->getDFace()->GetSurface()->Surface().Surface();
@@ -364,7 +382,9 @@ private:
{
Standard_Real anAngle = aNorm1.Angle(aNorm2);
if (anAngle > this->getParameters().AngleInterior)
{
return Standard_False;
}
}
#if 0
else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0)
@@ -380,6 +400,14 @@ private:
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
//! insertion in case if it overflows deflection.
//! @return True if point has been cached for insertion.
@@ -388,8 +416,7 @@ private:
const gp_XY& thePnt2d,
const DeflectionFunctor& theDeflectionFunctor)
{
gp_Pnt aPnt;
this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
const gp_Pnt aPnt = getPoint3d (thePnt2d);
if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
{
myControlNodes->Append(thePnt2d);
@@ -421,14 +448,14 @@ private:
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(
const gp_XY& thePnt2d,
const gp_Pnt& thePnt3d)
{
const Standard_Real aSqMinSize =
this->getParameters().MinSize * this->getParameters().MinSize;
IMeshData::MapOfInteger aUsedNodes;
IMeshData::ListOfInteger& aCirclesList =
const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
@@ -450,7 +477,7 @@ private:
const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
if (thePnt3d.SquareDistance(aPoint) < aSqMinSize)
if (thePnt3d.SquareDistance(aPoint) < mySqMinSize)
{
return Standard_True;
}
@@ -463,6 +490,7 @@ private:
private:
Standard_Real myMaxSqDeflection;
Standard_Real mySqMinSize;
Standard_Boolean myIsAllDegenerated;
Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
Handle(IMeshData::ListOfPnt2d) myControlNodes;