| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Four capability pillars. Every case below is a real, reproducible session: the replay demos are single-file offline HTML pages that faithfully replay the full recorded conversation (user turns, agent thinking, every tool call and patch, role switches) next to the exported 3D model — open them directly in a browser.
Parametric parts authored as readable Feature Tree Convention feature blocks — named parameters with units, verifier-first staged modeling, deterministic face tags that survive re-parameterization, and synchronized .scadpkg / STEP AP242 / STL / editable FreeCAD exports.
Turntables are rendered by the in-repo [Scene Viewer](viewer/)'s BRep renderer (face shading + wide edges); one full turn = 48 deterministic azimuth steps driven through `viewer/gif-harness.html`.| Case | First-turn requirement (excerpt) | Delivered model · BRep turntable |
|---|---|---|
| Robotic-arm U-link + motor mount 15 user turns · 601 tool calls ▶ Full session replay |
"Build a parametric robotic-arm link that adapts to length changes and mounts motors generically: sweep a circular profile down D → right L → up D into a U; cut motor sockets with spheres; the mounting face must carry a deterministic name indexable by the query language; split the bottom cylinder into a half cylinder; then fillet everything." | ![]() |
| Parametric flange plate 2 user turns · 66 tool calls ▶ Full session replay |
"Parametric flange: OD 100, thickness 10, hub ⌀55 top +30, bore ⌀30, 6×⌀11 bolt holes on PCD 78, hub-root R3 / rim R2 fillets; every dimension a named parameter; edge-selection cards printed before each fillet; parameter-feasibility guards; one feature per block." GIF shows the final 8-hole @PCD 84.5 state: turn 2 re-parameterized 6→8 holes; PCD 88 was rejected live by the guards and 85 excluded for fillet tangency. |
![]() |
| Ribbed L-bracket (FEM main model) 2 user turns · 49 tool calls ▶ Full session replay |
"Formalize the existing legacy L-bracket script through the single-part workflow: rebuild with FTC feature blocks and named parameters; geometric equivalence to the legacy model (volume delta < 0.1%); the interface.* FEM boundary tags must survive untouched — the downstream Gmsh/CalculiX pipeline selects faces by them." | ![]() |
Nested durable assemblies with explicit kinematics: gear meshes, revolute joints, and bearing interfaces are solved constraints, not eyeballed positions. Standard parts — involute gears, ball bearings (as subassemblies with individual balls), roller-chain sprockets, metric fasteners with real thread profiles — come from scad.std.* and compose into mechanisms that export to STEP, editable FreeCAD projects, and MJCF for physics engines.
Reproduce it: uv run python examples/integrated_bldc_joint_actuator/main.py builds the package from scratch; render_showcase.py renders the views above; export_all.py emits STEP / editable FCStd / MJCF.
Import a STEP, inspect its BREP in the browser, and click the geometric entities you care about — each pick lands as a tag in an annotation composer next to operation intents (sketch · boolean · fillet · pattern …) and a free note. Your reverse-engineering hunches ride on concrete face tags, so the agent receives a narrowed search space instead of guessing from scratch — and the whole human-agent session is recorded and replayable.
![]() re-studio MVP — click faces on the STEP target, stack operation chips and notes per pick, submit; the agent classifies all 37 faces of a link rod and starts rebuilding from your context · ▶ full video |
The same parametric package feeds downstream solvers without manual rework: AP242 STEP into Gmsh for volume meshing and CalculiX for static FEM (boundary faces are selected by preserved interface.* tags, so simulation survives model revisions), and MJCF into MuJoCo for mechanism dynamics — where a virtual-collision pass catches assembly interference and drives the correction before the mechanism runs clean.
![]() L-bracket static FEM — CalculiX von Mises meshed via Gmsh OpenCASCADE kernel from the AP242 export |
![]() Four-bar linkage + MuJoCo — first assembly pass: the links crash through each other mid-cycle; the assembly is wrong · ▶ full video |
![]() After the virtual-collision correction — corrected assembly: the full crank cycle sweeps clean in the same sim · ▶ full video |
Release notice: Pre-release (beta). Validate generated definitions, assembly constraints, and manufacturing geometry before production use.
SimpleCADAPI 2.1.3b1 ships the addon ecosystem: a sca CLI that installs third-party skill+tooling repositories (sca addon init/add/update/remove/list), a strict sca-addon.toml descriptor with platform and [compat] sca gates, and a consumer-facing .scadpkg format spec written so an agent given the document alone can produce a correct parser or exporter. See the full English update notes for the CLI contract, the two legal integration modes, and the tag channel; 2.1.2's script-anchored part cache is described in docs/updates/2.1.2.md.
All formal single-script examples emit a synchronized .scadpkg, AP242 .step, and editable .FCStd from the same product package. The split AP242/Gmsh example under examples/ap242_gmsh_volume_mesh/ exposes each build and export stage as a separate directly runnable script.
This repository is an artifact of
CADIR: A Cross-Backend Editable Intermediate Representation for Agentic CAD Generation
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 release: simplecadapi==2.1.3.
pip install simplecadapiWith uv:
uv add simplecadapiFor local development from this repository:
uv sync --group devAfter installing with pip above, install the bundled skill for your agent harness:
sca skill targets
# Default location (~/.agents/skills), or select ZCode's explicitly:
sca skill install --target zcode --skills-dir ~/.zcode/skillstargets lists the available harness targets. install compiles the bundled source and writes it to <skills-dir>/simplecadapi; without --skills-dir, it uses the existing addon configuration/environment resolution, falling back to ~/.agents/skills; sca init is not required. The wheel includes the uncompiled docs/skill/ source tree and skillproj.toml as package resources — compilation happens on install, no repository checkout needed. With uv, prefix these commands with uv run.
install fails if the destination already exists. Add --force to replace it only if it is a directory whose SKILL.md declares the matching skill name (simplecadapi); unrelated directories cannot be overwritten.
from pathlib import Path
import simplecadapi as scad
out = Path("out")
@scad.part(id="bracket")
def build_bracket() -> scad.Solid:
base = scad.make_box_rsolid(
width=60.0, height=36.0, depth=8.0, bottom_face_center=(0.0, 0.0, 0.0)
)
hole = scad.make_cylinder_rsolid(
radius=5.0, height=14.0, bottom_face_center=(0.0, 0.0, -3.0)
)
slot = scad.make_box_rsolid(
width=18.0, height=8.0, depth=14.0, bottom_face_center=(14.0, 0.0, -3.0)
)
body = scad.cut_rsolid(base, hole, slot)
boss = scad.make_cylinder_rsolid(
radius=8.0, height=7.0, bottom_face_center=(-18.0, 0.0, 8.0)
)
return scad.apply_tag(
shape=scad.union_rsolid(body, boss),
tag="role.demo.bracket",
)
result = build_bracket()
package_path = out / "bracket.scadpkg"
scad.capture(result, package_path)
print("volume", round(result.part.body.get_volume(), 3))
print("tags", scad.list_tags(shape=result.part.body))
scad.exporter.export_product_package_to_step(package_path, out / "bracket.step")
scad.exporter.export_product_package_to_stl(package_path, out / "bracket.stl")
scad.exporter.export_product_package_to_obj(package_path, out / "bracket.obj")Use an explicit GraphSession when a geometry flow should be inspectable, serializable, replayable, or translated into another CAD environment.
import simplecadapi as scad
from simplecadapi import GraphSession, export_model_json, replay_model_json
from simplecadapi import ql as Q
with GraphSession(graph_id="chamfered_block") as session:
body = scad.make_box_rsolid(
width=40.0, height=24.0, depth=10.0,
bottom_face_center=(0.0, 0.0, 0.0),
)
cutter = scad.make_cylinder_rsolid(
radius=4.0, height=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(kind="circle"))
.order_by(Q.center_axis(axis="z"))
.take(1)
.exactly(1)
)
final = scad.chamfer_rsolid(solid=drilled, edges=bottom_circle, distance=0.6)
session.capture_result(value=final)
model_json = export_model_json(session=session)
recorded_nodes = session.graph.node_count
rebuilt = replay_model_json(json_str=model_json)
print("recorded_nodes", recorded_nodes)
print("replayed_outputs", len(rebuilt))An explicit GraphSession remains in memory until an export API is called. For a durable CAD/viewer deliverable, define one physical single-solid part with @scad.part or an assembly with @scad.assemble, then capture and write it in one call:
scad.capture(result, "out/product.scadpkg")The package embeds the definition closure, evaluated scene, feature graphs, source snapshots, topology, and render/selection assets. STEP, STL, FCStd, and low-level JSON remain explicit exports.
Use @scad.part for one physical single-solid part and @scad.assemble for an assembly with explicit external definitions. Both use the unified CachePolicy; same-key part calls reuse the runtime PRT in process, while durable part bundles persist unchanged PRTs across later runs.
@scad.part(id="mounting_plate", cache="auto")
def build_plate(width: float = 30.0) -> scad.Part:
body = scad.make_box_rsolid(width=width, height=20.0, depth=3.0)
return scad.make_part_rpart(part_id="mounting_plate", body=body)
cold = build_plate()
warm = build_plate()
print(cold.cache_report.hit, warm.cache_report.hit)Inspect or maintain the cache with stable JSON output:
sca cache status
sca cache verify
sca cache pruneSee the persistent cache and product build workflow for cache modes, configuration precedence, PRT reuse, incremental invalidation, corruption repair, and destructive-command confirmation.
scad.capture(warm, "out/mounting_plate.scadpkg")
scad.translator.freecad_translator.translate_product_package_to_fcstd(
"out/mounting_plate.scadpkg", "out/mounting_plate.FCStd"
)
scad.exporter.export_product_package_to_step(
"out/mounting_plate.scadpkg", "out/mounting_plate.step"
)
scad.exporter.export_product_package_to_stl(
"out/mounting_plate.scadpkg", "out/mounting_plate.stl"
)
scad.exporter.export_product_package_to_obj(
"out/mounting_plate.scadpkg", "out/mounting_plate.obj"
)Export the standard delivery set (AP242 STEP, binary STL, and OBJ) from a validated product package with no wrapper script:
uv run sca export out/mounting_plate.scadpkg --output-dir out/exportsRequest additional targets explicitly. FCStd requires FreeCADCmd (or an explicit --freecad-cmd path); --check validates the package, output paths, and selected target prerequisites without writing files.
uv run sca export out/mounting_plate.scadpkg \
--format fcstd --format mjcf --output-dir out/exports --check
uv run sca export out/mounting_plate.scadpkg \
--format fcstd --freecad-cmd /path/to/FreeCADCmd --output-dir out/exportsSTL and OBJ share one direct OpenCASCADE tessellation of the evaluated BREP. Both outputs contain the same oriented triangles and require no optional remeshing dependency. Control curved-surface accuracy with linear_deflection and angular_deflection_degrees.
The AP242/Gmsh example also includes an optional CalculiX FEM workflow. Install the Python-side FEM dependencies with uv sync --extra fem, and install the external CalculiX solver separately (on macOS: brew install costerwi/homebrew-calculix/calculix-ccx). The example uses consistent mm, N, and MPa units:
uv run --extra fem python examples/ap242_gmsh_volume_mesh/run_calculix.py \
--ccx "$(brew --prefix calculix-ccx)/bin/ccx_2.23"
uv run --extra fem python examples/ap242_gmsh_volume_mesh/visualize_calculix.py
uv run --extra fem python examples/ap242_gmsh_volume_mesh/study_mesh_convergence.py \
--ccx "$(brew --prefix calculix-ccx)/bin/ccx_2.23" \
--linear-solver "ITERATIVE CHOLESKY" --solver-timeout 2400The analysis writes CalculiX .inp, .dat, .frd, solver-log, summary JSON, ParaView .vtu, and displaced von-Mises PNG artifacts. The preview shows the load physical group's yellow boundary and red -Z force arrows without covering the stress heatmap. The convergence study supports --resume; failed solver levels are reported separately and never enter the numerical sequence.
The checked-in -1000 N study evaluates eleven mesh sizes from h=3.0 mm to h=0.25 mm. A platform requires three consecutive refinement pairs below 5% maximum-displacement change and 10% peak integration-point von-Mises change. The verification level N is h=0.25 mm (0.0331843 mm, 98.6392 MPa), so the recommended production level N-1 is h=0.27 mm. Fine levels use iterative Cholesky after a same-mesh comparison at h=0.375 mm matched SPOOLES within 0.005%; this avoids the direct solver's in-memory capacity limit.
Install the optional rendering dependency when synchronized STEP views, highlighted regions, or slice overlays are needed:
pip install "simplecadapi[inspect]"Inspection lives under simplecadapi.inspect.brep. These APIs are diagnostic tools, not modeling operations: they do not enter the graph and are rejected inside GraphSession. Export or obtain the geometry first, then inspect it outside the modeling script.
Choose calls from the evidence required by the case instead of following a fixed reverse-engineering pipeline. Start with bounded global and local facts; add sections, component renders, boundary distance, material difference, or strict topology comparison only when those facts answer the current question.
from simplecadapi.inspect import brep
summary = brep.inspect_step_rsummary(
path="target.step",
include_parameter_groups=True,
)
face = brep.inspect_step_entity_rdescriptor(
path="target.step",
entity_id="face:0",
)
print("faces", summary["face_count"])
print("carrier", face["geometry"]["type"])Use the Reconstruction Agent test specification for controlled runs and the STEP BREP reverse-engineering guide for the inspection primitives, modeling loop, replay checks, and acceptance gates.
Declare nominal and manufacturing-tolerance units at the variable boundary. SimpleCAD evaluates lengths in millimeters and angles in degrees while preserving the declaration units in model JSON:
import simplecadapi as scad
width = scad.var(
"width",
1.0,
unit="in",
tolerance=0.1,
tolerance_unit="mm",
)
height = scad.var("height", 40.0, unit="mm", tolerance=0.2)
diagonal = scad.sqrt(width**2 + height**2)
analysis = scad.analyze_tolerance(diagonal)
check = scad.check_tolerance(diagonal, 0.3, tolerance_unit="mm")
print(analysis.dimension.name, analysis.unit.symbol)
print(analysis.nominal, analysis.lower_bound, analysis.upper_bound)
print("passes", check.passed)Addition and subtraction require matching dimensions. Multiplication, division, integer powers, and square root derive dimensions. Trigonometric functions require angle or dimensionless inputs as appropriate. Legacy variables without unit remain supported, but cannot be mixed with unit-declared variables in one expression.
script = scad.translator.freecad_translator.translate_product_package_to_freecad_script(
package_path
)
scad.translator.freecad_translator.translate_product_package_to_fcstd(
package_path, "bracket.FCStd"
)Part/Assembly models are written as editable FreeCAD assembly structure: parts are App::Part, assemblies are Assembly::AssemblyObject, and components are links. The exporter namespace owns neutral STEP and STL file output.
Every example is a self-contained folder: sources, verification scripts, and fresh artifacts under examples/<name>/out/. The set covers part modeling, assemblies, reverse engineering, and FEM — see the category index in examples/README.md.
# part (quickstart FTC example, external verification script included)
uv run python examples/flange_plate/model.py
# assembly (two-stage planetary reducer, MJCF export)
uv run python examples/compact_two_stage_planetary_reducer/main.py
# FEM (AP242 STEP -> Gmsh volume mesh -> Calculix statics)
uv run python examples/ap242_gmsh_volume_mesh/model.py
uv run --extra fem python examples/ap242_gmsh_volume_mesh/run_calculix.pyReverse engineering runs through the browser studio in viewer/re.html against a target STEP (see examples/bowl_connector/).
The skill source tree lives under docs/skill/ and stays harness-neutral. tools/skillbuild.py wraps the same compiler the sca skill CLI uses, for maintainer builds in this repository: it compiles per harness target (targets and default output directories are configured in skillproj.toml; the outputs under skills/simplecadapi-*/ are regenerable build artifacts and are not committed). Harness-specific text, when it is ever needed, is marked with <!-- skill:if ... --> conditional blocks that compile per target. The wheel itself never contains precompiled targets — end users install from the bundled source with sca skill install.
From a clean checkout, update the project version and documentation, then build and validate the release artifacts:
uv sync --group dev
uv run python tools/auto_docs_gen.py --quiet
uv run python tools/skillbuild.py --target omp
uv run pytest test/test_skill_build.py
tar -C skills -czf skills/simplecadapi.tar.gz simplecadapi-ompThe commands regenerate the API references inside the skill tree, recompile the omp target, and create skills/simplecadapi.tar.gz. Review the source tree and the compiled output before release:
git diff -- docs/skill
tar -tzf skills/simplecadapi.tar.gz | headCommit only the docs/skill/ source tree; the release workflow builds the harness outputs and uploads the archive to the GitHub release. Prefer sca skill for installation from a pip-installed package.
uv sync --group dev
uv run python -m pytest test tests
python3 -m compileall src/simplecadapiApache-2.0, see LICENSE.
The group chat currently has too many members for direct QR-code joining. Scan the QR code below to add Teacher Du Peng on WeChat, then ask him for an invitation to the CADDesigner technical community:
| Back | FazBrowse Home | New Git URL |