Scripting in Fusion

The globals a fusionctl script gets, the API's centimetres, which way each sketch plane points, user parameters, and recipes taken from examples/bracket.py.

fusionctl exec and fusionctl run send Python to the add-in, which runs it on Fusion's main thread with the full adsk API. These notes were checked on Fusion 2705.1.30.

Globals

NameWhat it is
appadsk.core.Application
uiapp.userInterface (do not open dialogs with it, see below)
designthe active adsk.fusion.Design
rootdesign.rootComponent
adskthe adsk package (adsk.core, adsk.fusion, …)
mm(v)millimetres to the API's centimetres: mm(5) returns 0.5
P(x, y, z)adsk.core.Point3D.create
V(v)adsk.core.ValueInput.createByReal (API units)
VS(s)adsk.core.ValueInput.createByString, e.g. VS("12 mm") or VS("width / 2")

Anything else a script defines (variables, functions) stays available to the next exec or run until fusionctl reset or fusionctl new. The globals above are refreshed on every call, so design and root always point at the active document.

Returning values

print() output is captured and printed by the CLI. Set result to return a value as JSON:

fusionctl exec 'result = {"bodies": root.bRepBodies.count, "features": design.timeline.count}'

A value that is not JSON-serialisable is returned as its repr(). With --json, the CLI prints the whole reply, stdout and result included.

Units

The API works in centimetres and radians, whatever the document's display units. Writing millimetre numbers into Point3D makes the part ten times too large and raises no error.

P(mm(40), 0, 0)          # 40 mm along X
VS("12 mm")              # a length from an expression, stays parametric
VS("width / 2")          # an expression over user parameters

Prefer VS(...) with an expression for feature sizes, so the feature follows the parameters.

Sketch planes

For sketches created through the API on the origin planes:

Planesketch +Xsketch +Yextrude (+)
xYConstructionPlaneworld +Xworld +Y+Z
xZConstructionPlaneworld +Xworld −Z+Y
yZConstructionPlaneworld −Zworld +Y+X

On XZ, a point at world height z is P(x, -z, 0) in sketch coordinates. The bracket script keeps that in one helper:

xz = lambda x, z: P(x, -z, 0)  # world (x, z) -> XZ sketch coordinates

Sketches on body faces choose their own axes: check sketch.xDirection or convert with sketch.modelToSketchSpace(...).

Orientation

fusionctl ping reports orientation. On a Z-up install the print bed is the XY plane and +Z is up. On a Y-up install the floor is XZ. The bracket script assumes Z-up; check before you reuse it.

Parameters

Create user parameters first and refer to them by name in dimensions and features. Then fusionctl params --set changes the part and the timeline regenerates.

examples/bracket.py
params = {
    "length": "40 mm",      # base, along X
    "height": "30 mm",      # wall, along Z
    "width": "24 mm",       # along Y
    "thick": "4 mm",
    "hole_d": "4.5 mm",     # M4 clearance, ISO 273 medium
    "bend_r": "3 mm",       # inner fillet: stiffens the bend
    "bed_chamfer": "0.6 mm" # chamfer, not fillet, on edges touching the bed (elephant foot)
}
for name, expr in params.items():
    p = design.userParameters.itemByName(name)
    if p is None:
        design.userParameters.add(name, VS(expr), "mm", "")

The itemByName check makes the script safe to run twice in the same design.

Recipes from the bracket

Dimension a sketch to a parameter

Place the geometry at its current size, then dimension it and set the dimension's expression:

d = dims.addDistanceDimension(seg.startSketchPoint, seg.endSketchPoint, orient, at)
d.parameter.expression = "length"

Extrude symmetrically by a parameter

ext_in = root.features.extrudeFeatures.createInput(
    sk.profiles.item(0), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
ext_in.setSymmetricExtent(VS("width"), True)
ext = root.features.extrudeFeatures.add(ext_in)

Holes that follow the parameters

A bare sketch point does not move when parameters change. Dimension it to the sketch origin with an expression:

hs.sketchDimensions.addDistanceDimension(
    hs.originPoint, a, H_, P(x0, -W / 2 - 0.5, 0)
).parameter.expression = "thick + (length - thick) / 2"

Two sketch points that share an X cannot both get a horizontal dimension from the origin: Fusion reports VCS_SKETCH_OVER_CONSTRAINTS with no visible constraint. Dimension the first point fully, give the second only its Y, then tie the X:

hs.geometricConstraints.addVerticalPoints(a, b)

A hole drills against its sketch normal. From a sketch on the XY plane at the bed, that is −Z, away from the part. Drill up through the base with:

h_in.setAllExtent(adsk.fusion.ExtentDirections.NegativeExtentDirection)

Find a face or an edge by geometry

def face_at(normal, pred):
    for f in body.faces:
        ok, n = f.evaluator.getNormalAtPoint(f.pointOnFace)
        if ok and n.isEqualTo(normal) and pred(f.pointOnFace):
            return f
    raise RuntimeError("face not found")

outer = face_at(adsk.core.Vector3D.create(-1, 0, 0), lambda p: abs(p.x) < 1e-6)

The script selects the bend edge (a line along Y at x = z = thick) and the bed edges (lines at z = 0) the same way, then fillets and chamfers them with VS("bend_r") and VS("bed_chamfer"). It returns the edge counts in result, so a wrong selection shows up as a number.

Things that break a session

  • Modal dialogs. ui.messageBox, selection prompts and other dialogs block Fusion's main thread, so the bridge cannot answer and the CLI times out. Print instead.
  • Occurrences. New occurrences are grounded to their parent: setting occurrence.transform2 is ignored until occurrence.isGroundToParent = False. Then call design.snapshots.add() if design.snapshots.hasPendingSnapshot.
  • 3MF export. The API method is createC3MFExportOptions. fusionctl export part.3mf handles it.
  • Renamed methods. Older samples use names that have changed. Check with fusionctl apidoc ExtrudeFeatures.addSimple against the installed build instead of guessing.

Made by Lucas Piera. MIT licence. fusionctl is not affiliated with or endorsed by Autodesk; Autodesk and Fusion are trademarks of Autodesk, Inc.

fusionctl