Create a User Coordinate System

Description

Demonstrates the creation of a user coordinate system at the end of a selected sketch curve or edge.

Code Samples

"""This file acts as the main module for this script."""

import traceback
import adsk.core
import adsk.fusion

# Initialize the global variables for the Application and UserInterface objects.
app = adsk.core.Application.get()
ui  = app.userInterface


def run(_context: str):
    """This function is called by Fusion when the script is run."""

    try:
        des = adsk.fusion.Design.cast(app.activeProduct)
        if not des:
            ui.messageBox('No active Fusion design', 'Error')
            return

        root = des.rootComponent

        # Have a sketch curve selected by the user.
        sel = ui.selectEntity('Select a sketch curve or edge.', "SketchCurves, Edges")
        if not sel:
            return

        # Get the entity and its associated geometry.
        entity = sel.entity
        geom = None
        if isinstance(entity, adsk.fusion.BRepEdge):
            edge: adsk.fusion.BRepEdge = entity
            geom = edge.geometry    
        elif isinstance(entity, adsk.fusion.SketchCurve):
            curve: adsk.fusion.SketchCurve = entity
            geom = curve.worldGeometry

        # Make sure the selected curve is not a circle or ellipse. Closed curves are not supported.
        if isinstance(geom, adsk.core.Circle3D) or isinstance(geom, adsk.core.Ellipse3D):
            ui.messageBox('Please select a sketch curve that is not a circle or ellipse.', 'Error')
            return
        
        # Determine which end of the curve the selection was closest to.
        selPnt = sel.point
        curveEval: adsk.core.CurveEvaluator3D = geom.evaluator # type: ignore
        (_, selParam) = curveEval.getParameterAtPoint(selPnt)
        (_, startParam, endParam) = curveEval.getParameterExtents()
        (_, lengthToStart) = curveEval.getLengthAtParameter(startParam, selParam)
        (_, lengthToEnd) = curveEval.getLengthAtParameter(selParam, endParam)
        isAtStart = True
        if lengthToStart > lengthToEnd:
            isAtStart = False

        # Set the ratio along the curve where the construction plane will be placed,
        # either at the start (0) or the end (1) of the curve, depending on which end
        # of the curve the user selected.
        if isAtStart:
            distanceVal = 0
        else:
            distanceVal = 1

        # Add a construction plane normal to the curve at the specified ratio along the curve.
        planeInput = root.constructionPlanes.createInput()
        planeInput.setByDistanceOnPath(entity, adsk.core.ValueInput.createByReal(distanceVal))
        constPlane = root.constructionPlanes.add(planeInput)

        # Create a sketch on the construction plane.
        sk = root.sketches.add(constPlane)

        # Add a UCS using the origin point of the sketch, which will be
        # at the end of the selected curve.
        geomInput = adsk.fusion.UserCoordinateSystemGeometry.createByPoint(sk.originPoint)
        ucsInput = root.userCoordinateSystems.createInput(geomInput)
        ucs = root.userCoordinateSystems.add(ucsInput)

        # Group the results in the timeline.
        group = des.timeline.timelineGroups.add(constPlane.timelineObject.index, ucs.timelineObject.index)
        group.name = 'UCS Normal to Curve'
            
    except:  #pylint:disable=bare-except
        # Write the error message to the TEXT COMMANDS window.
        app.log(f'Failed:\n{traceback.format_exc()}')