Skip to main content

CodeToCAD

CodeToCAD accelerates mechanical and electrical CAD design, simulations/FEA, controls software and MCU firmware by giving you one language to define your design — your script is federated to the modeling or design application automatically.

Install

pip install codetocad

Quick start (CLI)

codetocad init cup

This creates a cup/ folder with a cup.py file and opens an interactive menu to create parts and sketches, transform, boolean, shell, constrain and export them. Every action updates generated python part files (for example cup_cylinder.py), so the CLI extends to the full functionality of the CodeToCAD classes.

Run a script:

codetocad path/to/script.py

Quick start (Python)

import codetocad

body = codetocad.cylinder(radius="2cm", height="5cm")
body.shell(thickness="5mm")
body.set_material(codetocad.aluminum_material())
body.export("cup.stl")

Highlights

  • Units: floats are meters/radians; strings such as "2in", "10 deg" or expressions like "2in - 5mm" are parsed and converted.
  • Locations: 6-dof positions/orientations; CubeLocations shortcuts to the 23 topological locations of any shape's bounding cube; the @codetocad.location decorator marks named locations on your part classes.
  • Parts & assemblies: Part2D/Part3D with extrude, shell, fillet, chamfer, hole; Assembly2D/Assembly3D constraints (coincide, parallel, fixed, revolute, prismatic, ...) recorded in ledgers.
  • Primitives: cube, cylinder, sphere, rectangle, circle, text, import_file and material presets.
  • ECAD: led, diode, resistor, capacitor, inductor, voltage_source, current_source components (each a Part3D with pins, a value and a Footprint) wired into a Circuit of Nets — capture schematics with skidl and simulate with SPICE (below).
  • Mixins: sensors (CameraMixin, IMUMixin, MicrophoneMixin) and actuators (DCMotorMixin, BLDCMotorMixin) for custom parts.
  • Fasteners: CommonFasteners enum that can build() a part or apply features (clearance holes) to another part.

Build123D integration

Install the extra (uv sync --extra build123d) and your parts are federated to real OpenCascade solids — booleans, shells, fillets, chamfers, holes and transforms are replayed natively, and geometry queries, analysis and STL/STEP export use the native topology:

from codetocad_integrations.build123d import make_cube

if __name__ == "__main__":
    cube = make_cube("10cm", "10cm", "5cm")
    cube.hole(cube.top_center, radius="4cm", amount="5cm")
    cube.export("my_cube.stl")

Subclass codetocad_integrations.build123d.Part3D and override build_native() to model a custom base shape with the Build123D API; all CodeToCAD operations still apply on top. adapt(part) converts any core CodeToCAD part (including led(), resistor(), fasteners, ...) into a Build123D-federated one.

See codetocad_integrations/build123d/examples/ for the full gallery.

Blender integration

With Blender on your PATH (or CODETOCAD_BLENDER pointing at it), the same designs federate to Blender mesh objects — booleans, shells (solidify), fillets/chamfers (bevel), holes and transforms are replayed with modifiers, and you can export .stl, .obj, .glb, .fbx or a full .blend scene:

from codetocad_integrations.blender import ensure_blender, make_cube

if __name__ == "__main__":
    ensure_blender()  # relaunches this script under `blender --background`
    cube = make_cube("10cm", "10cm", "5cm")
    cube.hole(cube.top_center, radius="4cm", amount="5cm")
    cube.export("my_cube.blend")

Subclass codetocad_integrations.blender.Part3D and override build_native() to model with bpy/bmesh directly. See codetocad_integrations/blender/examples/.

Simulation (PyBullet & MuJoCo)

Model in Build123D or Blender, assemble with joint constraints, and import right into physics simulation — simulate(part) walks the assembly, exports the meshes and generates a URDF (PyBullet) or MJCF (MuJoCo):

from codetocad import Location
from codetocad_integrations.build123d import make_cube, make_cylinder
from codetocad_integrations.pybullet import simulate  # or ...mujoco

mount = make_cube("6cm", "6cm", "4cm", start_location=Location(z="52cm"))
rod = make_cylinder("1cm", "40cm", start_location=Location(z="30cm"))
pivot = Location.from_euler(0, 0, "50cm", x_deg=-90, name="pivot")
mount.revolute(pivot, rod, pivot)  # hinge about the Y axis

sim = simulate(mount, gui=True)
sim.set_joint_value("pivot", 1.0)
sim.run(10.0, realtime=True)

Joint axes come from the constraint Location's orientation, limits from min_limits/max_limits, masses/inertias from part materials and geometry, and codetocad.Lighting describes scene lights. Free-floating scene_parts (objects the robot can interact with) and a ground_plane complete the scene. See the examples in codetocad_integrations/pybullet/examples/ and codetocad_integrations/mujoco/examples/ (a 6-DOF arm with a parallel-jaw gripper that picks up a cube, pendulum, double pendulum).

FEA (CalculiX)

Analyze the same parts with finite elements — analyze(part) meshes the exported geometry with gmsh, applies fixtures/loads described with Locations, solves with CalculiX via pygccx, and returns displacement and von Mises stress fields with visualization:

from codetocad import steel_material
from codetocad_integrations.build123d import make_cube
from codetocad_integrations.calculix import analyze

beam = make_cube("200mm", "20mm", "10mm")
beam.set_material(steel_material())

fea = analyze(beam)
fea.fix(beam.left_center)                          # clamp the left face
fea.add_force(beam.right_center, force=(0, 0, -100))
results = fea.solve()
print(results.max_displacement, results.max_von_mises)
results.visualize("beam_fea.png")

Materials carry elastic properties (steel_material(), aluminum_material() or set youngs_modulus/poissons_ratio on any MaterialBase). The ccx solver is auto-discovered from CODETOCAD_CCX, the PATH, or ~/.codetocad/ccx/bin/ccx. See codetocad_integrations/calculix/examples/.

Visualization (Open3D)

Display any Part3D — core, Build123D- or Blender-federated — in an Open3D window, or render a screenshot headlessly for docs/CI:

from codetocad_integrations.build123d import make_cube
from codetocad_integrations.open3d import show, render

cube = make_cube("10cm", "10cm", "5cm")
cube.hole(cube.top_center, radius="4cm", amount="5cm")

show(cube)                          # interactive window
render(cube, path="cube.png")       # offscreen screenshot

The part is exported (part.export()) to a temporary mesh and loaded into Open3D, so it works with any backend — Open3D itself isn't a CAD kernel. See codetocad_integrations/open3d/examples/.

ECAD: schematics (skidl) & simulation (SPICE)

Describe a circuit once as a Circuit of components and nets, then federate it to schematic capture and circuit simulation — the same components are Part3Ds (each carries a Footprint), so they drop straight into a board assembly:

from codetocad import Circuit, resistor, voltage_source
from codetocad_integrations.skidl import export_netlist, export_schematic
from codetocad_integrations.spice import simulate

circuit = Circuit("divider")
v1 = circuit.add(voltage_source(dc=9))
r1, r2 = circuit.add(resistor("10k"), resistor("20k"))
circuit.connect(v1["+"], r1[1], name="VIN")
circuit.connect(r1[2], r2[1], name="VOUT")
circuit.connect(r2[2], v1["-"], circuit.gnd)

export_netlist(circuit, "divider.net")     # KiCad netlist (with footprints)
export_schematic(circuit, "divider.svg")   # schematic SVG (netlistsvg)

op = simulate(circuit).operating_point()
print(op.voltage("VOUT"))                   # 6.0

Schematics (skidl). codetocad_integrations.skidl converts a Circuit into a skidl circuit to run its ERC and write KiCad netlists/XML, and renders schematic SVGs with standard analog symbols via netlistsvg. Install with uv sync --extra skidl plus npm install -g netlistsvg. See codetocad_integrations/skidl/examples/.

