Interactive BRL-CAD Ray Tracer (IBRT) is an interactive graphical raytracing application for viewing BRL-CAD .g databases and other geometry files through Intel OSPRay and BRL-CAD ray tracing. This repository is not just a small viewer app. It also contains:
- a full OSPRay source tree (fork)
- a standalone build for a custom
ospray_module_brl_cadplugin - a Qt desktop viewer application
- a render worker process used to keep expensive rendering work off the UI thread
- superbuild scripts for fetching and building OSPRay dependencies
The viewer can load:
- BRL-CAD
.gdatabases - OBJ meshes
When a BRL-CAD file is loaded:
- the app enumerates selectable top-level objects from the database
- the user selects a specific object or region to render
- the custom OSPRay BRL-CAD module loads that object into OSPRay scene data
- the viewer progressively renders the result in a Qt
QOpenGLWidget
When an OBJ file is loaded:
- the viewer uses TinyObjLoader
- the mesh is converted into OSPRay geometry and models
- the same progressive rendering pipeline is used
- OSPRay provides the rendering engine.
- A custom BRL-CAD geometry module teaches OSPRay how to render BRL-CAD geometry.
- The Qt viewer provides the desktop UI.
- A helper worker process performs rendering and scene loading out-of-process.
QtOsprayViewer/QtOsprayViewerThis is the desktop application and worker executable source.brl_cad_standaloneThis builds the customospray_module_brl_cad.dll.modules/pluggableGeometryExample/brl_cad_moduleThis is the BRL-CAD geometry module implementation used by the standalone module build.scripts/superbuildThis builds OSPRay and its third-party dependencies into an install tree.ospray,modules,apps,cmakeThese are the OSPRay source tree and related modules included in the repo.
At runtime the typical flow is:
IBRT(Interactive BRL-CAD Ray Tracer) starts.- OSPRay is initialized and the CPU device is created.
- The main Qt window starts.
- The UI launches
IBRTRenderWorker.exe. - The UI and worker connect over a Windows named pipe.
- The user opens a scene.
- The worker or local backend loads the scene into OSPRay.
- Camera and renderer settings are pushed to the backend.
- Frames are progressively rendered.
- The UI displays the latest image and overlays controls/stats via ImGui.
The worker exists for responsiveness and isolation.
- scene loading can be expensive
- raytracing can stall the UI if performed directly on the main thread
- a separate process makes it easier to recover from worker crashes
- the UI can restart the worker and replay scene/camera state
QtOsprayViewer/QtOsprayViewer/main.cppApplication entry point. Initializes OSPRay, installs Windows crash/error helpers, starts Qt.QtOsprayViewer/QtOsprayViewer/mainwindow.cppMain application window, menus, demo model selection, BRL-CAD object selection.QtOsprayViewer/QtOsprayViewer/renderwidget.cppMain viewport widget. Handles input, progressive rendering, overlay UI, camera movement, async scene loading.QtOsprayViewer/QtOsprayViewer/ospraybackend.cppCore rendering backend. Owns OSPRay renderer/camera/world/framebuffers and progressive render logic.QtOsprayViewer/QtOsprayViewer/renderworkerclient.cppUI-side IPC client that launches and communicates with the worker.QtOsprayViewer/QtOsprayViewer/worker_main.cppWorker process main loop.QtOsprayViewer/QtOsprayViewer/worker_ipc.cppNamed-pipe message framing and transport helpers.QtOsprayViewer/QtOsprayViewer/interactioncontroller.cppMaps mouse/modifier combinations into translate/rotate/scale actions.
brl_cad_standalone/CMakeLists.txtStandalone build recipe forospray_module_brl_cad.modules/pluggableGeometryExample/brl_cad_moduleBRL-CAD geometry plugin sources.
osprayOSPRay core API and implementation.modulesOSPRay CPU, denoiser, MPI, and example modules.appsOSPRay sample/tutorial applications.scripts/superbuildConvenience build system for OSPRay dependencies.
docOSPRay/related documentation content.CHANGELOG.mdHistorical change log.STYLEGUIDE.mdFormatting and style notes.
To run the viewer successfully on Windows, you need all of these pieces aligned:
- BRL-CAD build or install
- OSPRay install
- rkcommon install
- Embree install
- OpenVKL install
- TBB runtime
- Qt runtime
ospray_module_brl_cad.dllIBRT.exeIBRTRenderWorker.exe
The CMake files in this repo are already set up to copy most of the runtime DLLs into the output folder after build.
You should have the following installed for building on Windows (Linux and Mac are on-your-own):
- Visual Studio 2022
Required workload:
Desktop development with C++ - CMake 3.20 or newer
- Qt 6.x
Example:
C:\Qt\6.11.0\msvc2022_64 - ISPC Required to build the BRL-CAD OSPRay module
- BRL-CAD 7.42.0 or compatible build tree
- Git
You should also make sure:
cmakeis onPATHispc.exeis onPATH
The build order matters. Use this order:
- Build BRL-CAD
- Build OSPRay and dependencies with the superbuild
- Build the standalone
ospray_module_brl_cad - Build the IBRT Qt viewer
If you skip step 3, the viewer will start but BRL-CAD scene loading will fail because ospLoadModule("brl_cad") will not be able to find the module.
Example:
cd C:\brlcad-src
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config ReleaseImportant outcome:
- remember the BRL-CAD build/install prefix you will pass as
BRLCAD_PREFIX
This prefix must expose:
include\brlcadlib\rt.libor equivalentlib\bu.lib- runtime DLLs under
bin
This repository already includes scripts/superbuild, which is the recommended way to get a matching OSPRay dependency stack.
Example:
mkdir C:\ospray-build
cd C:\ospray-build
cmake -G "Visual Studio 17 2022" -A x64 `
-DINSTALL_IN_SEPARATE_DIRECTORIES=ON `
C:\BRLCADVisualizer\scripts\superbuild
cmake --build . --config ReleaseExpected result:
C:\ospray-build\install\osprayC:\ospray-build\install\rkcommonC:\ospray-build\install\embreeC:\ospray-build\install\openvklC:\ospray-build\install\tbb
INSTALL_IN_SEPARATE_DIRECTORIES=ONis useful because the Qt viewer CMake expects separate prefixes for multiple dependencies.- The superbuild can also build more than you need, but for this project the key outputs are OSPRay, rkcommon, Embree, OpenVKL, and TBB.
- The included
scripts/superbuild/README.mddescribes other options such as building TBB or Embree from source.
This produces the custom geometry module that OSPRay loads at runtime for BRL-CAD scenes.
Example:
mkdir C:\build-brlcad-module
cd C:\build-brlcad-module
cmake C:\BRLCADVisualizer\brl_cad_standalone -G "Visual Studio 17 2022" -A x64 `
-DOSPRAY_PREFIX=C:\ospray-build\install\ospray `
-DRKCOMMON_PREFIX=C:\ospray-build\install\rkcommon `
-DEMBREE_PREFIX=C:\ospray-build\install\embree `
-DOPENVKL_PREFIX=C:\ospray-build\install\openvkl `
-DBRLCAD_PREFIX=C:\path\to\brlcad\build
cmake --build . --config Release
cmake --install . --config ReleaseWhat this build does:
- builds a shared library named
ospray_module_brl_cad - compiles ISPC sources needed by the BRL-CAD geometry path
- links against OSPRay,
ospray_module_cpu, rkcommon, and BRL-CAD libraries - installs the DLL into
${OSPRAY_PREFIX}/libsoospLoadModule("brl_cad")can find it
OSPRay itself does not natively understand BRL-CAD databases. The module is the bridge.
Example:
mkdir C:\build-qt-viewer
cd C:\build-qt-viewer
cmake C:\BRLCADVisualizer\QtOsprayViewer\QtOsprayViewer -G "Visual Studio 17 2022" -A x64 `
-DCMAKE_PREFIX_PATH=C:\Qt\6.11.0\msvc2022_64 `
-DOSPRAY_PREFIX=C:\ospray-build\install\ospray `
-DRKCOMMON_PREFIX=C:\ospray-build\install\rkcommon `
-DEMBREE_PREFIX=C:\ospray-build\install\embree `
-DOPENVKL_PREFIX=C:\ospray-build\install\openvkl `
-DTBB_ROOT=C:\ospray-build\install\tbb `
-DBRLCAD_PREFIX=C:\path\to\brlcad\build
cmake --build . --config ReleaseIf the BRL-CAD module DLL is not in the expected auto-detected locations, provide it explicitly:
cmake C:\BRLCADVisualizer\QtOsprayViewer\QtOsprayViewer -G "Visual Studio 17 2022" -A x64 `
-DCMAKE_PREFIX_PATH=C:\Qt\6.11.0\msvc2022_64 `
-DOSPRAY_PREFIX=C:\ospray-build\install\ospray `
-DRKCOMMON_PREFIX=C:\ospray-build\install\rkcommon `
-DEMBREE_PREFIX=C:\ospray-build\install\embree `
-DOPENVKL_PREFIX=C:\ospray-build\install\openvkl `
-DTBB_ROOT=C:\ospray-build\install\tbb `
-DBRLCAD_PREFIX=C:\path\to\brlcad\build `
-DBRLCAD_OSPRAY_MODULE_DLL=C:\full\path\to\ospray_module_brl_cad.dllThe viewer CMake is more than a simple compile step. It also:
- builds the UI executable
- builds the worker executable
- copies OSPRay DLLs
- copies rkcommon DLLs
- copies Embree DLLs
- copies OpenVKL DLLs
- copies BRL-CAD DLLs
- copies TBB DLLs
- copies the BRL-CAD module DLL when available
- runs
windeployqt - copies
IBRTRenderWorker.exenext to the UI executable - removes bundled CRT DLLs that could conflict with the system-installed MSVC runtime
The Qt viewer target is QtOsprayViewer, but its output executable name is set to:
IBRT.exe
The worker executable is:
IBRTRenderWorker.exe
After build:
cd C:\build-qt-viewer\Release
.\IBRT.exeOn startup:
- OSPRay initializes
- the CPU device is created
- the main window opens
- the worker process starts
- the app may load a startup demo if one is found
Use:
File > Open Model...- choose a
.gfile - select the desired object from the hierarchy dialog
The app looks for demo models in:
modelsnext to the application binary- or
share/dbunderBRLCAD_INSTALL_PREFIX
The viewer supports two camera modes:
OrbitFly
It also supports two world up-axis conventions:
Z-UpY-Up
Orbit mode keeps a pivot around the scene center.
- rotating moves the camera around the pivot
- panning moves the pivot
- zoom changes camera distance
This is the default mode and is best for inspecting a loaded model.
Fly mode treats the camera like a free-moving observer.
- camera orientation is represented by yaw/pitch
- movement keys translate through the scene
This is better for interior or first-person exploration.
Mouse gestures are abstracted through InteractionController.
The code classifies a combination of:
- mouse buttons
ShiftCtrlAlt
into:
- translate
- rotate
- scale
- optional axis constraints
The viewer uses ImGui to draw a control overlay on top of the rendered image.
The overlay includes:
- stats
- render path information
- frame times
- accumulated frame counts
- renderer selection
- other runtime controls
The viewer exposes at least these renderer modes:
aoscivispathtracer
Fast, simple ambient occlusion rendering.
General scientific visualization style renderer with default lighting.
Higher quality physically-based rendering. Slower, but more realistic lighting.
The backend applies default light setups when scenes do not supply their own lighting.
Rendering is progressive, not single-shot.
That means:
- the app starts with lower-cost preview passes
- it refines over time
- once interaction stops, the renderer may accumulate more full-quality frames
OsprayBackend manages:
- renderer selection
- camera state
- scene world and instances
- framebuffers
- current render future
- progressive scale ladder
- accumulation behavior
- watchdog timeouts
- dynamic AO/sample backoff
The backend uses a progressive scale ladder:
168421
It starts coarse, then refines to full resolution.
When the user is actively manipulating the camera:
- the backend can temporarily reduce quality
- a preview render request may preempt a more expensive in-flight render
- accumulation is reset after camera changes
The backend tracks slow frames and has a watchdog timeout.
This is used to:
- cancel frames that are taking too long
- reduce AO cost if the renderer becomes too expensive for interactive use
The viewer and worker communicate using a Windows named pipe.
Shared protocol code lives in:
worker_ipc.hworker_ipc.cpp
Each message has:
- a magic number
- protocol version
- message type
- request ID
- payload size
- payload bytes
PingPongShutdownListBrlcadObjectsBrlcadObjectListLoadObjLoadBrlcadLoadResultResizeSetCameraResetAccumulationRequestFrameFrameDataSetRendererSetRenderSettings
The protocol is synchronous and request/response based.
- the client sends one request
- the worker returns one matching response
- request IDs ensure the response corresponds to the correct request
Responsibilities:
- install stderr filtering on Windows
- install unhandled-exception crash dump handling
- initialize OSPRay
- create the CPU device
- load the OSPRay CPU module
- start the Qt event loop
Responsibilities:
- own the main render widget
- own the render worker client
- create menus
- open models
- choose BRL-CAD objects
- expose demo models
- recover from worker disconnects
Responsibilities:
- present the rendered image
- handle mouse/keyboard input
- manage orbit/fly camera state
- start asynchronous scene loads
- maintain scene metadata
- show the ImGui overlay
- push camera/renderer state to the backend or worker
Responsibilities:
- own OSPRay
Renderer,Camera,World,Instance,FrameBuffer, andFuture - load OBJ scenes
- load BRL-CAD scenes
- compute bounds
- manage progressive rendering
- manage accumulation
- manage quality adaptation and watchdog behavior
Responsibilities:
- launch the worker executable
- connect to the named pipe
- send render-control requests
- request frames
- decode binary payloads returned by the worker
Responsibilities:
- create the named pipe
- initialize OSPRay in the worker process
- create a single
OsprayBackend - service incoming requests
- serialize responses back to the UI
CMAKE_PREFIX_PATHQt prefix, usually enough forfind_package(Qt6 ...)OSPRAY_PREFIXRKCOMMON_PREFIXEMBREE_PREFIXOPENVKL_PREFIXTBB_ROOTBRLCAD_PREFIXBRLCAD_OSPRAY_MODULE_DLLOptional explicit full path to the module DLLBRLCAD_OSPRAY_MODULE_DEPLOY_DIROptional extra directory of dependent DLLs to copy next to the viewer
OSPRAY_PREFIXRKCOMMON_PREFIXEMBREE_PREFIXOPENVKL_PREFIXBRLCAD_PREFIX
After a successful viewer build, the output directory should contain at least:
IBRT.exeIBRTRenderWorker.exe- OSPRay DLLs
- rkcommon DLLs
- Embree DLLs
- OpenVKL DLLs
- BRL-CAD DLLs
- Qt DLLs
ospray_module_brl_cad.dll
This repo includes a large OSPRay tree. That does not mean you must build the whole repo from the root CMakeLists.txt to use the viewer.
For the viewer workflow, the practical builds are:
scripts/superbuildbrl_cad_standaloneQtOsprayViewer/QtOsprayViewer
The root CMakeLists.txt is the OSPRay project root.
If you want to modify behavior, these are the most important starting points:
- add new UI/menu behavior:
QtOsprayViewer/QtOsprayViewer/mainwindow.cpp - change camera/input behavior:
QtOsprayViewer/QtOsprayViewer/renderwidget.cpp - change render scheduling or quality adaptation:
QtOsprayViewer/QtOsprayViewer/ospraybackend.cpp - change worker messages:
QtOsprayViewer/QtOsprayViewer/worker_ipc.hQtOsprayViewer/QtOsprayViewer/worker_main.cppQtOsprayViewer/QtOsprayViewer/renderworkerclient.cpp - change BRL-CAD geometry integration:
modules/pluggableGeometryExample/brl_cad_modulebrl_cad_standalone/CMakeLists.txt
BRL-CAD Visualizer / IBRT project code is licensed under the MIT License. See:
LICENSE
The repository also includes upstream OSPRay source and third-party notices. Those files keep their original license terms. See:
LICENSE.txtthird-party-programs.txt- other
third-party-programs-*.txtfiles - Do not replace upstream OSPRay/Intel headers with the project MIT header.