From 4097ab152e422a3deb41835b87e592197ba44d7c Mon Sep 17 00:00:00 2001 From: akaftasev Date: Wed, 15 Jul 2020 17:23:32 +0300 Subject: [PATCH] 0025113: Added progress indicator to BRepMesh_IncrementalMesh [backport for OCCT 7.2.0] --- src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx | 5 +- src/BRepMesh/BRepMesh_Delaun.cxx | 84 +++++++++++++- src/BRepMesh/BRepMesh_Delaun.hxx | 16 +++ src/BRepMesh/BRepMesh_FastDiscret.cxx | 17 ++- src/BRepMesh/BRepMesh_FastDiscret.hxx | 7 ++ src/BRepMesh/BRepMesh_FastDiscretFace.cxx | 77 +++++++++++-- src/BRepMesh/BRepMesh_FastDiscretFace.hxx | 15 ++- src/BRepMesh/BRepMesh_IncrementalMesh.cxx | 132 +++++++++++++++++++--- src/BRepMesh/BRepMesh_IncrementalMesh.hxx | 13 ++- src/BRepMesh/BRepMesh_Status.hxx | 3 +- src/MeshTest/MeshTest.cxx | 12 +- 11 files changed, 335 insertions(+), 46 deletions(-) diff --git a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx index c63a53875c..6e8a00b3d5 100644 --- a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx +++ b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx @@ -69,4 +69,7 @@ static const char BOPAlgo_BOPAlgo_msg[] = "Warning: Removal of internal boundaries among Faces has failed\n" "\n" ".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n" - "Warning: Removal of internal boundaries among Edges has failed\n"; + "Warning: Removal of internal boundaries among Edges has failed\n" + "\n" + ".BOPAlgo_AlertSolidBuilderUnusedFaces\n" + "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"; diff --git a/src/BRepMesh/BRepMesh_Delaun.cxx b/src/BRepMesh/BRepMesh_Delaun.cxx index 62ff759122..26d3fce6ea 100644 --- a/src/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/BRepMesh/BRepMesh_Delaun.cxx @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -304,6 +305,17 @@ void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes) //======================================================================= void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex, BRepMesh::MapOfIntegerInteger& thePoly) +{ + createTriangles (theVertexIndex, thePoly, NULL); +} + +//======================================================================= +//function : createTriangles +//purpose : Creates the triangles beetween the node and the polyline. +//======================================================================= +void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex, + BRepMesh::MapOfIntegerInteger& thePoly, + Message_ProgressSentry* theProgressEntry) { BRepMesh::ListOfInteger aLoopEdges, anExternalEdges; const gp_XY& aVertexCoord = myMeshData->GetNode( theVertexIndex ).Coord(); @@ -311,6 +323,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn BRepMesh::MapOfIntegerInteger::Iterator anEdges( thePoly ); for ( ; anEdges.More(); anEdges.Next() ) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } Standard_Integer anEdgeId = anEdges.Key(); const BRepMesh_Edge& anEdge = GetEdge( anEdgeId ); @@ -408,6 +424,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn while ( !aLoopEdges.IsEmpty() ) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } const BRepMesh_Edge& anEdge = GetEdge( Abs( aLoopEdges.First() ) ); if ( anEdge.Movability() != BRepMesh_Deleted ) { @@ -425,6 +445,17 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn //======================================================================= void BRepMesh_Delaun::createTrianglesOnNewVertices( BRepMesh::Array1OfInteger& theVertexIndexes) +{ + createTrianglesOnNewVertices (theVertexIndexes, NULL); +} + +//======================================================================= +//function : createTrianglesOnNewVertices +//purpose : Creation of triangles from the new nodes +//======================================================================= +void BRepMesh_Delaun::createTrianglesOnNewVertices( + BRepMesh::Array1OfInteger& theVertexIndexes, + Message_ProgressSentry* theProgressEntry) { Handle(NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); @@ -440,6 +471,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices( Standard_Integer anUpper = theVertexIndexes.Upper(); for( ; anIndex <= anUpper; ++anIndex ) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + aAllocator->Reset(Standard_False); BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator); @@ -483,6 +519,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices( isModify = Standard_True; while ( isModify && !aCirclesList.IsEmpty() ) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + isModify = Standard_False; BRepMesh::ListOfInteger::Iterator aCircleIt1( aCirclesList ); for ( ; aCircleIt1.More(); aCircleIt1.Next() ) @@ -503,13 +544,25 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices( } } + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } // Creation of triangles with the current node and free edges // and removal of these edges from the list of free edges - createTriangles( aVertexIdx, aLoopEdges ); + createTriangles( aVertexIdx, aLoopEdges, theProgressEntry ); } } + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } - insertInternalEdges(); + insertInternalEdges (theProgressEntry); + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } // Adjustment of meshes to boundary edges frontierAdjust(); @@ -520,6 +573,15 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices( //purpose : //======================================================================= void BRepMesh_Delaun::insertInternalEdges() +{ + insertInternalEdges (NULL); +} + +//======================================================================= +//function : insertInternalEdges +//purpose : +//======================================================================= +void BRepMesh_Delaun::insertInternalEdges (Message_ProgressSentry* theProgressEntry) { BRepMesh::HMapOfInteger anInternalEdges = InternalEdges(); @@ -530,6 +592,11 @@ void BRepMesh_Delaun::insertInternalEdges() BRepMesh::MapOfInteger::Iterator anInernalEdgesIt( *anInternalEdges ); for ( ; anInernalEdgesIt.More(); anInernalEdgesIt.Next() ) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + const Standard_Integer aLinkIndex = anInernalEdgesIt.Key(); const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(aLinkIndex); @@ -2094,12 +2161,21 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex ) } } - //======================================================================= //function : AddVertices //purpose : Adds some vertices in the triangulation. //======================================================================= void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices) +{ + AddVertices (theVertices, NULL); +} + +//======================================================================= +//function : AddVertices +//purpose : Adds some vertices in the triangulation. +//======================================================================= +void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices, + Message_ProgressSentry* theProgressEntry) { std::make_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun()); std::sort_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun()); @@ -2111,7 +2187,7 @@ void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices) for ( Standard_Integer i = aLower; i <= anUpper; ++i ) aVertexIndexes(i) = myMeshData->AddNode( theVertices(i) ); - createTrianglesOnNewVertices( aVertexIndexes ); + createTrianglesOnNewVertices( aVertexIndexes, theProgressEntry ); } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_Delaun.hxx b/src/BRepMesh/BRepMesh_Delaun.hxx index e8fcba595e..18f1339c11 100755 --- a/src/BRepMesh/BRepMesh_Delaun.hxx +++ b/src/BRepMesh/BRepMesh_Delaun.hxx @@ -33,6 +33,7 @@ class Bnd_B2d; class Bnd_Box2d; class BRepMesh_Vertex; +class Message_ProgressSentry; //! Compute the Delaunay's triangulation with the algorithm of Watson. class BRepMesh_Delaun @@ -61,6 +62,10 @@ public: //! Adds some vertices into the triangulation. Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices); + //! Adds some vertices into the triangulation. + Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices, + Message_ProgressSentry* theProgressEntry); + //! Modify mesh to use the edge. //! @return True if done Standard_EXPORT Standard_Boolean UseEdge (const Standard_Integer theEdge); @@ -222,6 +227,10 @@ private: void createTriangles (const Standard_Integer theVertexIndex, BRepMesh::MapOfIntegerInteger& thePoly); + void createTriangles (const Standard_Integer theVertexIndex, + BRepMesh::MapOfIntegerInteger& thePoly, + Message_ProgressSentry* theProgressEntry); + //! Add a triangle based on the given oriented edges into mesh void addTriangle (const Standard_Integer (&theEdgesId)[3], const Standard_Boolean (&theEdgesOri)[3], @@ -252,6 +261,10 @@ private: BRepMesh::SequenceOfInteger& thePolygon, BRepMesh::SequenceOfBndB2d& thePolyBoxes); + //! Creates the triangles on new nodes. + void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices, + Message_ProgressSentry* theProgressEntry); + //! Creates the triangles on new nodes. void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices); @@ -323,6 +336,9 @@ private: //! Performs insertion of internal edges into mesh. void insertInternalEdges(); + //! Performs insertion of internal edges into mesh. + void insertInternalEdges (Message_ProgressSentry* theProgressEntry); + private: Handle(BRepMesh_DataStructureOfDelaun) myMeshData; diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx index 1d453897ff..f64de14122 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.cxx @@ -68,6 +68,7 @@ #include #include +#include #include #include @@ -123,15 +124,25 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape) OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel); } - //======================================================================= //function : Process //purpose : //======================================================================= void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const +{ + Process (theFace, NULL); +} + +//======================================================================= +//function : Process +//purpose : +//======================================================================= +void BRepMesh_FastDiscret::Process (const TopoDS_Face& theFace, + Message_ProgressSentry* theProgrEntry) const { Handle(BRepMesh_FaceAttribute) anAttribute; - if (GetFaceAttribute(theFace, anAttribute)) + if (GetFaceAttribute(theFace, anAttribute) + && (theProgrEntry == NULL || theProgrEntry->More())) { try { @@ -139,7 +150,7 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize, myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection); - aTool.Perform(anAttribute); + aTool.Perform (anAttribute, theProgrEntry); } catch (Standard_Failure) { diff --git a/src/BRepMesh/BRepMesh_FastDiscret.hxx b/src/BRepMesh/BRepMesh_FastDiscret.hxx index 3db6feeae2..87cc55587d 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.hxx @@ -46,6 +46,7 @@ class BRepMesh_Edge; class BRepMesh_Vertex; class gp_Pnt; class BRepMesh_FaceAttribute; +class Message_ProgressSentry; //! Algorithm to mesh a shape with respect of the
//! frontier the deflection and by option the shared
@@ -129,6 +130,12 @@ public: //! parallel threads. Standard_EXPORT void Process(const TopoDS_Face& face) const; + //! Triangulate a face previously recorded for + //! processing by call to Add(). Can be executed in + //! parallel threads. + Standard_EXPORT void Process (const TopoDS_Face& theFace, + Message_ProgressSentry* theProgrEntry) const; + void operator () (const TopoDS_Face& face) const { Process(face); diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index 89cbc89540..ed13287b4a 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -187,7 +188,21 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace( //======================================================================= void BRepMesh_FastDiscretFace::Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute) { - add(theAttribute); + Perform (theAttribute, NULL); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void BRepMesh_FastDiscretFace::Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute, + Message_ProgressSentry* theProgressEntry) +{ + add(theAttribute, theProgressEntry); + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } commitSurfaceTriangulation(); } @@ -345,7 +360,8 @@ void BRepMesh_FastDiscretFace::addLinkToMesh( //function : Add //purpose : //======================================================================= -void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttribute) +void BRepMesh_FastDiscretFace::add (const Handle(BRepMesh_FaceAttribute)& theAttribute, + Message_ProgressSentry* theProgressEntry) { if (!theAttribute->IsValid() || theAttribute->ChangeMeshNodes()->IsEmpty()) return; @@ -397,12 +413,22 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr (vmax - vmin) < Precision::PConfusion()); Standard_Real aDef = -1; + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 ) { if (!rajout) { // compute maximal deflection - aDef = control(trigu, Standard_True); + aDef = control(trigu, Standard_True, theProgressEntry); + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.); } if (thetype != GeomAbs_Plane) @@ -415,11 +441,21 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr if (rajout) { - insertInternalVertices(trigu); + insertInternalVertices(trigu, theProgressEntry); + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } //control internal points if (myIsControlSurfaceDeflection) - aDef = control(trigu, Standard_False); + { + aDef = control(trigu, Standard_False, theProgressEntry); + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return; + } + } } } } @@ -447,7 +483,8 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr //======================================================================= Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh( const BRepMesh::ListOfVertex& theVertices, - BRepMesh_Delaun& theMeshBuilder) + BRepMesh_Delaun& theMeshBuilder, + Message_ProgressSentry* theProgressEntry) { if (theVertices.IsEmpty()) return Standard_False; @@ -457,8 +494,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh( for (Standard_Integer aVertexId = 0; aVertexIt.More(); aVertexIt.Next()) aArrayOfNewVertices(++aVertexId) = aVertexIt.Value(); - theMeshBuilder.AddVertices(aArrayOfNewVertices); - return Standard_True; + theMeshBuilder.AddVertices(aArrayOfNewVertices, theProgressEntry); + return theProgressEntry == NULL || theProgressEntry->More(); } //======================================================================= @@ -527,7 +564,8 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams, //function : insertInternalVertices //purpose : //======================================================================= -void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBuilder) +void BRepMesh_FastDiscretFace::insertInternalVertices (BRepMesh_Delaun& theMeshBuilder, + Message_ProgressSentry* theProgressEntry) { Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; BRepMesh::ListOfVertex aNewVertices(anAlloc); @@ -555,7 +593,7 @@ void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBu break; } - addVerticesToMesh(aNewVertices, theMeshBuilder); + addVerticesToMesh(aNewVertices, theMeshBuilder, theProgressEntry); } //======================================================================= @@ -1182,7 +1220,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert( //======================================================================= Standard_Real BRepMesh_FastDiscretFace::control( BRepMesh_Delaun& theTrigu, - const Standard_Boolean theIsFirst) + const Standard_Boolean theIsFirst, + Message_ProgressSentry* theProgressEntry) { Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent(); if (aTrianglesNb < 1) @@ -1219,6 +1258,11 @@ Standard_Real BRepMesh_FastDiscretFace::control( new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return 0; + } + aTempAlloc->Reset(Standard_False); BRepMesh::ListOfVertex aNewVertices(aTempAlloc); @@ -1236,6 +1280,11 @@ Standard_Real BRepMesh_FastDiscretFace::control( BRepMesh::MapOfInteger::Iterator aTriangleIt(aTriangles); for (; aTriangleIt.More(); aTriangleIt.Next()) { + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return 0; + } + const Standard_Integer aTriangleId = aTriangleIt.Key(); const BRepMesh_Triangle& aCurrentTriangle = myStructure->GetElement(aTriangleId); @@ -1398,8 +1447,12 @@ Standard_Real BRepMesh_FastDiscretFace::control( << aP.X() << " " << aP.Y() << " " << aP.Z() << endl; } #endif + if (theProgressEntry != NULL && !theProgressEntry->More()) + { + return 0; + } - if (addVerticesToMesh(aNewVertices, theTrigu)) + if (addVerticesToMesh(aNewVertices, theTrigu, theProgressEntry)) ++aInsertedNb; } diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx index 76b00e1914..dbf301965f 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx @@ -41,6 +41,7 @@ class gp_Pnt2d; class BRepMesh_Edge; class BRepMesh_Vertex; class gp_Pnt; +class Message_ProgressSentry; //! Algorithm to mesh a face with respect of the frontier //! the deflection and by option the shared components. @@ -62,15 +63,19 @@ public: Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute); + Standard_EXPORT void Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute, + Message_ProgressSentry* theProgressEntry); + DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient) private: - void add(const Handle(BRepMesh_FaceAttribute)& theAttribute); + void add(const Handle(BRepMesh_FaceAttribute)& theAttribute, Message_ProgressSentry* theProgressEntry); void add(const TopoDS_Vertex& theVertex); Standard_Real control(BRepMesh_Delaun& theMeshBuilder, - const Standard_Boolean theIsFirst); + const Standard_Boolean theIsFirst, + Message_ProgressSentry* theProgressEntry); //! Registers the given nodes in mesh data structure and //! performs refinement of existing mesh. @@ -80,12 +85,14 @@ private: //! @return TRUE if vertices were been inserted, FALSE elewhere. Standard_Boolean addVerticesToMesh( const BRepMesh::ListOfVertex& theVertices, - BRepMesh_Delaun& theMeshBuilder); + BRepMesh_Delaun& theMeshBuilder, + Message_ProgressSentry* theProgressEntry); //! Calculates nodes lying on face's surface and inserts them to a mesh. //! @param theMeshBuilder initialized tool refining mesh //! in respect to inserting nodes. - void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder); + void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder, + Message_ProgressSentry* theProgressEntry); //! Calculates nodes lying on spherical surface. //! @param theNewVertices list of vertices to be extended and added to mesh. diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx index 70278be259..e44d979ffb 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx @@ -54,6 +54,8 @@ #include +#include + IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot) namespace @@ -63,6 +65,51 @@ namespace static Standard_Boolean IS_IN_PARALLEL = Standard_False; } +class BRepMesh_IncrementalMesh::FaceListFunctor +{ +public: + FaceListFunctor (BRepMesh_IncrementalMesh* theAlgo, + const Handle(Message_ProgressIndicator)& theProgress, + Standard_Boolean theParallel) + : myAlgo (theAlgo), + mySentry (theProgress, "Mesh faces", 0, theAlgo->myFaces.Size(), 1), + myThreadId (OSD_Thread::Current()), + myIsParallel (theParallel), + myHasProgress (!theProgress.IsNull()) + { + } + + void operator() (const Standard_Integer theFaceIndex) const + { + if (!mySentry.More()) + { + return; + } + + TopoDS_Face& aFace = myAlgo->myFaces.ChangeValue (theFaceIndex); + myAlgo->myMesh->Process (aFace, &mySentry); + + if (myIsParallel) + { + // use a trick to avoid mutex locks - increment the progress only within main thread + if (myHasProgress && myThreadId == OSD_Thread::Current()) + { + mySentry.Next (OSD_Parallel::NbLogicalProcessors()); + } + } + else + { + mySentry.Next(); + } + } + +private: + mutable BRepMesh_IncrementalMesh* myAlgo; + mutable Message_ProgressSentry mySentry; + Standard_ThreadId myThreadId; + Standard_Boolean myIsParallel; + Standard_Boolean myHasProgress; +}; //======================================================================= //function : Default constructor @@ -202,41 +249,94 @@ void BRepMesh_IncrementalMesh::collectFaces() //purpose : //======================================================================= void BRepMesh_IncrementalMesh::Perform() +{ + Perform (Handle(Message_ProgressIndicator)()); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void BRepMesh_IncrementalMesh::Perform (const Handle(Message_ProgressIndicator)& theProgress) { init(); if (myMesh.IsNull()) return; - update(); + update (theProgress); } //======================================================================= //function : update() //purpose : //======================================================================= -void BRepMesh_IncrementalMesh::update() +void BRepMesh_IncrementalMesh::update (const Handle(Message_ProgressIndicator)& theProgress) { - // Update edges data - TopExp_Explorer aExplorer(myShape, TopAbs_EDGE); - for (; aExplorer.More(); aExplorer.Next()) - { - const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current()); - if(!BRep_Tool::IsGeometric(aEdge)) - continue; + Message_ProgressSentry anOuterSentry (theProgress, "Updating", 0, 100, 1); - update(aEdge); + // Update edges data + anOuterSentry.Next(9); + { + int aNbEdges = 0; + for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next()) + { + ++aNbEdges; + } + + Message_ProgressSentry anEdgeSentry (theProgress, "Update edges data", 0, aNbEdges, 1); + for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE); + aExplorer.More() && anEdgeSentry.More(); aExplorer.Next(), anEdgeSentry.Next()) + { + const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current()); + if(!BRep_Tool::IsGeometric(aEdge)) + continue; + + update(aEdge); + } } + if (!anOuterSentry.More()) + { + myStatus = BRepMesh_UserBreak; + return; + } + anOuterSentry.Next(5); + // Update faces data NCollection_Vector::Iterator aFaceIt(myFaces); - for (; aFaceIt.More(); aFaceIt.Next()) + for (Message_ProgressSentry aFacesSentry (theProgress, "Update faces data", 0, myFaces.Size(), 1); + aFaceIt.More() && aFacesSentry.More(); aFaceIt.Next(), aFacesSentry.Next()) + { update(aFaceIt.Value()); + } - // Mesh faces - OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel); + if (!anOuterSentry.More()) + { + myStatus = BRepMesh_UserBreak; + return; + } - commit(); + anOuterSentry.Next(80); + + { + // Mesh faces + FaceListFunctor aFacesFunctor (this, theProgress, myParameters.InParallel); + OSD_Parallel::For (0, myFaces.Size(), aFacesFunctor, !myParameters.InParallel); + } + + if (!anOuterSentry.More()) + { + myStatus = BRepMesh_UserBreak; + return; + } + + anOuterSentry.Next(5); + { + Message_ProgressSentry aSentry (theProgress, "Commit", 0, myFaces.Size(), 1); + commit (aSentry); + } + anOuterSentry.Next(); clear(); } @@ -493,10 +593,10 @@ void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace) //function : commit //purpose : //======================================================================= -void BRepMesh_IncrementalMesh::commit() +void BRepMesh_IncrementalMesh::commit (Message_ProgressSentry& theSentry) { NCollection_Vector::Iterator aFaceIt(myFaces); - for (; aFaceIt.More(); aFaceIt.Next()) + for (; aFaceIt.More() && theSentry.More(); aFaceIt.Next(), theSentry.Next()) commitEdges(aFaceIt.Value()); discretizeFreeEdges(); diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx index 5e7d4f3bdc..84541536f9 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx @@ -25,6 +25,7 @@ #include +class Message_ProgressIndicator; class Poly_Triangulation; class TopoDS_Shape; class TopoDS_Edge; @@ -68,7 +69,10 @@ public: //! @name mesher API //! Performs meshing ot the shape. Standard_EXPORT virtual void Perform() Standard_OVERRIDE; - + + //! Performs meshing ot the shape. + Standard_EXPORT void Perform(const Handle(Message_ProgressIndicator)& theProgress); + public: //! @name accessing to parameters. //! Returns meshing parameters @@ -126,7 +130,7 @@ protected: private: //! Builds the incremental mesh for the shape. - void update(); + void update(const Handle(Message_ProgressIndicator)& theProgress); //! Checks triangulation of the given face for consistency //! with the chosen tolerance. If some edge of face has no @@ -167,7 +171,7 @@ private: const Standard_Boolean isWithCheck); //! Stores mesh to the shape. - void commit(); + void commit(Message_ProgressSentry& theSentry); //! Stores mesh of internal edges to the face. void commitEdges(const TopoDS_Face& theFace); @@ -175,6 +179,9 @@ private: //! Clears internal data structures. void clear(); +private: + class FaceListFunctor; + protected: BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges; diff --git a/src/BRepMesh/BRepMesh_Status.hxx b/src/BRepMesh/BRepMesh_Status.hxx index a9b4545717..0c4ce44179 100644 --- a/src/BRepMesh/BRepMesh_Status.hxx +++ b/src/BRepMesh/BRepMesh_Status.hxx @@ -23,7 +23,8 @@ enum BRepMesh_Status BRepMesh_OpenWire = 0x1, BRepMesh_SelfIntersectingWire = 0x2, BRepMesh_Failure = 0x4, - BRepMesh_ReMesh = 0x8 + BRepMesh_ReMesh = 0x8, + BRepMesh_UserBreak = 0x16 }; #endif diff --git a/src/MeshTest/MeshTest.cxx b/src/MeshTest/MeshTest.cxx index 9ee7595246..7db1a42f02 100644 --- a/src/MeshTest/MeshTest.cxx +++ b/src/MeshTest/MeshTest.cxx @@ -80,6 +80,7 @@ #include #include #include +#include #include //epa Memory leaks test @@ -195,7 +196,11 @@ options:\n\ aMeshParams.ControlSurfaceDeflection = isControlSurDef; aMeshParams.AdaptiveMin = isAdaptiveMin; - BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams); + Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1); + BRepMesh_IncrementalMesh aMesher; + aMesher.SetShape (aShape); + aMesher.ChangeParameters() = aMeshParams; + aMesher.Perform (aProgress); di << "Meshing statuses: "; Standard_Integer statusFlags = aMesher.GetStatusFlags(); @@ -206,7 +211,7 @@ options:\n\ else { Standard_Integer i; - for( i = 0; i < 4; i++ ) + for( i = 0; i < 5; i++ ) { if( (statusFlags >> i) & (Standard_Integer)1 ) { @@ -224,6 +229,9 @@ options:\n\ case 4: di << "ReMesh "; break; + case 5: + di << "UserBreak"; + break; } } }