Last modified: 2025-02-21 21:47:31
< 2025-02-20 2025-02-22 >I think the main things left to do are:
But there is now discussion on https://github.com/FreeCAD/FreeCAD/pull/19710 about doing it natively with OpenCascade after all, so I may be barking up the wrong tree.
I'll try to make it work via the main FreeCAD binary though.
I think we add some --boolean-worker
option in processProgramOptions()
in Application.cpp
, and then it says mConfig["RunMode"]
to BooleanWorker
or something,
which we then implement in runApplication()
.
Great success, works. You have to go via Python in order to access dynamically-loaded modules, which is mildly annoying, but the plumbing isn't too bad.
"hyarion" suggests I test out the OpenCascade method of interrupting long-running tasks.
So there is some "Message_ProgressIndicator::UserBreak()" that you can call to request that it stop working.
So I think diff my branch from the current main branch, and then just keep the parts that are to do with the dialog window and throw away the rest. And make the dialog window call "Message_ProgressIndicator::UserBreak()" when you click the button.
Looks like the only file I want to keep is src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp
.
Annoyingly, UserBreak()
is "protected" in BRepAlgoAPI_BooleanOperation
, so I can't
call it.
Maybe cast to a custom subclass that just makes it public?
Well I got it to compile and run, but it doesn't abort. Just keeps going, as if
the UserBreak()
doesn't do anything at all.
https://github.com/jes/FreeCAD/commit/3aa8262ff923884b8b480c86226dfcfab8a7a9b5
OK, update is that I need to implement UserBreak()
and make it return true if the
use has asked to abort. I guess that makes sense.
That didn't work.
But now I see what I need to do: I need to make a subclass of Message_ProgressScope
and implement UserBreak()
in that, and then pass the Message_ProgressScope
into
the Build()
call.
So, I guess start again from the point where I only have the Abort dialog.
Whoa, I think it might be working. This might also give us the option to actually report progress percentages!
https://www.youtube.com/watch?v=Q93bFbr5ERg
The big downside is you need it to get to a point where it is ready to be interrupted.
Possibly that is a change that would be easy-ish to upstream to OCCT though: work out
where it is getting stuck and add more UserBreak()
checks.
"tritao" suggested on Discord trying to do the child process thing but with a child thread, says you can't abort threads with C++11, links to https://chatgpt.com/share/67b8a487-cb10-8008-a75b-6d77563fff51
One idea is we could use the ProgressIndicator thing as a "primary" method of aborting, but have a "Force abort" if you press Abort and it still hasnt' finished a second later, and then we only do the potentially-dangerous thing if the user really wants it
And tritao adds "and maybe save backup file at that point too".
Skip the backup file thing for now.
So the plan now is to make it kill the worker thread if it doesn't finish within a second or something.
First result is that it dies with:
terminate called without an active exception
Aborted (core dumped)
if I try to abort the thread. Reading the ChatGPT thread more closely, looks like I need to set a "cancelstate" and "canceltype", let's try that.
Nope.
Next up is wrapping the whole thread in try/catch in case that will do it.
"chennes" in Discord told me this happens if something throws an exception during the
destructor. I pasted a backtrace into Cursor and it told me you need to detach the
thread otherwise when you exit the scope it will terminate()
because the thread is
theoretically still running but you lost the handle to it?
That's working!
Hmm, it sometimes segfaults FreeCAD anyway.
Another point is that if OCCT is doing multi-threaded work in the background then cancelling the thread that you started won't automatically cancel OCCT's other threads.
Oh, actually, I think the segfault is my fault. I put a return
where I oughtn't've.
Nope, wasn't that.
I've stashed my changes and trying again, I'm sure on my last commit it wasn't segfaulting when you abort.
Meh, it's segfaulting every time now.
New PR: https://github.com/FreeCAD/FreeCAD/pull/19763
Todo is: