This has been shared with a few developers already, but opening the discussion to a broader community for input, feedback, awareness. It's a work-in-progress diagram showing a near-term path for BRL-CAD's major architecture, particularly as it relates to major libraries and a push towards a single graphical application framework. BRL-CAD-Architecture-Prospectus.pdf
The main implications of this are in line with the massive consolidation and reduction efforts announced over a year ago (to get command-line apps down below 10 and ged commands below 100), namely that a lot of the complexity that currently exists in command-line form is getting grouped together with related features or eliminated where out of scope, immature, and/or undeveloped.
It indicates we're planning to drop a few major dependencies (like Tcl/Tk for GUI) and adopt a few major dependencies that we've already proofed in some form (like Qt and OSPray for GUI) along with TBB and C++11 for our core runtime, the latter of which is already under way.
Some aspects are heavily dependent on how quickly GUI development matures and whether we can secure dedicated development support, but other work hinted at include integration of 3rd party framework like OSG for scene management, appleseed for advanced rendering, and possible consolidation of BU+BN+BG into a LIBBPR.
Not depicted but intended with this rearchitecting is a change to how BRL-CAD has been historically packaged and deployed. Instead of hundreds of binaries with adhoc conflict with system facilities, adopting modern packaging standards for Mac, Linux, and Windows where there is a singular entry point into our ecosystem that can be made to comply with LSB, iOS, Windows 10, and other common standards.
Hi All, it's been a year of reflection, so I've updated the architecture diagram. This is in response to code discoveries, development, discussions, and more. Feedback and discussion is of course always welcome, particularly from any of you new guys from GCI seeing things for the first time, and core devs of course.
BRL-CAD-Architecture-Prospectus.png
Just a note, but the spacings in the GUI app denote where we currently have code "air gapped" in separate repos. The biggest change is making MOOSE be the main engine and interface through which the GUI represents and interacts with geometry.
I like the libcad :smiley:
@Himanshu Sekhar Nayak diagram is maybe useful context? This isn't the current state, but a proposed direction (at least that I'm slowly working towards)
Wow so many libraries that I have never seen and heard about it. In my free time, I will look into it. What I understand that MOOSE will be the main kernel where it will take requests from the GUI side and will send to the libraries. It is similar to what I know about OS kernel :sweat_smile:.
There will be one GUI for total number of command line applications or for each command line application there will be each gui?
That's the hope/goal (for me at least) that there will be one primary GUI application environment built on top of MOOSE. There will also be other CLI applications where needed (e.g., for rendering, image and data conversion, scripting needs, etc).
starseeker said:
Daniel Rossberg Is there a good example somewhere of an implementation of that pattern (ideally cross platform?)
@starseeker, @Sean, I think, this is more a general architectural discussion now:
Cross platform: yes, Open source: no. However, here are some principles and practice:
For the OS part, I use Qt. Doing this for every OS separately with its low-level functions would be error-prone and like a hare and tortoise game, when they decide to change something in their API for the new version. I.e., I do shared library handling with Qt.
There, I search for something like
BRLCAD_MODULE_EXPORT void RegisterBrlCadModule(BrlCadModuleRegisterCallback& callback);
in the shared libraries. (In fact, it's C call and it looks for a RegisterBrlCadModule only.)
If RegisterBrlCadModule
is found, it will be executed with a BrlCadModuleCallback
object, which has methods like
void RegisterGedCommand(GedCommand* (*create)(BRLCAD::Core&)
const char* commandName,
const char* helpString);
I.e., what's typed after commandName will be handed over to the corresponding GedCommand
object.
Then, there are the "call-backs" to the core. One could imagine to make the important librt functionality, which cannot reached via BRLCAD::Database
, accessible via a BRLCAD::Core
object. But libbu stuff?
This can be done as a header-only implementation. For more complex objects, an additional source file can be provided, which had to be compiled and linked to the module's binary.
The memory management needs special attention. When the core and the module use different registries, one side cannot free what the other allocated. This already happens when booth sides where build with different versions of MS Visual Studio.
This issue can be solved by providing virtual functions for features, which require allocation or freeing of heap memory. Sometimes, even destructing of objects had to be done this way.
Reviving an old architecture discussion thread, love it! That diagram should be revisited, but it's an interesting reminder that relates to this discussion as well.
Qt to me is fine for apps to use, particularly as a layer to OS facilities, just as STL and Boost are -- but would be a significant architectural change to put underneath libbu for example, which nominally serves the same purpose but is more directly tested and dependency-free. To balance the hare and tortoise game (which is practically non-existent for fundamental OS constructs), we've been adopting C11 and C++17 (and STL accordingly) underneath libbu. I think that works pretty well.
Before diving deeper, though -- some sanity checks. Are you describing what moose is currently doing, what you'd like it to do, what you think some brl-cad lib should be doing/providing for a general callback mechanism?
There is no "BRLCAD" library (at least not canonically) to register against at present, but libbu would nominally be the place to have a global publish-subscribe callback API that librt and/or libged and/or moose could use..
Therefore, MOOSE doesn't do it and I don't plan to implement it. I'ts just the requested example translated to BRL-CAD.
starseeker said:
Hmm. So I guess what you'd ideally like from the main BRL-CAD build would be a single libbrlad.so with everything (including all the plugins) included? And basically have some mechanism for the libged initializer to recognize that it already has the commands and doesn't need to try to load shared libraries?
@starseeker, this is a much more general question ;)
However, the real question is: What do you want? What does the Army want? You Army people keep heavily committing. I cannot compete with you.
Usual development goals would be "easy to use" and "easy to contribute to", but you are moving in the opposite direction. I made myself a bit independent of it by using my C++ core interface. There, I handled the changes in the main BRL-CAD in the DLL, keeping its API stable. But with the changes in the build system, I don't know if it is still possible to build the usual brlcad.dll. I would need to say bext that it shall use static C-runtime linking, which doesn't work in general for sure, but maybe for the stuff needed to build the core libraries. This is some work I plan for the time after I got my new office PC.
BTW, because I don't need the ged stuff, I don't care much about the issues connected with it.
Daniel Rossberg said:
Therefore, MOOSE doesn't do it and I don't plan to implement it. I'ts just the requested example translated to BRL-CAD.
Been thinking about how something like this could be implemented more generally.
Seems like it has elements of bu_cmdtab (which is a simple string to function callback mechanism), but with some semblance of library scoping/registration, maybe auto-loading/unloading.
Do like the idea of implementing a more general publish/subscribe mechanism that extends to library callers. There is already the cmdtab interface in libbu that binds
The mechanism sounds almost identical to what Tcl itself does during library loading. A special init function that can be automatically found and executed, which in turn performs registration.
Think that could possibly address the issue of a library being combined into another static as it wouldn't find that one, but then the one it could find (e.g., libbrlcad) could call any other static lib init function(s).
Last updated: Aug 07 2025 at 01:01 UTC