BCad fork

Setting up BCad on macOS
Login

Setting up BCad on macOS

This guide explains how to build and run BCad — an OpenSCAD-style CAD application based on OpenCASCADE — on macOS (both Intel and Apple Silicon).

Note: The author does not own a Mac. This guide is provided as a reference for contributors who do. Please report issues and corrections at the Fossil forum.


Prerequisites

Install Homebrew first, then:

brew install cmake ninja python glfw pkg-config

Miniconda (for pythonocc-core)

pythonocc-core is not available on PyPI — it must be installed via conda:

brew install --cask miniconda
conda init "$(basename "$SHELL")"
exec $SHELL

After conda init, create a dedicated environment:

conda create -n bcad python=3.13 pythonocc-core -c conda-forge
conda activate bcad

This gives you OCCT native libraries and the OCC Python bindings in one step. Check that it works:

python -c "from OCC.Core.gp import gp_Pnt; print(gp_Pnt(1,2,3))"

Cloning the repository

BCad uses Fossil for version control, not git:

mkdir -p ~/src && cd ~/src
fossil clone https://asm32.info/fossil/bcad bcad.fossil
mkdir bcad && cd bcad
fossil open ../bcad.fossil

If you prefer read-only access, a git/svn mirror may exist; check the project page. Otherwise, fossil is a single static binary — just download it and put it in your PATH.

Alternatively, grab a source tarball from the project page.


Setting up the Python virtual environment

Although the conda environment provides pythonocc-core, it is cleaner to keep bcad's own dependencies in a venv managed by the project. We'll create one inside the conda environment so that OCC (which is conda-only) is importable:

# Make sure the 'bcad' conda env is active
conda activate bcad

cd ~/src/bcad
python -m venv --system-site-packages bcad.venv

The --system-site-packages flag lets the venv see OCC and other conda packages. The project's bcad-launcher script expects the interpreter at bcad.venv/bin/python3.

Now install pure-Python dependencies inside the venv:

source bcad.venv/bin/activate
pip install --upgrade pip
pip install glfw PyOpenGL Pillow ezdxf scipy numpy

Building imgui-bundle with bcad patches

BCad uses a customised version of imgui-bundle with:

The patched native extension must be compiled from source.

1. Initialise submodules

cd cpp/imgui_bundle
git submodule update --init --recursive

(If you cloned via fossil, the submodule .git data may be missing. In that case, run git init inside cpp/imgui_bundle/ first, add the upstream remote, then git submodule update.)

cd ../..  # back to project root

# Symlink the OpenSCAD language sources
IMGUI_EDITOR="cpp/imgui_bundle/external/ImGuiColorTextEdit/ImGuiColorTextEdit"
ln -sf ../../../../imgui/openscad_language/OpenscadLanguage.h "$IMGUI_EDITOR/"
ln -sf ../../../../imgui/openscad_language/OpenscadLanguage.cpp "$IMGUI_EDITOR/"

# Apply the patch
cd cpp/imgui_bundle
patch -p1 < ../../cpp/imgui/imgui_color_text_edit.patch

3. Build and install

cd cpp/imgui_bundle
source ../../bcad.venv/bin/activate

CMAKE_BUILD_PARALLEL_LEVEL=$(sysctl -n hw.ncpu) \
pip install . \
  --config-settings=build-dir=./build_py/ \
  --no-build-isolation

This compiles the native _imgui_bundle extension and installs it into the venv. The first build takes several minutes.

Incremental rebuild (after reapplying the patch):

cmake --build build_py -j$(sysctl -n hw.ncpu) --target _imgui_bundle
cp build_py/_imgui_bundle*.so ../../bcad.venv/lib/python3.13/site-packages/imgui_bundle/

OS-specific fixes

Multiprocessing start method

bcad/__main__.py currently sets 'fork' on non-Windows platforms:

if sys.platform != 'win32':
    multiprocessing.set_start_method('fork', force=True)

On macOS, fork is unreliable when combined with GUI frameworks (Cocoa/GLFW). Edit the file to use 'spawn' on Darwin:

if sys.platform == 'win32':
    pass
elif sys.platform == 'darwin':
    multiprocessing.set_start_method('spawn', force=True)
else:
    multiprocessing.set_start_method('fork', force=True)

(This is already what glfw_display.py uses internally for the worker process respawning — the change simply makes the top-level match.)

DejaVu Sans Mono font

The bundled font at assets/fonts/DejaVuSansMono.ttf is used automatically when found. If it is missing, the fallback path is:

/Library/Fonts/DejaVuSansMono.ttf

You can install the system-wide font via Homebrew if needed:

brew install --cask font-dejavu-sans-mono

or simply place the .ttf file at the expected path.

OpenGL context

BCad uses OpenGL 3.3 Core Profile. This works on macOS, but Apple deprecated OpenGL in macOS 10.14 (2018). The current implementation functions correctly on macOS 13 Ventura through macOS 15 Sequoia (Intel and Apple Silicon). If a future macOS version drops OpenGL entirely, the project will need to migrate to Metal or use a compatibility layer.


Running BCad

cd ~/src/bcad
source bcad.venv/bin/activate
python -m bcad

Or use the launcher script:

./bcad-launcher

CLI mode (no GUI)

python -m bcad --output out.stl file.scad

Packaging a .app bundle (optional)

For distribution you can create a self-contained macOS application bundle using PyInstaller (available via pip):

source bcad.venv/bin/activate
pip install pyinstaller

pyinstaller \
  --name BCad \
  --icon path/to/icon.icns \
  --add-data "assets:assets" \
  --hidden-import OCC \
  --hidden-import imgui_bundle \
  --collect-all OCC \
  --collect-all imgui_bundle \
  bcad/__main__.py

Important: Because pythonocc-core ships native .dylib files via conda, PyInstaller may not automatically bundle all of them. You will likely need a custom .spec file that explicitly collects OCCT libraries (libTK*.dylib). See the Linux AppImage build at packaging/build_appimage.sh for a comparable approach — the copy_deps.py script could be adapted for macOS.

For ad-hoc signing (required on Apple Silicon even for local runs):

codesign --force --sign - --deep dist/BCad.app

Known issues / caveats

Issue Status
OpenGL deprecated on macOS Works on current OS versions; future risk.
fork() start method Patched to spawn on Darwin at runtime.
pythonocc-core not on PyPI Requires conda; no way around it.
Ray-tracing renderer OCCT's ray-tracing may not work on Apple Silicon GPUs (lack of OpenCL/CUDA). Falls back to rasterisation.
Offscreen rendering OCCT's offscreen renderer may need a GL context. Use offscreenViewer3d with a hidden window on macOS.
imgui-bundle native build Build process is the same as Linux; only GLFW linkage differs.
Font rendering Freetype is bundled statically in imgui-bundle — no system dependency.

Getting help