0025113: Mesh - Progress indication and user break functionality for BRepMesh component
[occt.git] / src / BRepMesh / BRepMesh_FaceDiscret.cxx
index ce6db21..424fdd2 100644 (file)
@@ -39,13 +39,46 @@ BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret()
 {
 }
 
+//! Auxiliary functor for parallel processing of Faces.
+class BRepMesh_FaceDiscret::FaceListFunctor
+{
+public:
+  FaceListFunctor (BRepMesh_FaceDiscret* theAlgo,
+                   const Message_ProgressRange& theRange)
+  : myAlgo (theAlgo),
+    myScope (theRange, "Face Discret", theAlgo->myModel->FacesNb())
+  {
+    myRanges.reserve (theAlgo->myModel->FacesNb());
+    for (Standard_Integer aFaceIter = 0; aFaceIter < theAlgo->myModel->FacesNb(); ++aFaceIter)
+    {
+      myRanges.push_back (myScope.Next());
+    }
+  }
+
+  void operator() (const Standard_Integer theFaceIndex) const
+  {
+    if (!myScope.More())
+    {
+      return;
+    }
+    Message_ProgressScope aFaceScope(myRanges[theFaceIndex], NULL, 1);
+    myAlgo->process(theFaceIndex, aFaceScope.Next());
+  }
+
+private:
+  mutable BRepMesh_FaceDiscret* myAlgo;
+  Message_ProgressScope myScope;
+  std::vector<Message_ProgressRange> myRanges;
+};
+
 //=======================================================================
 // Function: Perform
 // Purpose : 
 //=======================================================================
 Standard_Boolean BRepMesh_FaceDiscret::performInternal(
   const Handle(IMeshData_Model)& theModel,
-  const IMeshTools_Parameters&   theParameters)
+  const IMeshTools_Parameters&   theParameters,
+  const Message_ProgressRange&   theRange)
 {
   myModel      = theModel;
   myParameters = theParameters;
@@ -54,7 +87,12 @@ Standard_Boolean BRepMesh_FaceDiscret::performInternal(
     return Standard_False;
   }
 
-  OSD_Parallel::For(0, myModel->FacesNb(), *this, !(myParameters.InParallel && myModel->FacesNb() > 1));
+  FaceListFunctor aFunctor(this, theRange);
+  OSD_Parallel::For(0, myModel->FacesNb(), aFunctor, !(myParameters.InParallel && myModel->FacesNb() > 1));
+  if (!theRange.More())
+  {
+    return Standard_False;
+  }
 
   myModel.Nullify(); // Do not hold link to model.
   return Standard_True;
@@ -64,7 +102,8 @@ Standard_Boolean BRepMesh_FaceDiscret::performInternal(
 // Function: process
 // Purpose : 
 //=======================================================================
-void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
+void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex, 
+                                   const Message_ProgressRange& theRange) const
 {
   const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
   if (aDFace->IsSet(IMeshData_Failure) ||
@@ -86,7 +125,12 @@ void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
       return;
     }
   
-    aMeshingAlgo->Perform(aDFace, myParameters);
+    if (!theRange.More())
+    {
+      aDFace->SetStatus (IMeshData_UserBreak);
+      return;
+    }
+    aMeshingAlgo->Perform(aDFace, myParameters, theRange);
   }
   catch (Standard_Failure const&)
   {