Simulation (SPICE). codetocad_integrations.spice builds a SPICE netlist from the Circuit (diode/LED models are derived from each component's electrical properties) and runs it with ngspice: operating point, DC sweep, transient and AC analyses come back as numpy vectors with plot()/bode() helpers. Install with uv sync --extra spice plus ngspice (brew install ngspice / apt install ngspice). See codetocad_integrations/spice/examples/.

WebApp control panels

Any Part3D can double as a sensor or actuator via mixins (DCMotorMixin, EncoderMixin, IMUMixin, ...). Bind them to a Microcontroller's pins and a PythonApp/WebApp federates sliders, buttons, gauges and plots to the same JSON-lines wire protocol the firmware speaks:

from codetocad import Microcontroller, MicrocontrollerBoard, SerialCommunication, WebApp
from codetocad.mixins import DCMotorMixin, EncoderMixin

class GearMotor(DCMotorMixin):
    no_load_speed_rpm = 200

motor, encoder = GearMotor(), EncoderMixin()
mcu = Microcontroller("motor-lab", board=MicrocontrollerBoard.ESP32)
mcu.bind_actuator(motor, name="wheel", pwm_pin=5, dir_pin=18)
mcu.bind_sensor(encoder, name="enc", a=32, b=33)
mcu.set_communication(SerialCommunication("/dev/ttyUSB0"))

app = WebApp("motor lab").set_communication(mcu.communication)
app.add_slider("speed (rpm)", target=motor, command="velocity_rpm", maximum=200)
app.add_plot("measured rpm", source=encoder)
app.run()

PythonApp opens a native window instead of a browser page and RerunApp streams telemetry to the Rerun viewer instead — all three take the same Communication instance as the microcontroller so both ends agree, and EmulatedMicrocontroller can stand in for real hardware to drive a physics simulation instead (see Robotics, below). Install with uv sync --extra nicegui (or --extra rerun). See Microcontroller, Sensors/Actuators definition, and communication in the design doc for I2C/SPI/UART buses, wireless transports and signal filtering.

Robotics examples: putting it all together

codetocad_integrations/robotics/ contains examples that combine everything above into one script: MCAD (the assembled parts and joint constraints), ECAD (the microcontroller as an ElectricalComponent with pin bindings), an MCU definition (run by real firmware or, for simulation, an in-process EmulatedMicrocontroller), and a WebApp control panel — all driving the same physics simulation.

codetocad_integrations/robotics/turtlebot/ is a differential-drive TurtleBot3 Burger: real chassis/wheel/caster dimensions, Dynamixel XL430-W250 motor/encoder specs, an ESP32 Microcontroller definition, MuJoCo physics with velocity-controlled wheels, and a WebApp with motor sliders and encoder/pose readouts. Swapping the emulator for a SerialCommunication to a real board is the only change needed to drive physical hardware from the same app.

User-defined parts

Define a part with the API of your choice (for example Build123D):

import build123d
import codetocad

class Box(codetocad.Part3D):
    def build(self):
        length, width, thickness = 80.0, 60.0, 10.0
        with build123d.BuildPart() as ex1:
            build123d.Box(length, width, thickness)

    @codetocad.location
    def example_location(self):
        return codetocad.CubeLocations.top_center.translate(x="2cm", y="2mm")

See CodeToCAD.md for the full design document.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codetocad-2026.7.21.1.tar.gz (14.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codetocad-2026.7.21.1-py3-none-any.whl (13.9 MB view details)

Uploaded Python 3

File details

Details for the file codetocad-2026.7.21.1.tar.gz.

File metadata

  • Download URL: codetocad-2026.7.21.1.tar.gz
  • Upload date:
  • Size: 14.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.5

File hashes

Hashes for codetocad-2026.7.21.1.tar.gz
Algorithm Hash digest
SHA256 89ac026def1eedd15a72e1f48ab693bad9e7ced45a7dc6e93b36f649a27db18f
MD5 39e52d5291b5e4309ede82afad44ca99
BLAKE2b-256 87527d6d7b00219475bd1d46fa1b520f8935b348c91152a384f0717e84ab203e

See more details on using hashes here.

File details

Details for the file codetocad-2026.7.21.1-py3-none-any.whl.

File metadata

File hashes

Hashes for codetocad-2026.7.21.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ade8838172760d61d26076189046c8b3a931e9443a5ad96d227226716f435f56
MD5 97939fd5b45284fcc1803f753c12bd51
BLAKE2b-256 67af4eca1ca9dab158cbde56c60e1f389c12ad7d797a9b37800d424ea8f58632

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2026.7.21.1 This release

2 files

2026.7.12.1

2 files

2026.7.5.1

2 files

0.4.1728739615

1 file

0.4.1724941494

1 file

0.4.1724940935

1 file

0.4.1724940633

1 file

0.4.1724939499

1 file

0.4.1722578893

1 file

0.4.1721023072

1 file

0.4.1720759072

1 file

0.4.1720744869

1 file

0.4.1720743277

1 file

0.4.1720627362

1 file

0.4.1717883845

1 file

0.4.1717872560

1 file

0.4.1717872248

1 file

0.4.1717871676

1 file

0.3.1717870527

1 file

0.3.1708482556

1 file

0.3.1708472437

1 file

0.3.1706461487

1 file

0.3.1706314314

1 file

0.3.1706309916

1 file

0.3.1705640780

1 file

0.3.1705384971

1 file

0.3.1705382360

1 file

0.3.1705279324

1 file

0.3.1705265326

1 file

0.3.1705144291

1 file

0.3.1705142508

1 file

0.3.1705126403

1 file

0.3.1705123749

1 file

0.3.1704924643

1 file

0.3.1704844141

1 file

0.3.1704834051

1 file

0.3.1704833939

1 file

0.3.1704660481

1 file

0.3.1704408419

1 file

0.3.1704408104

1 file

0.3.1704326562

1 file

0.3.1704324223

1 file

0.3.1704260693

1 file

0.3.1704222678

1 file

0.3.1704175124

1 file

0.3.1704174805

1 file

0.3.1704174731

1 file

0.3.1704167479

1 file

0.3.1704030903

1 file

0.3.1703959257

1 file

0.3.1703954363

1 file

0.3.1702515808

1 file

0.3.1700706610

1 file

0.3.1700621010

1 file

0.3.1698517520

1 file

0.3.1698358837

1 file

0.3.1697595282

1 file

0.2.1697392626

1 file

0.2.1696130649

1 file

0.2.1695934326

1 file

0.2.1692691355

1 file

0.2.1690831405

1 file

0.2.1689920227

1 file

0.2.1689879910

1 file

0.2.1689450180

1 file

0.2.1689145860

1 file

0.2.1689143387

1 file

0.2.1688705312

1 file

0.2.1688153808

1 file

0.2.1688153771

1 file

0.2.1688052828

1 file

0.2.1688050852

1 file

0.2.1687733068

1 file

0.2.1687056821

1 file

0.2.1687027263

1 file

0.2.1686968696

1 file

0.2.1686965494

1 file

0.2.1686928791

1 file

0.2.1686927744

1 file

0.2.1686597428

1 file

0.2.1686597252

1 file

0.2.1686589396

1 file

0.2.1686581804

1 file

0.2.1686580357

1 file

0.2.1685760707

1 file

0.2.1685760038

1 file

0.2.1685733826

1 file

0.2.1685726498

1 file

0.2.1685724399

1 file

0.2.1685464328

1 file

0.2.1682499911

1 file

0.2.1682497971

2 files

0.2.1682485196

1 file

0.2.1681961608

1 file

0.2.1681948051

1 file

0.2.1679348919

1 file

0.2.1679348377

1 file

0.2.1679347994

1 file

0.2.1678822807

1 file

0.2.6

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page