From: rnv Date: Thu, 22 Jul 2021 10:33:11 +0000 (+0300) Subject: 0032424: [Regression] Mesh - Slow triangulation of a simple shape. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR740-SALOME-PATCH-1;p=occt-copy.git 0032424: [Regression] Mesh - Slow triangulation of a simple shape. --- diff --git a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx index 04f4708d66..85e37ebaf1 100644 --- a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx +++ b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx @@ -34,7 +34,9 @@ public: //! Constructor. BRepMesh_DelaunayDeflectionControlMeshAlgo() : myMaxSqDeflection(-1.), - myIsAllDegenerated(Standard_False) + mySqMinSize(-1.), + myIsAllDegenerated(Standard_False), + myCircles(NULL) { } @@ -65,10 +67,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; for (Standard_Integer aPass = 1; aPass <= aIterationsNb && isInserted && !myIsAllDegenerated; ++aPass) @@ -318,22 +321,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 = @@ -344,7 +363,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) @@ -360,6 +381,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. @@ -368,8 +397,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); @@ -401,14 +429,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(*myCircles).Select( @@ -430,7 +458,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; } @@ -443,6 +471,7 @@ private: private: Standard_Real myMaxSqDeflection; + Standard_Real mySqMinSize; Standard_Boolean myIsAllDegenerated; Handle(IMeshData::MapOfOrientedEdges) myCouplesMap; Handle(IMeshData::ListOfPnt2d) myControlNodes;