Announcements
Due to scheduled maintenance, the Autodesk Community will be inaccessible from 10:00PM PDT on Oct 16th for approximately 1 hour. We appreciate your patience during this time.
Community
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.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Manufacturing (CAM) API Feedback

60 REPLIES 60
Reply
Message 1 of 61
prainsberry
7568 Views, 60 Replies

Manufacturing (CAM) API Feedback

With the latest Fusion 360 release, available starting today, you will see a huge increase in the APIs available for the manufacturing workspace.  This is a massive release, that I know many of you have been waiting for!

 

See here for a comprehensive list of these new capabilities.

 

You'll notice that all of the new Manufacture functionality is designated as being in "Preview". We're being cautious and releasing it as a preview, so we can react to problems and suggestions for improvement and be open to making changes that might break compatibility.

 

Please test it out and let us know in this thread:

  • If you find something that doesn't work.
  • If something doesn't make sense.
  • If the documentation needs to be improved.
  • Also, feel free to share successes with the capabilities.

Depending on the feedback we get, the plan is to take it out of preview after one or two major releases. 



Patrick Rainsberry
Developer Advocate, Fusion 360
60 REPLIES 60
Message 2 of 61
kandennti
in reply to: prainsberry

Thanks for the great work.

 

It would be useful to add a method to the PostConfiguration object that can income a list of post properties in the cps file.

I don't have an answer to this question, but perhaps there is no smart way to do this.

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/post-processor-and-pyton-script/td-p/11818... 

Message 3 of 61
MichaelT_123
in reply to: prainsberry

Great Job TF360,

 

Please check API page:

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-C6B71469-9BE3-46EE-B961-E254324DEB1F

There is missing reference link to:  

SectionAnalysisInput

 

Regards

MichaelT

MichaelT
Message 4 of 61
kandennti
in reply to: prainsberry

I created the following script thinking that DocumentToolLibrary could be easily copied by using the toJson and createFromJson methods of the DocumentToolLibrary object.

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.cam as cam
import json

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

        # アクティブドキュメントのツールライブラリ
        # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-C0A61669-1C70-4A68-8CAA-158108844FC7
        stateToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary
        ui.messageBox(f'Active DocumentToolLibrary Count:{stateToolLib.count}')
        if stateToolLib.count < 1:
            return

        # json化
        toolLibJson = stateToolLib.toJson()
        print(json.dumps(json.loads(toolLibJson), indent=2))

        # 新規ドキュメント
        app.documents.add(core.DocumentTypes.FusionDesignDocumentType)

        # 新規ドキュメントのツールライブラリ
        newToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary

        # 新規ドキュメントのツールライブラリにインポート
        newToolLib.createFromJson(toolLibJson)
        ui.messageBox(f'New DocumentToolLibrary Count:{newToolLib.count}')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def get_cam_product() -> cam.CAM:
    '''
    CAMの取得
    '''
    app: core.Application = core.Application.get()
    activete_cam_env()

    return app.activeProduct


def activete_cam_env() -> None:
    '''
    CAMアクティブ
    '''
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

    camWS: core.Workspace = ui.workspaces.itemById('CAMEnvironment') 
    camWS.activate()


No error was generated, but no tool was created in the newly created document.

(ver2.0.15775)

Please let me know if there is anything wrong with my method.

Message 5 of 61
kandennti
in reply to: kandennti

I misunderstood the return value of the createFromJson method.
It turns out that we can simply add without using json.

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.cam as cam

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

        # active doc toollibrary
        # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-C0A61669-1C70-4A68-8CAA-158108844FC7
        stateToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary
        ui.messageBox(f'Active DocumentToolLibrary Count:{stateToolLib.count}')
        if stateToolLib.count < 1:
            return

        # new doc toollibrary
        app.documents.add(core.DocumentTypes.FusionDesignDocumentType)
        newToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary

        # import tools
        [newToolLib.add(t) for t in stateToolLib]
        ui.messageBox(f'New DocumentToolLibrary Count:{newToolLib.count}')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Message 6 of 61
kandennti
in reply to: prainsberry

I tested changing the tool number.

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.cam as cam

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

        # Active Doc ToolLibrary
        activeToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary
        if activeToolLib.count < 1:
            return

        # get tool
        tool: cam.Tool = activeToolLib[0]

        # get tool_number Parameter
        prm: cam.CAMParameter = tool.parameters.itemByName('tool_number')

        # change tool_number
        prm.value.value += 1

        # ToolLibrary Update
        # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-34200AFB-2CC9-463D-8BCC-502F57D1E81B
        activeToolLib.update(tool, True)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def get_cam_product() -> cam.CAM:
    '''
    CAMの取得
    '''
    app: core.Application = core.Application.get()
    activete_cam_env()

    return app.activeProduct


def activete_cam_env() -> None:
    '''
    CAMアクティブ
    '''
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

    camWS: core.Workspace = ui.workspaces.itemById('CAMEnvironment') 
    camWS.activate()

 

