A simplified OCP-native CAD modeling Python API
Project description
SimpleCADAPI
SimpleCADAPI is an OCP-native Python SDK for building CAD models with clear, functional operations and replayable model graphs. It wraps OpenCascade geometry in a compact public API for creating solids, applying features, tagging semantic intent, querying topology, exporting manufacturing files, and translating recorded models into FreeCAD workflows.
Current beta: simplecadapi==2.0.0b4.
What It Provides
- OCP-native shape types:
Vertex,Edge,Wire,Face, andSolid. - Functional modeling operations for primitives, profiles, extrude, revolve, loft, sweep, booleans, transforms, patterns, fillets, chamfers, and shells.
- Replayable modeling with
GraphSession,export_model_json(...),import_model_json(...), andreplay_model_json(...). - Expression parameters with
var(...), arithmetic expressions, and serialized expression graphs. - QL selectors for geometry grounding, topology queries, and stable feature selections.
- Semantic tags through
apply_tag(shape, tag)andlist_tags(shape). - STEP/STL export and FreeCAD translation helpers for script or
.FCStdoutput.
Install
pip install simplecadapi
With uv:
uv add simplecadapi
For local development from this repository:
uv sync --group dev
Quick Start
from pathlib import Path
import simplecadapi as scad
out = Path("out")
out.mkdir(exist_ok=True)
base = scad.make_box_rsolid(60.0, 36.0, 8.0, bottom_face_center=(0.0, 0.0, 0.0))
hole = scad.make_cylinder_rsolid(5.0, 14.0, bottom_face_center=(0.0, 0.0, -3.0))
slot = scad.make_box_rsolid(18.0, 8.0, 14.0, bottom_face_center=(14.0, 0.0, -3.0))
part = scad.cut_rsolid(base, hole, slot)
boss = scad.make_cylinder_rsolid(8.0, 7.0, bottom_face_center=(-18.0, 0.0, 8.0))
part = scad.union_rsolid(part, boss)
part = scad.apply_tag(part, "role.demo.bracket")
print("volume", round(part.get_volume(), 3))
print("faces", len(part.get_faces()))
print("tags", scad.list_tags(part))
scad.export_step(part, str(out / "bracket.step"))
scad.export_stl(part, str(out / "bracket.stl"))
Replayable Modeling
Use GraphSession when a model should be inspectable, serializable, replayable,
or translated into another CAD environment.
import simplecadapi as scad
from simplecadapi import ql as Q
with scad.GraphSession() as session:
body = scad.make_box_rsolid(40.0, 24.0, 10.0, bottom_face_center=(0.0, 0.0, 0.0))
cutter = scad.make_cylinder_rsolid(4.0, 16.0, bottom_face_center=(0.0, 0.0, -3.0))
drilled = scad.cut_rsolid(body, cutter)
bottom_circle = (
Q.edges()
.where(Q.curve_type("circle"))
.order_by(Q.center_axis("z"))
.take(1)
.exactly(1)
)
final = scad.chamfer_rsolid(drilled, bottom_circle, 0.6)
model_json = scad.export_model_json(session)
rebuilt = scad.replay_model_json(model_json)
print("recorded_nodes", session.graph.node_count)
print("replayed_outputs", len(rebuilt))
Modeling Mental Model
- Start from design intent: reference axes, critical profiles, and the features that produce the final solid.
- Build from lower-dimensional geometry to higher-dimensional geometry: profile wires/faces first, then solid features such as extrude, revolve, loft, and sweep.
- Keep operations functional. Create new values with public functions such as
make_rectangle_rface(...),extrude_rsolid(...),cut_rsolid(...), andfillet_rsolid(...). - Use tags for semantic intent and selection anchors, for example
role.mounting.surface,anchor.datum.primary, orgroup.fasteners. - Store numeric and geometric facts in metadata or graph payloads, not in tags.
- Use QL to ground selections by geometry facts rather than relying on topology iteration order.
- When an indexed topology pick is intentional, pass the index to the plural
child-geometry getter, such as
get_edges(index),get_faces(index),get_wires(index), orget_vertices(index), so replayable graph workflows preserve the pick as a geo select node. - Use model JSON as the interchange boundary for replay, tests, and FreeCAD translation.
FreeCAD Translation
Recorded model JSON can be translated into a FreeCAD Python script:
script = scad.translate_model_json_to_freecad_script(model_json)
If FreeCAD or FreeCADCmd is available, the same model JSON can be written as an
.FCStd file:
scad.translate_model_json_to_fcstd(model_json, "bracket.FCStd")
Examples
Run examples from the source checkout:
uv run python examples/01_basic_modeling.py
uv run python examples/02_graph_replay.py
uv run python examples/03_expressions.py
uv run python examples/05_loft_sweep_revolve.py
uv run python examples/06_parametric_gear_model.py
uv run python examples/07_serialization_operation_tree.py
Documentation
- Public API reference:
docs/api/ - Core type and modeling notes:
docs/core/ - Serialization and replay details:
docs/core/serialization/README.md - Operation graph JSON spec:
docs/core/operation_graph_json_spec.md
Development
uv sync --group dev
uv run python -m pytest test tests
python3 -m compileall src/simplecadapi
License
MIT, see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simplecadapi-2.0.0b4.tar.gz.
File metadata
- Download URL: simplecadapi-2.0.0b4.tar.gz
- Upload date:
- Size: 218.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
160cfb8a413f69a34de3139cc8f21104aec028a484128cc619b119ec6815a6bb
|
|
| MD5 |
cb83d2e96d3dc9ba2dbd09ce6e4ac4ca
|
|
| BLAKE2b-256 |
d883591e83bb183e305c2e703c2e35963a91249a450cdada27af7ecf1ac4691c
|
File details
Details for the file simplecadapi-2.0.0b4-py3-none-any.whl.
File metadata
- Download URL: simplecadapi-2.0.0b4-py3-none-any.whl
- Upload date:
- Size: 276.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
061f1618a396c60a0481253f3580571e2e98aba12375adc6716a5f996f54142b
|
|
| MD5 |
4b55b58d4275216ca4d6434fac0f0fe2
|
|
| BLAKE2b-256 |
aae3c5e7d0c4e26c4ad5f24731127c74b12779320b4640a7bb576975e7d5b48b
|