The Problem
Engineers need a scriptable, fully‑Python CAD kernel that can be embedded in CI pipelines, Jupyter notebooks, or back‑end services. Existing solutions either require a heavy GUI stack or expose only a limited subset of OCCT features, making automated parametric modeling cumbersome.
What This Does
The repository provides a pure‑Python API that wraps the Open CASCADE Technology (OCCT) kernel. Core geometry lives in cadquery/occ_impl/*.py (e.g., shapes.py, geom.py, assembly.py). High‑level helpers such as cadquery/cq.py, cadquery/assembly.py, and the selector library cadquery/selectors.py let users build and query models with a fluent “Workplane” style (Workplane, Vector, box, extrude, etc.).
Documentation (doc/), a full test suite (tests/), and numerous Jupyter‑ready examples (examples/) illustrate usage from simple blocks to complex assemblies.
How It Is Wired
Execution starts at the CLI entry point cadquery/cq_directive.py:run (line 218). That function parses command‑line arguments and ultimately invokes the public API (e.g., Workplane, Assembly).
- The most‑used symbols—
Workplane,Vector,box,faces,val,size,extrude—are defined acrosscadquery/cq.py,cadquery/occ_impl/shapes.py, andcadquery/occ_impl/geom.py. They are called from 277, 218, 173 distinct places respectively, giving them the widest blast radius.
cadquery/occ_impl/shapes.pyalone defines 351 functions and 13 classes, is imported by 40 other files, and calls into eight lower‑level modules. It therefore acts as a hub; any change ripples broadly.
cadquery/assembly.pyandcadquery/occ_impl/assembly.pytogether manage hierarchical assemblies, exposing methods such asadd,remove, andsolve. They are called from 27 files and perform the only observed external effect: a filesystem write viaos.makedirsin themain → run_constructorpath (see What Each File Is Responsible For).
- The import graph contains 22 circular dependencies, notably among
cadquery/__init__.py,cadquery/occ_impl/shapes.py, andcadquery/occ_impl/geom.py. These cycles increase cognitive load and risk accidental breakage when refactoring.
- The internal call graph shows dense coupling:
test_constraint_solver → constrain(45 calls) andtestSweep → Workplane(28 calls), confirming that the test suite exercises the core API heavily.
How To Use It
# Clone the fork
git clone https://github.com/moses-y/cadquery
cd cadquery
# Install in editable mode (requires a working OCCT wrapper, e.g., the OCP package)
pip install -e .
No additional configuration files are required; the package reads no environment variables.
Run a script or notebook that imports the top‑level package:
import cadquery as cq
result = (
cq.Workplane("XY")
.box(10, 20, 5)
.faces(">Z")
.hole(2)
)
result.exportStep("example.step")
The cq_directive.py script can be invoked directly for command‑line modelling:
python -m cadquery.cq_directive --script examples/Ex001_Simple_Block.py --export step
Real‑World Use
A manufacturing pipeline can generate a custom bracket per order:
def make_bracket(width, height, thickness):
return (
cq.Workplane("XY")
.box(width, height, thickness)
.faces(">Z")
.hole(5)
)
bracket = make_bracket(120, 80, 10)
bracket.exportStl("bracket.stl")
The generated STL can be fed to downstream slicers without manual CAD interaction.
Code Health & Issues
- High – soundness – 22 import cycles (e.g.,
cadquery/__init__.py↔occ_impl/shapes.py). - High – cognitive_load – oversized files (
shapes.py,geom.py,selectors.py≈ 5 k lines). - High – cognitive_load – deep nesting (max depth 6) in the same large modules.
- High – clarity – hub module
cadquery/__init__.pyimported by 53 other modules. - Medium – resource_safety –
open(...)without context manager intests/__init__.py,occ_impl/exporters/svg.py,setup.py. - Medium – resilience – broad
except:blocks inocc_impl/importers/dxf.py,cq_directive.py,cqgi.py. - High – clarity – duplicated 6‑line code blocks across >20 files.
All findings are derived from deterministic static analysis; no additional issues were observed.
The Bottom Line
The fork delivers a functional, well‑documented Python wrapper around OCCT, suitable for automated parametric modelling and integration into CI or Jupyter workflows. However, the core modules are large, tightly coupled, and contain import cycles, which will increase maintenance effort for any substantial modification. Teams comfortable with deep refactoring or willing to isolate stable API surfaces will benefit most.