I noticed that the tool number is not changed unless the DocumentToolLibrary.update method is used, but since the second argument in the document is listed as "updateFeedAndSpeed", I misunderstood that it was only about the cutting condition.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-34200AFB-2CC9-463D-8BCC-502F57D1E81B 

1.png

 

Also, even if the second argument is set to false, the update is still performed, so I did not understand what the parameter meant.

Message 7 of 61
kandennti
in reply to: kandennti

Sorry for repeating myself.


I understand the meaning of the second argument of the update method.

We create one tool and create a DRILL operation.
The settings are as follows

1.png

 

Next, run the script to halve the spindle speed.
The second argument is "True".

 

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.cam as cam

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

        # Active Doc ToolLibrary
        activeToolLib: cam.DocumentToolLibrary = get_cam_product().documentToolLibrary
        if activeToolLib.count < 1:
            return

        # get tool
        tool: cam.Tool = activeToolLib[0]

        # get preset
        presets: cam.ToolPresets = tool.presets
        preset: cam.ToolPreset = presets.itemsByName('Default preset')[0]

        # change spindleSpeed
        prm: cam.CAMParameter = preset.parameters.itemByName('tool_spindleSpeed')
        prm.value.value /= 2

        # ToolLibrary Update
        activeToolLib.update(tool, True)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def get_cam_product() -> cam.CAM:
    '''
    CAMの取得
    '''
    app: core.Application = core.Application.get()
    activete_cam_env()

    return app.activeProduct


def activete_cam_env() -> None:
    '''
    CAMアクティブ
    '''
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

    camWS: core.Workspace = ui.workspaces.itemById('CAMEnvironment') 
    camWS.activate()

 

 

The result is shown here.

1.png

The spindle speed has been halved on both the operation side and the tool library side.

 

 

Restore the spindle speed and modify the script.

 

・・・
        # ToolLibrary Update
        # activeToolLib.update(tool, True)
        activeToolLib.update(tool, False)
・・・

 

 

Here is the result of the script execution.

1.png

The tool library has been changed as intended.
The spindle speed of the operation is not changed, but Preset is changed to "Custom".

 

 

I understood the meaning of the second argument to be whether or not it affects the cutting conditions of the already created operation.
However, it should be noted that if "False" is selected, Preset will be changed to "Custom".

Message 8 of 61
Joshua.mursic
in reply to: prainsberry

Hello!

 

Is it possible to give the SetupInput an occurrences origin axis as an input? Or to give it a sketch line as an axis?

The expression just always says true if anything is selected, and the value is CadAxis no matter what is selected.

Being able to select a sketch or origin axis as an input would be really helpful in creating setups. The box point option works great for milling operations but is not available for turning operations.

# set setup origin
setup.parameters.itemByName('wcs_origin_boxPoint').value.value = SetupWCSPoint.TOP_XMIN_YMIN.value

 

 

Joshuamursic_0-1680815280764.png

Joshuamursic_1-1680815310749.png

 

 

Message 9 of 61
kandennti
in reply to: prainsberry

The sample code on the following page is broken because it is not displayed as code.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-6B9555DF-0F90-4F46-B3F6-EADE8A87C4C9 

1.png


Perhaps, this is a sample like this.

# Get a reference to the CAMManager object.
camMgr = adsk.cam.CAMManager.get()

# Get the ToolLibraries object.
toolLibs = camMgr.libraryManager.toolLibraries

# Get the URL for the local libraries.
localLibLocationURL = toolLibs.urlByLocation(adsk.cam.LibraryLocations.LocalLibraryLocation)

# Get the URL of the folder, which will be for the "CustomTools" folder.
f360FolderURLs = toolLibs.childFolderURLs(localLibLocationURL)
customToolsFolderURL = f360FolderURLs[0]

# Get the "CustomMilling" library.
f360LibraryURLs = toolLibs.childAssetURLs(customToolsFolderURL)

toolLib = None 
for libURL in f360LibraryURLs:
    if 'CustomMilling' in libURL.leafName:
        toolLib = toolLibs.toolLibraryAtURL(libURL)

# Find a specific tool.
for tool in toolLib:
    if tool.parameters.itemByName('tool_description').value.value == '1/16" Ball Endmill':
        return tool
    return None
return None
Message 10 of 61
kandennti
in reply to: Joshua.mursic

Hi @Joshua.mursic .

 

For SetupInput, it is stated to be set after it is created because there are only minimal inputs.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7F3F9D48-ED88-451A-907C-82EAE67DEA93 

 

