Digital Handstand
← Back to FlywheelCAD
Reference
FlywheelCAD icon

Python Syntax

Public command reference for the FlywheelCAD Python API.

A FlywheelCAD document is ordinary Python. The app runs that Python through the bundled flywheelcad module, which emits CAD commands that are then parsed and replayed by the app.

from flywheelcad import *
cad = FlywheelCAD()

Working with an AI coding assistant? There is a compact, machine-oriented version of this reference — the rules, the full API, and worked patterns in one Markdown file you can drop into the assistant's context: download the AI scripting guide.

Setup and Helpers

FlywheelCAD() Creates or returns the shared API object. Multiple calls return the same singleton, which keeps variable naming and origin references consistent across helper modules.
cad.with_sketch(plane_name) Switches the active sketch context to a plane such as "xy", "yz", "zx", or a custom plane name.
cad.origin(plane_name) Returns the origin ref for a sketch plane. Standard origins such as origin_xy are auto-injected; custom origins appear as origin_<plane_name> once a plane is used.
ref(name) Creates a symbolic reference by name. Useful when a valid CAD symbol exists but is not bound as a Python variable in the current scope.
region(loop, holes=None, inside=None) Builds a region intent for body commands. loop is the directed outer boundary — the boundary elements in traversal order. holes is a list of inner boundary loops, and inside is an optional (x, y) material point used to disambiguate when two regions trace the same loop.
rev(ref) Marks a boundary element as traversed against its intrinsic direction inside a region loop (equivalent to prefixing the element name with -).

Geometry Creation

cad.point2d(x, y) Creates a 2D point in the active sketch plane and returns a point ref.
cad.line2d(p1, p2, construction=False) Creates a line between two point refs. Set construction=True for guide geometry.
cad.circle2d(center, radius, construction=False) Creates a circle from a center point ref and numeric or variable radius.
cad.ellipse2d(focus1, focus2, point, construction=False) Creates an ellipse from two foci and one boundary point.
cad.spline2d(points, closed=False, construction=False) Creates a spline through a list of point refs. Set closed=True for a closed spline.
cad.arc2d(center, start, end, clockwise=False, construction=False) Creates an arc from center, start, and end points. Use clockwise=True when needed.
cad.trim(element, near) Trims an element near a supplied (x, y) location. Returns the surviving element ref and a secondary split ref when trim produces two pieces.
cad.fillet(element1, element2, radius) Rounds the corner where two elements — lines or arcs, in any combination — share an endpoint: both retract to the tangent points and a tangent arc of the given radius bridges them, with tangency and radius constrained so the fillet stays valid when the sketch re-solves. The element refs keep referring to the retracted elements; the returned arc slots between them in region loops: region(loop=[l1, f1, l2, ...]). Also available in the UI: select the two elements, then Modify → Fillet Corner… or the fillet toolbar button.

Geometric Constraints

cad.horizontal(line)Makes a line horizontal in the current sketch plane.
cad.vertical(line)Makes a line vertical in the current sketch plane.
cad.parallel(line1, line2)Constrains two lines to remain parallel.
cad.perpendicular(line1, line2)Constrains two lines to be perpendicular.
cad.collinear(line1, line2)Places two lines on the same infinite line.
cad.coincident(p0, p1)Makes two points share the same location by merging them (an alias for merge_points).
cad.pointlinecoincident(point, line)Places a point onto a line.
cad.pointoncircle(point, circle)Constrains a point to lie on a circle.
cad.pointonellipse(point, ellipse)Constrains a point to lie on an ellipse.
cad.pointonplane(point, plane)Constrains a point reference onto a plane object.
cad.concentric(circle1, circle2)Makes two circles share a center.
cad.equallines(line1, line2)Makes two line lengths equal.
cad.equalradius(circle1, circle2)Makes two circle radii equal.
cad.circletangentline(circle, line)Makes a circle tangent to a line.
cad.circletangentcircle(circle1, circle2)Makes two circles tangent to each other.
cad.ellipsetangentline(ellipse, line)Makes an ellipse tangent to a line.
cad.splinetangentline(spline, line)Makes a spline tangent to a line.
cad.symmetryline(...)Advanced symmetry constraint around a sketch line. Use keyword arguments such as point refs and the symmetry line ref.
cad.symmetryplane(...)Advanced symmetry constraint around a plane, used through keyword arguments.

Dimensions and Variables

cad.variable(value=None, fixed=False, driving=False) Creates a scalar variable ref such as d1. Use it in dimensions directly or inside arithmetic expressions. fixed=True pins the value; driving=True exposes it as an editable driving dimension.
cad.distance(p0, p1, distance)Sets the distance between two points. Keyword or positional form is supported.
cad.length(line, length)Sets a line length.
cad.radius(circle, radius)Sets a circle radius.
cad.angle(line1, line2, angle=None)Constrains the angle between two lines. If the angle is omitted, the app records the relation without a fixed value.
cad.pointlinedistance(point, line, distance)Sets the perpendicular distance from a point to a line.
cad.fraction(...)Advanced fractional constraint helper. Pass keyword arguments only.
width = cad.variable(80, fixed=True)
clearance = cad.variable(12)
cad.length(line, width * 2 + clearance)

