Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to create a custom joint direction for a revolute joint motion?

Message 1 of 1
228 Views, 0 Replies

How to create a custom joint direction for a revolute joint motion?

I am trying to create a script using Fusion360 API to automatically generate a Bennett mechanism with basic geometry as the link.

Here is what a Bennett mechanism looks like.


So I need to joint two links as revolute joint but the joint axis is not a regular axis such xAxis or zAxis. I need to create a revolute joint axis with a twist angle.

Currently I think there are two ways:

1. Use customRotationAxisEntity when setting joinInput:

jointInput_var.setAsRevoluteJointMotion(rotationAxis, customRotationAxisEntity)

 but customRotationAxisEntity can only be linear BRepEdge, ConstructionAxis, or a SketchLine(Am I right?). This is not very convenient to set a custom rotation axis.

2. Change the jointOrign's axis at first and then use whatever axis for example xAxis:

# Set the value of the property.
jointOrigin_var.xAxisEntity = propertyValue


I am not sure with the second method so I try the first method. Here is my code:


import adsk.core, adsk.fusion,, traceback
import math

def generateBox(x, y, z, rootCom: adsk.fusion.Component) -> adsk.fusion.Component:
    generate a box component inside rootComponent
    box is a basic geometry element of SDF:
    x, y, z unit: m

    return: component generated by extrude object

    extrudes = rootCom.features.extrudeFeatures
    x = x*100.0 # convert from m to cm
    y = y*100.0
    z = z*100.0

    # Create a new sketch on the xy plane
    sketches = rootCom.sketches
    xyPlane = rootCom.xYConstructionPlane
    sketch = sketches.add(xyPlane)

    # Draw a rectangle on the xy plane
    point1 = adsk.core.Point3D.create(-x/2, y/2, 0.0)
    point2 = adsk.core.Point3D.create(x/2, y/2, 0.0)
    point3 = adsk.core.Point3D.create(x/2, -y/2, 0.0)
    point4 = adsk.core.Point3D.create(-x/2, -y/2, 0.0)

    sketch_lines = sketch.sketchCurves.sketchLines
    line1 = sketch_lines.addByTwoPoints(point1, point2)
    line2 = sketch_lines.addByTwoPoints(point2, point3)
    line3 = sketch_lines.addByTwoPoints(point3, point4)
    line4 = sketch_lines.addByTwoPoints(point4, point1)

    # Get the profile defined by the four lines
    prof = sketch.profiles.item(0)

    # Define the distance to extrude
    distance = adsk.core.ValueInput.createByReal(z)
    # extrude = extrudes.addSimple(prof, distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
    extrude = extrudes.addSimple(prof, distance, adsk.fusion.FeatureOperations.NewComponentFeatureOperation)
    return extrude.parentComponent

def rotateZ(degree)->adsk.core.Matrix3D:
    retrun a transform matrix to rotate about world frame's z-axis with degree
    rotZ = adsk.core.Matrix3D.create()
    rotZ.setCell(0, 0, math.cos(math.radians(degree)))
    rotZ.setCell(1, 0, math.sin(math.radians(degree)))
    rotZ.setCell(2, 0, 0.0)
    rotZ.setCell(3, 0, 0.0)

    rotZ.setCell(0, 1, -math.sin(math.radians(degree)))
    rotZ.setCell(1, 1, math.cos(math.radians(degree)))
    rotZ.setCell(2, 1, 0.0)
    rotZ.setCell(3, 1, 0.0)

    rotZ.setCell(0, 2, 0.0)
    rotZ.setCell(1, 2, 0.0)
    rotZ.setCell(2, 2, 1.0)
    rotZ.setCell(3, 2, 0.0)

    rotZ.setCell(0, 3, 0.0)
    rotZ.setCell(1, 3, 0.0)
    rotZ.setCell(2, 3, 0.0)
    rotZ.setCell(3, 3, 1.0)

def run(context):
    ui = None
        app = adsk.core.Application.get()
        ui  = app.userInterface

        textPalette = ui.palettes.itemById("TextCommands")
        if not textPalette.isVisible:
            textPalette.isVisible = True

        # doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        # design.designType = adsk.fusion.DesignTypes.ParametricDesignType
        design.designType = adsk.fusion.DesignTypes.DirectDesignType

        rootComp = design.rootComponent
        extBox = generateBox(0.1, 0.1, 1, rootComp)
        # textPalette.writeText("num of bRepBodies: {}".format(extBox.bRepBodies.count))
        extBody = extBox.bRepBodies.item(0)
        # textPalette.writeText("num of bRepFaces: {}".format(extBody.faces.count))
        extJointFace1 = extBody.faces.item(4) # item 4 is the end extrude face, item 5 is the start extrude face
        point1 = extJointFace1.centroid

        # for i in range(6):
        #     textPalette.writeText("bRepFace areas: {}".format(extBody.faces.item(i).area))

        # Create the joint geometry
        jointGeo = adsk.fusion.JointGeometry.createByPlanarFace(extJointFace1, None, adsk.fusion.JointKeyPointTypes.CenterKeyPoint)

        jointOrigins = extBox.jointOrigins
        jointOriginInput = jointOrigins.createInput(jointGeo)
        jointOrigin1 = jointOrigins.add(jointOriginInput)
        # jointXAxis = jointOrigin1.secondaryAxisVector

        extBox2 = generateBox(0.1, 0.1, 0.5, rootComp)
        extBody2 = extBox2.bRepBodies.item(0)
        extJointFace2 = extBody2.faces.item(4)
        jointGeo2 = adsk.fusion.JointGeometry.createByPlanarFace(extJointFace2, None, adsk.fusion.JointKeyPointTypes.CenterKeyPoint)
        jointOrigins2 = extBox2.jointOrigins
        jointOriginInput2 = jointOrigins.createInput(jointGeo2)
        jointOrigin2 = jointOrigins2.add(jointOriginInput2)

        # Define a axis of rotation
        # This can be a linear BRepEdge, ConstructionAxis, or a SketchLine
        sketches1 = extBox.sketches
        sketch = sketches1.add(extJointFace1)
        sketchOrigin = sketch.origin
        sketchOriginPoint = sketch.originPoint
        theta = 30 # degree
        sketchPoint1 = adsk.core.Point3D.create(0.0, 0.0, 0.0)
        sketchPoint2 = adsk.core.Point3D.create(math.cos(math.radians(theta))*10, math.sin(math.radians(theta))*10, 0.0)
        sketchLine = sketch.sketchCurves.sketchLines.addByTwoPoints(sketchPoint1, sketchPoint2)

        textPalette.writeText("sketch line isVisible: {}".format(sketchLine.isVisible))
        textPalette.writeText("sketch line is2D: {}".format(sketchLine.is2D))
        textPalette.writeText("sketch line length: {}".format(sketchLine.length))

        # Create jont
        joints = rootComp.joints
        jointInput = joints.createInput(jointOrigin1, jointOrigin2)
        # jointInput.setAsRevoluteJointMotion(adsk.fusion.JointDirections.XAxisJointDirection)
        jointInput.setAsRevoluteJointMotion(adsk.fusion.JointDirections.CustomJointDirection, sketchLine)
        joint1 = joints.add(jointInput)
        joint1Motion = joint1.jointMotion

        if ui:


But I got an RuntimeError:

joint1 = joints.add(jointInput)
RuntimeError: 2 : InternalValidationError : Utils::getObjectPath(object, objPath, nullptr, context)

 I don't know what is going on.

Can anyone help me with my error or tell me how to create revolute joint with custom axis?

Thanks a lot!


Labels (2)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th

Autodesk Design & Make Report