I made a sample where Setup is created by Turning and the origin of WCS is the origin of the root component.

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.fusion as fusion
import adsk.cam as cam
import pprint

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

        # get cam object
        camObj: cam.CAM = get_cam_product()

        # create setup - turning
        setups: cam.Setups = camObj.setups
        setupIpt: cam.SetupInput = setups.createInput(cam.OperationTypes.TurningOperation)
        setup: cam.Setup = setups.add(setupIpt)

        # get origin point
        desRootOcc: fusion.Occurrence = camObj.designRootOccurrence
        root: fusion.Component = desRootOcc.component
        origin: fusion.ConstructionPoint = root.originConstructionPoint

        # set wcs mode
        wcsModePrm: cam.CAMParameter = setup.parameters.itemByName('wcs_orientation_mode')
        wcsModeValue: cam.ChoiceParameterValue = wcsModePrm.value
        pprint.pprint(wcsModeValue.getChoices())
        wcsModeValue.value = 'coordinateSystem'

        # set wcs origin
        wcscSysPrm: cam.CAMParameter = setup.parameters.itemByName('wcs_orientation_cSys')
        wcscSysValue: cam.CadObjectParameterValue = wcscSysPrm.value
        wcscSysValue.value = [origin]

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def get_cam_product() -> cam.CAM:
    '''
    CAMの取得
    '''
    app: core.Application = core.Application.get()
    activete_cam_env()

    return app.activeProduct


def activete_cam_env() -> None:
    '''
    CAMアクティブ
    '''
    camEnvId = 'CAMEnvironment'
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

    if ui.activeWorkspace.id == camEnvId:
        return

    camWS: core.Workspace = ui.workspaces.itemById(camEnvId) 
    camWS.activate()
Message 11 of 61
Joshua.mursic
in reply to: kandennti

Thank you very much
Message 12 of 61
Joshua.mursic
in reply to: prainsberry

is anyone else getting the "Failed to write job file" error on toolpaths when using:

cam.generateAllToolpaths(False)

Joshuamursic_0-1681139123746.png

it can be resolved easily by simply regenerating the toolpath manually. I am just not sure the cause of the error in the first place.

Message 13 of 61
kandennti
in reply to: Joshua.mursic

@Joshua.mursic .

 

Without publishing the f3d files and scripts, no one will be able to find out the cause.

 

I have experienced crashes in the generateToolpath method when processing at startup.

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/run-on-startup-addin-problem/m-p/11867248#... 

Message 14 of 61
ltomuta
in reply to: prainsberry

I have a design for which simply enumerating CAMProduct's existing NCPrograms is enough to crash Fusion (several crashes should be logged yesterday under my email, all caused by this bug).

 

try:
    for pro in cam.ncPrograms:
        pass
except:
    pass

 


The code is impossible to debug as simply adding the pro object to the Watch window in VSC's debugger causes Fusion to crash.

Message 15 of 61
nicole.debowski
in reply to: kandennti

@kandennti Thanks for all your feedback below, it is much appreciated!

I don't quite get what you're asking for in the first post though. The entry you have posted refers to the old post processing workflow, whereas PostConfiguration is meant to be used with NCProgram objects. NCProgram contains two lists of CAMParameters, one is accessible via the parameters property (essentially, in the UI the left hand side of the NCProgram dialog and the other tab), the other via the postParameters property (the right side). The latter is the one containing the properties you're looking for. Since those are CAMParameters and not NamedValues, you can easily check whether a property exists and change it according to your needs.

We have decided against making those parameters available in PostConfiguration, as that object mirrors a .cps file itself and not the values within. The UI behaves similarly: you can change the values only in the NCPrograms dialog, an attempt to edit the post via the library will result in the user editing the .cps file directly.

Message 16 of 61
nicole.debowski
in reply to: ltomuta

@ltomuta I have found the reports, but I have not been able to reproduce the issues on my end, iterating and inspecting the NCProgram objects worked fine (in a fairly primitive test case). Inside the reports calls to the NCProgram's operations property fail. Is there any change you can share your design with us?
Message 17 of 61
kandennti
in reply to: nicole.debowski

@nicole.debowski .

Thanks for the replies.

 

I think you are lacking in understanding because of the large number of features added.
No problem.

Message 18 of 61
nicole.debowski
in reply to: kandennti

@kandennti: My lack of understanding does not stem from the features added, but may instead come from workflows we have not considered while designing the new API functions or have intended to work differently. The new API around posts and post processing relates to what users see in the UI, but not to the old way of posting via CAM.postProcess(...). If you could please elaborate a bit further about what you feel is missing around posting via NCPrograms (or any new functionality for that matter!), we could figure out whether this has been covered in a different manner users may not expect and thus need better examples, or whether we need to look into implementing that.
Message 19 of 61
Joshua.mursic
in reply to: prainsberry

I have a strange case.

 

I am trying to modify the bottom height for my operation

Joshuamursic_0-1682026395529.png

 

this parameter is expecting a "CadObjectParameterValue". I am not sure if a construction point counts as this, but the selection field accepts it.

rotaryRoughOp = mainSetup.operations.item(3)
rotaryRoughOp.parameters.itemByName("bottomHeight_ref").value.value = [lowPoint]

# lowPoint: adsk.fusion.ConstructionPoint

 

The issue is that the bottom plane that is generated is not at the correct height.

Joshuamursic_1-1682026918258.png

you can see the point that was selected and way below it is the bottom height plane that is created. 

 

Message 20 of 61

I assume the issue was that I was giving it a construction point, when I converted that same point into a sketchPoint and then fed that into the parameter it is working correctly.

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

Post to forums  

Autodesk Design & Make Report