Updates and Editing Helpers

cad.merge_points(source, target)Merges two points so they become one shared point in the model.
cad.mirror(elements, symmetry_line)Mirrors a list of elements across a symmetry line.
cad.update(changes)Updates existing geometry properties, usually point coordinates such as {p1: {"x": 10, "y": 20}}.
cad.ensure_convergence()Forces an explicit sketch solve when a script wants to converge before continuing.
cad.label_offset(key, dx, dy)Adjusts a dimension or annotation label offset by key.

Bodies, Analysis, and Custom Planes

cad.extrude(plane, region, distance, direction=None, quality=None, edge_radius=None, offset=None, draft=None, twist=None, twist_center=None)Creates a solid by extruding a region on a given plane. Returns a body ref. edge_radius fillets every edge of the prism uniformly — the vertical corners as well as the top and bottom rims. offset shifts the whole body along the plane normal (0 starts on the plane; negative is allowed). draft tapers the walls by an angle in degrees (positive slopes outward, negative inward), measured from the sketch-side face. twist rotates the cross-section as it rises (degrees over the full height) about twist_center (default: the region centroid) — this is how the helical and herringbone gear examples are built.
cad.revolve(plane, region, axis, angle, quality=None, edge_radius=None)Creates a revolved body from a region and selected axis line.
cad.loft(start_plane, start_region, end_plane, end_region, quality=None, edge_radius=None)Creates a lofted body between two regions on different planes (the planes may be non-parallel). Either side also accepts a list of regions, which are unioned into one composite profile.
cad.multi_loft(planes, regions, quality=None, edge_radius=None)Lofts one smooth solid through N ≥ 2 cross-sections (a plane name and a region per section) with continuous curvature between stations — no internal seams, unlike chaining two-section lofts with unions. This is how the sample aircraft fuselages and wings are built.
cad.bool_union(*bodies, quality=None, blend=None, radius=None)Creates the boolean union of two or more bodies. blend="smooth" or "chamfer" with a radius rounds or bevels the seam.
cad.bool_difference(*bodies, quality=None, blend=None, radius=None)Subtracts later bodies from the first body.
cad.bool_intersection(*bodies, quality=None, blend=None, radius=None)Keeps only the shared volume between bodies.
cad.offset(body, distance)Shells a body outward (positive) or inward (negative) by an SDF offset.
cad.set_cell_size(body, cell_size) / body.set_cell_size(...)Pins an absolute mesh resolution (model units per cell) for one body, overriding the quality preset’s model-size-relative grid. Use it when a small feature — a thin slot, a fine engraving — needs finer sampling than the preset gives on a large model.
cad.delete_body(body) / body.delete()Deletes a body, cascading to any boolean or offset bodies built from it.
cad.section(body, plane)Creates a section curve of a body on a target plane.
cad.project(body, plane)Projects body silhouette-style geometry onto a target plane.
cad.project_point(point, plane)Projects a topology point onto another plane.
cad.create_sketch_plane(p1, p2, p3, name=None)Creates a named custom sketch plane from three 3D points or topology refs.
Body refs: body-producing commands return refs that expose topology points such as body1.v0, body1.v1, or similar names. Those are what you pass into create_sketch_plane(...), project_point(...), or helper functions that need body topology.

Body Transforms, Colors, and Export

cad.move(body, dx=0, dy=0, dz=0)Translates a body. All transforms are keep-both: the source stays and a new body ref is returned.
cad.rotate(body, axis=(0, 0, 1), angle=0, center=(0, 0, 0))Rotates a body by an angle in degrees about an axis through center.
cad.scale(body, factor=None, sx=None, sy=None, sz=None)Scales a body uniformly (factor) or per axis.
cad.mirror_body(body, plane="yz")Mirrors a body across a standard or custom plane.
cad.copy(body)Duplicates a body in place (identity transform).
cad.set_color(body, color, finish=None) / body.set_color(...)Sets a display color (named color or hex) and an optional finish — "matte", "glossy", "metallic", or "glass". Colors carry into .3mf export.
body.set_export(False)Excludes a body from .3mf export (intermediate construction bodies).

Components and Assemblies

Components define a reusable part once and place it many times. A component body is written flat inside a with cad.component(...) block — blocks never nest; larger structures nest by instancing other components. A component that is never instanced is transparent: it builds the top-level design, so a component file opened directly behaves like a normal editable part.

with cad.component("bracket"):
    cad.with_sketch("xy")
    # ... sketch + region ...
    body = cad.extrude("xy", r, 5)
    cad.set_color(body, "steel", finish="metallic")
    cad.export(body)                                  # assembly-visible part
    cad.export_point("hole", cad.point(10, 0, 0))     # named anchor for mating

