0030788: Modeling Algorithms - BRepAlgoAPI_Defeaturing does not propagate progress...
authorakaftasev <akaftasev@opencascade.com>
Tue, 7 Sep 2021 15:03:20 +0000 (18:03 +0300)
committersmoskvin <smoskvin@opencascade.com>
Wed, 8 Sep 2021 16:14:11 +0000 (19:14 +0300)
Added progress indicator to BRepAlgoAPI_Defeaturing

src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx
src/BOPAlgo/BOPAlgo_RemoveFeatures.hxx
src/BOPTest/BOPTest_RemoveFeaturesCommands.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Defeaturing.cxx
tests/bugs/modalg_7/bug30788 [new file with mode: 0644]

index 7616e1d..12b972b 100644 (file)
@@ -119,12 +119,41 @@ static void FindSolid(const TopoDS_Shape& theSolIn,
                       BOPAlgo_Builder& theBuilder,
                       TopoDS_Shape& theSolOut);
 
+namespace
+{
+  //=======================================================================
+  //function : BOPAlgo_PIOperation
+  //purpose  : List of operations to be supported by the Progress Indicator
+  //=======================================================================
+  enum BOPAlgo_PIOperation
+  {
+    PIOperation_PrepareFeatures = 0,
+    PIOperation_RemoveFeatures,
+    PIOperation_UpdateHistory,
+    PIOperation_SimplifyResult,
+
+    PIOperation_Last
+  };
+}
+
+//=======================================================================
+// function: fillPISteps
+// purpose: 
+//=======================================================================
+void BOPAlgo_RemoveFeatures::fillPIConstants (const Standard_Real theWhole,
+                                              BOPAlgo_PISteps& theSteps) const
+{
+  theSteps.SetStep(PIOperation_PrepareFeatures, 0.05 * theWhole);
+  theSteps.SetStep(PIOperation_RemoveFeatures, 0.8 * theWhole);
+  theSteps.SetStep(PIOperation_UpdateHistory, 0.05 * theWhole);
+  theSteps.SetStep(PIOperation_SimplifyResult, 0.1 * theWhole);
+}
 
 //=======================================================================
 // function: Perform
 // purpose: Performs the removal of the requested faces from the input shape
 //=======================================================================
