Forum archiveIssue archiveModeling Data and Algorithms

Archived discussion

BRepAlgoAPI_Defeaturing never finishes

Modeling Data and AlgorithmsFri, 12/08/2023 - 08:532 replies

Browse this forum
QuestionAuthor

Hello everyone, When I use BRepAlgoAPI_Defeaturing to remove a small face (created by BRepFilletAPI_MakeFillet), the BRepAlgoAPI_Defeaturing never finishes even with timeout setting, it loops in IntTools_BeanFaceIntersector::ComputeLocalized with huge amount of surface ranges (20355, 40000+...) Tesed with occ 7.6.1, 7.7, and latest github main branch.

Below is the sample code:

BRep_Builder bb;
TopoDS_Shape targetEntityShape;
const char* brepFile = R"(D:\tmp\anc101_def.brep)";

TopoDS_Shape nullShape;
if (!BRepTools::Read(targetEntityShape, brepFile, bb)) {
    return nullShape;
}

ShapeFix_ShapeTolerance aFixToler;
if (!aFixToler.LimitTolerance(targetEntityShape, Precision::Confusion(), Precision::Confusion() * 10)) {
    return nullShape;
}

TopoDS_Face face;
int i = 0;
for (TopExp_Explorer faceExplorer(targetEntityShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next()) {
    if (i == 1) {
        face = TopoDS::Face(faceExplorer.Current());
        break;
    }
    i++;
}

TopTools_ListOfShape faceShapes;
faceShapes.Append(face);

BRepAlgoAPI_Defeaturing aDefeaturing;

aDefeaturing.SetShape(targetEntityShape);
aDefeaturing.AddFacesToRemove(faceShapes);
aDefeaturing.SetRunParallel(false);
aDefeaturing.SetToFillHistory(true);
// Perform.
Handle(OcctProgressIndicator) pi = new OcctProgressIndicator(10); // 10 seconds
aDefeaturing.Build(pi->Start());

if (pi->TimedOut() || !aDefeaturing.IsDone() || aDefeaturing.HasWarnings()) {
    return targetEntityShape;
}
return aDefeaturing.Shape();

The brep file is attached, also a screen capture to show the solid and face to be removed.

Archived image: Alt text

If anyone could help, appreciate it very much!

Regards.

Discussion

2 archived replies

Posts are displayed in their archived order.

01Commenter-1

Hello.

We will try to reproduce. Probably it is problem with internal code. If problem will be reproduced - ticket will be created.

Additionally, progress indicator don't use seconds, it is semantic iteration count and input number is not working as a timeout.

Best regards Commenter-1.

02Author

Thanks a lot for reply, I created the customized indicator like this (by UserBreak returns true after timeout seconds):

DEFINE_STANDARD_HANDLE(OcctProgressIndicator, Message_ProgressIndicator)
class OcctProgressIndicator : public Message_ProgressIndicator
{
private:
    OSD_Timer aTimer;
    Standard_Real maxRunDuration;
    bool timedOut;
public:
    OcctProgressIndicator(Standard_Real maxDurationSeconds, bool startTimer = true);
    virtual Standard_Boolean Show(const Standard_Boolean) { return true; }
    virtual Standard_Boolean UserBreak() override;
    void StartTimer() { timedOut = false;  aTimer.Start(); }
    void StopTimer() { aTimer.Stop(); }
    Standard_Real ElapsedTime() { return aTimer.ElapsedTime(); }
    bool TimedOut() { return timedOut; }
    void Show(const Message_ProgressScope& theScope, const Standard_Boolean force = Standard_True) override;

    DEFINE_STANDARD_RTTIEXT(OcctProgressIndicator, Message_ProgressIndicator)
};


IMPLEMENT_STANDARD_HANDLE(OcctProgressIndicator, Message_ProgressIndicator)
IMPLEMENT_STANDARD_RTTIEXT(OcctProgressIndicator, Message_ProgressIndicator)

OcctProgressIndicator::OcctProgressIndicator(Standard_Real maxDurationSeconds, bool startTimer) :
    Message_ProgressIndicator()
{
    timedOut = false;
    maxRunDuration = maxDurationSeconds;
    if (startTimer)
        StartTimer();
}

Standard_Boolean OcctProgressIndicator::UserBreak()
{
    if (ElapsedTime() > maxRunDuration)
    {
        StopTimer();
        timedOut = true;
        return true;
    }
    else
        return false;
}

void OcctProgressIndicator::Show(const Message_ProgressScope&, const Standard_Boolean)
{
}

Best Regards, Author