b1 = cad.instance("bracket")
b2 = cad.instance("bracket", translate=(50, 0, 0), mirror="zx")
cad.mate_coincident(b2, "hole", b1.hole, offset=(0, 0, 5))
with cad.component(name):Defines a component scope. Everything inside builds the component's own sub-design.
cad.export(body, name=None)Marks a body as a visible part of the component. Multi-body components export several; each surfaces on an instance as <instance>_<name>.
cad.export_point(name, point)Promotes a reference point as a named anchor. Each instance exposes it as <instance>.<name> (e.g. b1.hole) for mates and assembly geometry.
cad.parametric(prefix, build, **params)Builds a distinct component per parameter set (memoized by parameters) from a flat build() function — the pattern behind the parametric wing in the sample aircraft.
cad.instance(component, translate=None, mirror=None, scale=None, axis=None, angle=None, center=None)Places a component into the assembly. Transforms compose in a fixed order (scale, rotate, mirror, translate). Returns a body ref usable anywhere a body is — booleans, transforms, set_color.
cad.mate_coincident(instance, anchor, target, offset=None)Closed-form snap: moves the instance so its named anchor coincides with a target point (plus an optional offset).
cad.mate_align(instance, anchor1, anchor2, target1, target2, offset=None)Snap and orient: places anchor1 on target1 and aligns the anchor1→anchor2 direction with target1→target2.
cad.mate(instance, anchor, target)Solved mate: several mate() calls on one instance are solved together as a 6-DOF pose (three point mates fully fix position and orientation).
Multi-file assemblies: component files live next to the assembly file and are pulled in with plain import fuselage — the import defines the component, the assembly places instances and mates them. The included Glider and Airplane samples are complete worked examples, including nested sub-assemblies that re-export parts and anchors of their own children.

Component Libraries

Catalog parts come from component libraries — folders of parametric part modules. A standard library ships in the app; add your own as folders under ~/Documents/FlywheelCAD/Libraries/. A library factory takes cad first and returns a component name, so it drops straight into the assembly flow — call it, then cad.instance(...) the result and mate to its exported anchors.

from lib.standard.steppers import stepper
from lib.standard.bearings import bearing

part = stepper(cad, size=17, length=40)     # a NEMA 17, 40 mm long
motor = cad.instance(part, translate=(0, 0, 0))
brg = cad.instance(bearing(cad, designation="608"))
cad.mate_coincident(brg, "bore", motor.shaft_tip)

Inserting through Component → Insert from Library… is copy-on-use: the module is vendored into the document’s lib/<library>/ folder (with a provenance header, shown as a read-only tab), so the design stays self-contained and a later library update never silently changes it. The standard library modules:

lib.standard.steppersstepper(cad, size=17, length=None, body="square") — NEMA 8/11/14/17/23 stepper motors, square or round body.
lib.standard.servosservo(cad, size="standard"), horn(cad, style="single", spline="standard") — hobby servos and control horns.
lib.standard.fastenerscap_screw, hex_nut, washer, clearance, tap (cad, thread="M3", ...) — metric hardware and the matching holes.
lib.standard.bearingsbearing(cad, designation="608", flanged=False) — deep-groove ball bearings.
lib.standard.extrusionsrail(cad, profile="2020", length=100.0) — T-slot aluminum extrusion (20/30/40 series).
lib.standard.linkageball_link, clevis, pushrod (cad, ...) — RC linkage hardware.
Standalone parts: to place a loose component .py that isn’t in a library, use Component → Insert Component from File… — it copies the file into the project and appends the import + instance lines. The MotorMount sample is a full standard-library showcase.

Including a Separate Python File

Put the helper module next to the main script you open in FlywheelCAD. The app executes the document using that folder as the working directory, so sibling imports work directly.

MyProject/
  gearbox.py
  CADgears.py
  CADpolygons.py
from flywheelcad import *
from CADgears import gear_outline
from CADpolygons import regular_polygon

cad = FlywheelCAD()

cad.with_sketch("xy")
regular_polygon(center_x=0, center_y=0, side_count=6, radius=80, plane_name="xy")
gear = gear_outline(center_x=180, center_y=0, tooth_count=18, module=5.0, plane_name="xy")
gear_body = cad.extrude("xy", gear["region_ring"], 24, quality="high")

This is the same pattern used by the included test projects, especially the gear examples.

Flat file or project bundle: a document is either a plain .py (helper modules and any vendored lib/ sit next to it) or a .fwcad project bundle — a folder whose main.py is the script, packaging every imported file so it travels as one self-contained item. The import rules are identical either way. To pull an existing helper into the project, use File → Add File to Project… (it copies the file in under an importable module name); File → Convert to Project Bundle… and Export as Flat Script… convert between the two formats.