-void BOPAlgo_RemoveFeatures::Perform(const Message_ProgressRange& /*theRange*/)
+void BOPAlgo_RemoveFeatures::Perform(const Message_ProgressRange& theRange)
 {
   try
   {
@@ -137,21 +166,36 @@ void BOPAlgo_RemoveFeatures::Perform(const Message_ProgressRange& /*theRange*/)
     CheckData();
     if (HasErrors())
       return;
+    Message_ProgressScope aPS(theRange, "Removing features", 100);
+    BOPAlgo_PISteps aSteps(PIOperation_Last);
+    analyzeProgress(100., aSteps);
 
     // Prepare the faces to remove.
-    PrepareFeatures();
+    PrepareFeatures(aPS.Next(aSteps.GetStep(PIOperation_PrepareFeatures)));
     if (HasErrors())
+    {
       return;
+    }
 
     // Remove the features and fill the created gaps
-    RemoveFeatures();
+    RemoveFeatures(aPS.Next(aSteps.GetStep(PIOperation_RemoveFeatures)));
+    if (HasErrors())
+    {
+      return;
+    }
 
     // Update history with the removed features
-    UpdateHistory();
-
+    UpdateHistory(aPS.Next(aSteps.GetStep(PIOperation_UpdateHistory)));
+    if (HasErrors())
+    {
+      return;
+    }
     // Simplify the result
-    SimplifyResult();
-
+    SimplifyResult(aPS.Next(aSteps.GetStep(PIOperation_SimplifyResult)));
+    if (HasErrors())
+    {
+      return;
+    }
     // Post treatment
     PostTreat();
   }
@@ -243,7 +287,7 @@ void BOPAlgo_RemoveFeatures::CheckData()
 // function: PrepareFeatures
 // purpose: Prepares the features to remove
 //=======================================================================
-void BOPAlgo_RemoveFeatures::PrepareFeatures()
+void BOPAlgo_RemoveFeatures::PrepareFeatures(const Message_ProgressRange& theRange)
 {
   // Map all sub-shapes of the input solids
   TopExp::MapShapes(myInputShape, myInputsMap);
@@ -251,12 +295,18 @@ void BOPAlgo_RemoveFeatures::PrepareFeatures()
   // Collect all faces of the input shape requested for removal
   TopTools_ListOfShape aFacesToRemove;
   TopTools_ListIteratorOfListOfShape aIt(myFacesToRemove);
-  for (; aIt.More(); aIt.Next())
+  Message_ProgressScope aPSOuter(theRange, "Preparing features", 2);
+  Message_ProgressScope aPS(aPSOuter.Next(), "Preparing the faces to remove", myFacesToRemove.Size());
+  for (; aIt.More(); aIt.Next(),aPS.Next())
   {
     const TopoDS_Shape& aS = aIt.Value();
     TopExp_Explorer anExpF(aS, TopAbs_FACE);
     for (; anExpF.More(); anExpF.Next())
     {
+      if (UserBreak(aPS))
+      {
+        return;
+      }
       const TopoDS_Shape& aF = anExpF.Current();
       if (myInputsMap.Contains(aF))
         aFacesToRemove.Append(aF);
@@ -327,6 +377,11 @@ public: //! @name Setters/Getters
     return myHistory;
   }
 
+  void SetRange(const Message_ProgressRange& theRange)
+  {
+    myRange = theRange;
+  }
+
 public: //! @name Perform the operation
 
   //! Performs the extension of the adjacent faces and
@@ -337,11 +392,17 @@ public: //! @name Perform the operation
 
     try
     {
+      Message_ProgressScope aPS(myRange, NULL, 3);
+
       myHistory = new BRepTools_History();
 
       // Find the faces adjacent to the faces of the feature
       TopTools_IndexedMapOfShape aMFAdjacent;
-      FindAdjacentFaces(aMFAdjacent);
+      FindAdjacentFaces(aMFAdjacent, aPS.Next());
+      if (!aPS.More())
+      {
+        return;
+      }
 
       myHasAdjacentFaces = (aMFAdjacent.Extent() > 0);
       if (!myHasAdjacentFaces)
@@ -349,10 +410,14 @@ public: //! @name Perform the operation
 
       // Extend the adjacent faces keeping the connection to the original faces
       TopTools_IndexedDataMapOfShapeShape aFaceExtFaceMap;
-      ExtendAdjacentFaces(aMFAdjacent, aFaceExtFaceMap);
+      ExtendAdjacentFaces(aMFAdjacent, aFaceExtFaceMap, aPS.Next());
+      if (!aPS.More())
+      {
+        return;
+      }
 
       // Trim the extended faces
-      TrimExtendedFaces(aFaceExtFaceMap);
+      TrimExtendedFaces(aFaceExtFaceMap, aPS.Next());
     }
     catch (Standard_Failure const&)
     {
@@ -380,17 +445,22 @@ public: //! @name Obtain the result
 private: //! @name Private methods performing the operation
 
   //! Finds the faces adjacent to the feature and stores them into outgoing map.
-  void FindAdjacentFaces(TopTools_IndexedMapOfShape& theMFAdjacent)
+  void FindAdjacentFaces(TopTools_IndexedMapOfShape& theMFAdjacent, const Message_ProgressRange& theRange)
   {
     // Map the faces of the feature to avoid them in the map of adjacent faces
     TopoDS_Iterator aIt(myFeature);
     for (; aIt.More(); aIt.Next())
       myFeatureFacesMap.Add(aIt.Value());
-
+    Message_ProgressScope aPSOuter(theRange, NULL, 2);
     // Find faces adjacent to the feature using the connection map
     aIt.Initialize(myFeature);
-    for (; aIt.More(); aIt.Next())
+    Message_ProgressScope aPSF(aPSOuter.Next(), "Looking for adjacent faces", 1, Standard_True);
+    for (; aIt.More(); aIt.Next(), aPSF.Next())
     {
+      if (!aPSF.More())
+      {
+        return;
+      }
       const TopoDS_Shape& aF = aIt.Value();
       TopExp_Explorer anExpE(aF, TopAbs_EDGE);
       for (; anExpE.More(); anExpE.Next())
@@ -420,8 +490,13 @@ private: //! @name Private methods performing the operation
 
     // Find solids containing the edges of adjacent faces
     const Standard_Integer aNbFA = theMFAdjacent.Extent();
-    for (Standard_Integer i = 1; i <= aNbFA; ++i)
+    Message_ProgressScope aPSS(aPSOuter.Next(), "Looking for adjacent solids", aNbFA);
+    for (Standard_Integer i = 1; i <= aNbFA; ++i, aPSS.Next())
     {
+      if (!aPSS.More())
+      {
+        return;
+      }
       TopExp_Explorer anExpEA(theMFAdjacent(i), TopAbs_EDGE);
       for (; anExpEA.More(); anExpEA.Next())
       {
@@ -448,7 +523,8 @@ private: //! @name Private methods performing the operation
 
   //! Extends the found adjacent faces and binds them to the original faces.
   void ExtendAdjacentFaces(const TopTools_IndexedMapOfShape& theMFAdjacent,
-                           TopTools_IndexedDataMapOfShapeShape& theFaceExtFaceMap)
+                           TopTools_IndexedDataMapOfShapeShape& theFaceExtFaceMap,
+                           const Message_ProgressRange& theRange)
   {
     // Get the extension value for the faces - half of the diagonal of bounding box of the feature
     Bnd_Box aFeatureBox;
@@ -457,7 +533,8 @@ private: //! @name Private methods performing the operation
     const Standard_Real anExtLength = sqrt(aFeatureBox.SquareExtent());
 
     const Standard_Integer aNbFA = theMFAdjacent.Extent();
-    for (Standard_Integer i = 1; i <= aNbFA; ++i)
+    Message_ProgressScope aPS(theRange, "Extending adjacent faces", aNbFA);
+    for (Standard_Integer i = 1; i <= aNbFA && aPS.More(); ++i, aPS.Next())
     {
       const TopoDS_Face& aF = TopoDS::Face(theMFAdjacent(i));
       // Extend the face
@@ -473,7 +550,8 @@ private: //! @name Private methods performing the operation
 
   //! Trims the extended adjacent faces by intersection with each other
   //! and following intersection with the bounds of original faces.
-  void TrimExtendedFaces(const TopTools_IndexedDataMapOfShapeShape& theFaceExtFaceMap)
+  void TrimExtendedFaces(const TopTools_IndexedDataMapOfShapeShape& theFaceExtFaceMap,
+                         const Message_ProgressRange& theRange)
   {
     // Intersect the extended faces first
     BOPAlgo_Builder aGFInter;
@@ -486,9 +564,10 @@ private: //! @name Private methods performing the operation
 
     // Intersection result
     TopoDS_Shape anIntResult;
+    Message_ProgressScope aPSOuter(theRange, NULL, (aGFInter.Arguments().Extent() > 1) ? 2 : 1);
     if (aGFInter.Arguments().Extent() > 1)
     {
-      aGFInter.Perform();
+      aGFInter.Perform(aPSOuter.Next());
       if (aGFInter.HasErrors())
         return;
 
@@ -511,7 +590,8 @@ private: //! @name Private methods performing the operation
     TopTools_IndexedMapOfShape aFeatureEdgesMap;
     TopExp::MapShapes(myFeature, TopAbs_EDGE, aFeatureEdgesMap);
 
-    for (Standard_Integer i = 1; i <= aNbF; ++i)
+    Message_ProgressScope aPS(aPSOuter.Next(), "Trimming faces", aNbF);
+    for (Standard_Integer i = 1; i <= aNbF && aPS.More(); ++i, aPS.Next())
     {
       const TopoDS_Face& aFOriginal = TopoDS::Face(theFaceExtFaceMap.FindKey(i));
       const TopoDS_Face& aFExt = TopoDS::Face(theFaceExtFaceMap(i));
@@ -705,6 +785,7 @@ private: //! @name Fields
   TopoDS_Shape myFeature;                             //!< Feature to remove
   TopTools_IndexedDataMapOfShapeListOfShape* myEFMap; //!< EF Connection map to find adjacent faces
   TopTools_IndexedDataMapOfShapeListOfShape* myFSMap; //!< FS Connection map to find solids participating in the feature removal
+  Message_ProgressRange                      myRange; //!< Indication of progress
 
   // Results
   TopTools_MapOfShape myFeatureFacesMap;              //!< Faces of the feature
@@ -721,7 +802,7 @@ typedef NCollection_Vector<FillGap> VectorOfFillGap;
 // purpose: Remove features by filling the gaps by extension of the
 //          adjacent faces
 //=======================================================================
-void BOPAlgo_RemoveFeatures::RemoveFeatures()
+void BOPAlgo_RemoveFeatures::RemoveFeatures(const Message_ProgressRange& theRange)
 {
   // For each feature:
   // - Find the faces adjacent to the feature;
@@ -730,6 +811,8 @@ void BOPAlgo_RemoveFeatures::RemoveFeatures()
   // - Rebuild the solids with reconstructed adjacent faces
   //   and avoiding the feature faces.
 
+  Message_ProgressScope aPSOuter(theRange, "Removing features", 2);
+
   // Make Edge-Face connection map of the input
   // shape to find faces adjacent to the feature
   TopTools_IndexedDataMapOfShapeListOfShape anEFMap;
@@ -755,9 +838,19 @@ void BOPAlgo_RemoveFeatures::RemoveFeatures()
     aFG.SetRunParallel(myRunParallel);
   }
 
+  const Standard_Integer aNbF = aVFG.Length();
+  Message_ProgressScope aPS(aPSOuter.Next(), "Filling gaps", aNbF);
+  for (Standard_Integer i = 0; i < aNbF; ++i)
+  {
+    FillGap& aFG = aVFG.ChangeValue(i);
+    aFG.SetRange(aPS.Next());
+  }
   // Perform the reconstruction of the adjacent faces
   BOPTools_Parallel::Perform (myRunParallel, aVFG);
-
+  if (UserBreak(aPSOuter))
+  {
+    return;
+  }
   // Even if the history is not requested, it is necessary to track:
   // - The solids modification after each feature removal to find
   //   the necessary solids to rebuild on the next step.
@@ -769,9 +862,13 @@ void BOPAlgo_RemoveFeatures::RemoveFeatures()
   // Remove the features one by one.
   // It will allow removing the features even if there were
   // some problems with removal of the previous features.
-  const Standard_Integer aNbF = aVFG.Length();
+  Message_ProgressScope aPSLoop(aPSOuter.Next(), "Removing features one by one", aNbF);
   for (Standard_Integer i = 0; i < aNbF; ++i)
   {
+    if (UserBreak(aPSLoop))
+    {
+      return;
+    }
     FillGap& aFG = aVFG(i);
 
     // No need to fill the history for solids if the history is not
@@ -781,7 +878,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeatures()
     // Perform removal of the single feature
     RemoveFeature(aFG.Feature(), aFG.Solids(), aFG.FeatureFacesMap(),
                   aFG.HasAdjacentFaces(), aFG.Faces(), aFG.History(),
-                  isSolidsHistoryNeeded);
+                  isSolidsHistoryNeeded, aPSLoop.Next());
   }
 }
 
@@ -796,7 +893,8 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
    const Standard_Boolean theHasAdjacentFaces,
    const TopTools_IndexedDataMapOfShapeListOfShape& theAdjFaces,
    const Handle(BRepTools_History)& theAdjFacesHistory,
-   const Standard_Boolean theSolidsHistoryNeeded)
+   const Standard_Boolean theSolidsHistoryNeeded,
+   const Message_ProgressRange& theRange)
 {
   Standard_Boolean bFuseShapes = Standard_True;
   const Standard_Integer aNbAF = theAdjFaces.Extent();
@@ -817,6 +915,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
     bFuseShapes = Standard_False;
   }
 
+  Message_ProgressScope aPS(theRange, NULL, 100);
   // Rebuild the shape using MakerVolume algorithm avoiding the faces of the
   // feature and replacing the adjacent faces with their images
 
@@ -848,7 +947,8 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
   GetOriginalFaces(myShape, theSolids, theFeatureFacesMap, theAdjFaces, myHistory,
                    aFacesToBeKept, anInternalShapes, aFacesToCheckOri,
                    aSolidsToRebuild, aSharedFaces, anUnTouchedSolids);
-
+  
+  aPS.Next(3);
   // To avoid excessive intersection of the faces collect the faces
   // of the input shape into a compound
   TopoDS_Compound anOrigF;
@@ -898,7 +998,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
   }
 
   // Build solids
-  aMV.Perform();
+  aMV.Perform(aPS.Next(90));
   if (aMV.HasErrors())
   {
     // Add warning for the feature
@@ -926,6 +1026,10 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
   TopTools_MapOfShape anAdjFacesSplits;
   for (Standard_Integer i = 1; i <= aNbAF; ++i)
   {
+    if (!aPS.More())
+    {
+      return;
+    }
     const TopoDS_Shape& aF = theAdjFaces.FindKey(i);
     const TopTools_ListOfShape& aLFIm = myHistory->Modified(aF);
     if (aLFIm.IsEmpty())
@@ -943,9 +1047,14 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
   aNbFK = aFacesToBeKept.Extent();
   for (Standard_Integer i = 1; i <= aNbFK && bValid; ++i)
   {
+
     const TopoDS_Shape& aS = aFacesToBeKept(i);
     if (anAdjFacesSplits.Contains(aS))
       continue;
+    if (!aPS.More())
+    {
+      return;
+    }
     TopExp_Explorer anExpF(aS, TopAbs_FACE);
     for (; anExpF.More(); anExpF.Next())
     {
@@ -976,7 +1085,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
     AddWarning(new BOPAlgo_AlertUnableToRemoveTheFeature(theFeature));
     return;
   }
-
+  aPS.Next(3);
   // Remove internal wires from the faces, possibly appeared after intersection
   RemoveInternalWires(aLSRes, &anInternalShapes);
 
@@ -1000,7 +1109,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
     MakeRemoved(anInternalShapes, aRemHist, aMSRes);
     myHistory->Merge(aRemHist);
   }
-
+  aPS.Next(3);
   // Fill the history for the solids
   if (theSolidsHistoryNeeded)
   {
@@ -1029,7 +1138,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeature
 // function: UpdateHistory
 // purpose: Update history with the removed features
 //=======================================================================
-void BOPAlgo_RemoveFeatures::UpdateHistory()
+void BOPAlgo_RemoveFeatures::UpdateHistory(const Message_ProgressRange& theRange)
 {
   if (!HasHistory())
     return;
@@ -1042,7 +1151,8 @@ void BOPAlgo_RemoveFeatures::UpdateHistory()
   BRepTools_History aHistory;
 
   const Standard_Integer aNbS = myInputsMap.Extent();
-  for (Standard_Integer i = 1; i <= aNbS; ++i)
+  Message_ProgressScope aPS(theRange, "Updating history", aNbS);
+  for (Standard_Integer i = 1; i <= aNbS; ++i, aPS.Next())
   {
     const TopoDS_Shape& aS = myInputsMap(i);
     if (!BRepTools_History::IsSupportedType(aS))
@@ -1051,6 +1161,10 @@ void BOPAlgo_RemoveFeatures::UpdateHistory()
     if (myHistory->IsRemoved(aS))
       continue;
 
+    if (UserBreak(aPS))
+    {
+      return;
+    }
     // Check if the shape has any trace in the result
     const TopTools_ListOfShape& aLSIm = myHistory->Modified(aS);
     if (aLSIm.IsEmpty())
@@ -1075,10 +1189,11 @@ void BOPAlgo_RemoveFeatures::UpdateHistory()
 // purpose: Simplifies the result by removing extra edges and vertices
 //          created during operation
 //=======================================================================
-void BOPAlgo_RemoveFeatures::SimplifyResult()
+void BOPAlgo_RemoveFeatures::SimplifyResult(const Message_ProgressRange& theRange)
 {
   if (myShape.IsSame(myInputShape))
     return;
+  Message_ProgressScope aPSOuter(theRange, "Simplifyingthe result", 2);
   ShapeUpgrade_UnifySameDomain aSDTool;
   aSDTool.Initialize(myShape, Standard_True, Standard_True);
   // Do not allow producing internal edges
@@ -1088,14 +1203,20 @@ void BOPAlgo_RemoveFeatures::SimplifyResult()
     TopExp::MapShapes(myShape, myMapShape);
 
   const Standard_Integer aNbS = myInputsMap.Extent();
-  for (Standard_Integer i = 1; i <= aNbS; ++i)
+  Message_ProgressScope aPS(aPSOuter.Next(), NULL, aNbS);
+  for (Standard_Integer i = 1; i <= aNbS; ++i, aPS.Next())
   {
+    if (UserBreak(aPS))
+    {
+      return;
+    }
     if (myMapShape.Contains(myInputsMap(i)))
       aSDTool.KeepShape(myInputsMap(i));
   }
 
   // Perform unification
   aSDTool.Build();
+  aPSOuter.Next();
   myShape = aSDTool.Shape();
   if (HasHistory())
     myHistory->Merge(aSDTool.History());
index 7db54ff..1303bc8 100644 (file)
@@ -231,11 +231,11 @@ protected: //! @name Protected methods performing the removal
   //! Prepares the faces to remove:
   //! - Gets only faces contained in the input solids;
   //! - Builds connected blocks of faces creating separate features to remove.
-  Standard_EXPORT void PrepareFeatures();
+  Standard_EXPORT void PrepareFeatures(const Message_ProgressRange& theRange);
 
   //! Removes the features and fills the created gaps by extension of the adjacent faces.
   //! Processes each feature separately.
-  Standard_EXPORT void RemoveFeatures();
+  Standard_EXPORT void RemoveFeatures(const Message_ProgressRange& theRange);
 
   //! Remove the single feature from the shape.
   //! @param theFeature [in] The feature to remove;
@@ -253,18 +253,22 @@ protected: //! @name Protected methods performing the removal
                                      const Standard_Boolean theHasAdjacentFaces,
                                      const TopTools_IndexedDataMapOfShapeListOfShape& theAdjFaces,
                                      const Handle(BRepTools_History)& theAdjFacesHistory,
-                                     const Standard_Boolean theSolidsHistoryNeeded);
+                                     const Standard_Boolean theSolidsHistoryNeeded,
+                                     const Message_ProgressRange& theRange);
 
   //! Updates history with the removed features
-  Standard_EXPORT void UpdateHistory();
+  Standard_EXPORT void UpdateHistory(const Message_ProgressRange& theRange);
 
   //! Simplifies the result by removing extra edges and vertices created
   //! during removal of the features.
-  Standard_EXPORT void SimplifyResult();
+  Standard_EXPORT void SimplifyResult(const Message_ProgressRange& theRange);
 
   //! Post treatment - restore the type of the initial shape
   Standard_EXPORT void PostTreat();
 
+  //! Filling steps for constant operations
+  Standard_EXPORT void fillPIConstants(const Standard_Real theWhole, BOPAlgo_PISteps& theSteps) const Standard_OVERRIDE;
+
 protected: //! @name Fields
 
   // Inputs
index 7a85b1d..2f00af4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <DBRep.hxx>
 #include <Draw.hxx>
+#include <Draw_ProgressIndicator.hxx>
 
 #include <TopoDS.hxx>
 #include <TopoDS_Compound.hxx>
@@ -98,9 +99,9 @@ Standard_Integer RemoveFeatures(Draw_Interpretor& theDI,
   }
 
   aRF.SetToFillHistory(BRepTest_Objects::IsHistoryNeeded());
-
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(theDI, 1);
   // Perform the removal
-  aRF.Build();
+  aRF.Build(aProgress->Start());
 
   // Check for the errors/warnings
   BOPTest::ReportAlerts(aRF.GetReport());
index 2f4def8..04fa1a3 100644 (file)
@@ -21,7 +21,7 @@
 //function : Build
 //purpose  : 
 //=======================================================================
-void BRepAlgoAPI_Defeaturing::Build(const Message_ProgressRange& /*theRange*/)
+void BRepAlgoAPI_Defeaturing::Build(const Message_ProgressRange& theRange)
 {
   // Set not done state for the operation
   NotDone();
@@ -36,7 +36,7 @@ void BRepAlgoAPI_Defeaturing::Build(const Message_ProgressRange& /*theRange*/)
   myFeatureRemovalTool.SetRunParallel(myRunParallel);
 
   // Perform the features removal
-  myFeatureRemovalTool.Perform();
+  myFeatureRemovalTool.Perform(theRange);
 
   // Merge the Errors/Warnings from the features removal tool
   GetReport()->Merge(myFeatureRemovalTool.GetReport());
diff --git a/tests/bugs/modalg_7/bug30788 b/tests/bugs/modalg_7/bug30788
new file mode 100644 (file)
index 0000000..a0ebc39
--- /dev/null
@@ -0,0 +1,22 @@
+puts "============================================"
+puts "0030788: Modeling Algorithms - BRepAlgoAPI_Defeaturing does not propagate progress indicator to underlying algorithms"
+puts "============================================"
+puts ""
+proc isTracked { theOutput } {
+  if {![regexp "Progress" $theOutput]} {
+    puts "Error: progress is not tracked"
+  }
+}
+XProgress +t
+restore [locate_data_file bug29481_ex1.brep] s
+explode s f
+
+compound s_6 s_18 step
+
+# check that progress is tracked for removefeatures operation
+
+set log [removefeatures res s step]
+isTracked $log