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
{
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();
}
// 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);
// 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);
return myHistory;
}
+ void SetRange(const Message_ProgressRange& theRange)
+ {
+ myRange = theRange;
+ }
+
public: //! @name Perform the operation
//! Performs the extension of the adjacent faces and
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)
// 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&)
{
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())
// 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())
{
//! 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;
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
//! 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;
// 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;
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));
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
// 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;
// - 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;
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.
// 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
// Perform removal of the single feature
RemoveFeature(aFG.Feature(), aFG.Solids(), aFG.FeatureFacesMap(),
aFG.HasAdjacentFaces(), aFG.Faces(), aFG.History(),
- isSolidsHistoryNeeded);
+ isSolidsHistoryNeeded, aPSLoop.Next());
}
}
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();
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
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;
}
// Build solids
- aMV.Perform();
+ aMV.Perform(aPS.Next(90));
if (aMV.HasErrors())
{
// Add warning for the feature
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())
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())
{
AddWarning(new BOPAlgo_AlertUnableToRemoveTheFeature(theFeature));
return;
}
-
+ aPS.Next(3);
// Remove internal wires from the faces, possibly appeared after intersection
RemoveInternalWires(aLSRes, &anInternalShapes);
MakeRemoved(anInternalShapes, aRemHist, aMSRes);
myHistory->Merge(aRemHist);
}
-
+ aPS.Next(3);
// Fill the history for the solids
if (theSolidsHistoryNeeded)
{
// function: UpdateHistory
// purpose: Update history with the removed features
//=======================================================================
-void BOPAlgo_RemoveFeatures::UpdateHistory()
+void BOPAlgo_RemoveFeatures::UpdateHistory(const Message_ProgressRange& theRange)
{
if (!HasHistory())
return;
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))
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())
// 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
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());