Manufacturing (CAM) API Feedback

Manufacturing (CAM) API Feedback

prainsberry
Autodesk Autodesk
13,449 Views
60 Replies
Message 1 of 61

Manufacturing (CAM) API Feedback

prainsberry
Autodesk
Autodesk

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
13,450 Views
60 Replies
Replies (60)
Message 21 of 61

Joshua.mursic
Advocate
Advocate

I did not see this in any of the documentation, so correct me if I am wrong, is there a way to duplicate or copy an operation in a setup?. It would be really useful to be have a template with many operations and then use a loop to duplicate them and provide new geometry to each duplicate. I know we can create new operations, but it would save time and may be faster to create the operation once and then copy it for other features.

0 Likes
Message 22 of 61

andrewVA8RQ
Participant
Participant

No issues with the CAM API thus far, except that we get a NoneType returned for the following expression:

tool.parameters.itemByName('holder_segments')

 

We don't have any problems accessing any of the other tool parameters, just that one.

 

The holder segments are usually something like this:

H5.000000 U40.000000 L30.000000; H45.000000 U40.000000 L40.000000; H16.510000 U41.275000 L41.275000; H0.762000 U63.550800 L62.026800; H3.683000 U63.550800 L63.550800; H2.006600 U56.261000 L63.550800; H2.997200 U56.261000 L56.261000; H2.006600 U63.550800 L56.261000; H3.632200 U63.550800 L63.550800; H0.762000 U62.026800 L63.550800; H3.175000 U44.450000 L44.450000

 

Is there a way of accessing this data through the API? Is the access to this parameter intentionally disabled? Or could we please get it enabled?

 

Thank you,

 

Andrew Chang

0 Likes
Message 23 of 61

kandennti
Mentor
Mentor

Hi @andrewVA8RQ .

 

The only way I have tried is to get the json, change it, and make a new tool again.
The following script is how I actually tried it.

# 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

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

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

        # get tool json
        # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-64B24924-4C71-4453-B453-EE1277CED8ED
        toolJson = json.loads(tool.toJson())
        print(json.dumps(toolJson, indent=2))

        # Holder shape modification
        toolJson['holder']['segments'][0]['lower-diameter'] *= 0.5
        toolJson['holder']['segments'][0]['upper-diameter'] *= 0.5

        # create tool
        # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-072FCA71-EE7F-4BA3-88AD-AE38C38E05F0
        newTool: cam.Tool = cam.Tool.createFromJson(json.dumps(toolJson))

        activeToolLib.add(newTool)

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


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

    return app.activeProduct


def activete_cam_env() -> None:
    app: core.Application = core.Application.get()
    ui: core.UserInterface = app.userInterface

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

 

Get the json from the first tool and halve the diameter of the bottom holder.

1.png


All that is left is to replace the tool in the toolpath that uses the original tool.
However, I could not think of many situations that would require a change of holders.

0 Likes
Message 24 of 61

andrewVA8RQ
Participant
Participant

That's very helpful. Thank you for the detailed answer. Our application is read only anyways, so we'll rewrite with the Tool.toJson method, get the ability to read tool holder segments, and drastically reduce the number of API requests.

Message 25 of 61

maurizio_manzi
Advocate
Advocate

Problem with tool query criteria because inaccuracy of float variables:

Please see attached cam part (.f3d) and attached script as example.

The local tool library of the cam part contains 3 tools.

With the query, I find 2 tools.

The ball end mill tool is not found, because query criteria is:

query.criteria.add('tool_diameter', adsk.core.ValueInput.createByReal(3 / 10)) # / 10 for mm to Cm
(tool has diameter 3mm),
but the message box at end say us, the tool_diameter value is = 0.30000000000000004
So, we have 0.3 != 0.30000000000000004
(0.3 is the result of 3/10).
The problems with float variables are known, but maybe, the API should use only 5 decimals, when comparing.
 
Best regards
Maurizio
 
0 Likes
Message 26 of 61

troglodactyl
Community Visitor
Community Visitor

There seems to be an issue with the "updateToolLibrary" function causing potential data loss. When updating a tool in a library (or even if no update is made as shown below), the "holder" section for every tool in the library is wiped out.

Ptr<ToolQuery> toolQuery_var = adsk::cam::CAMManager::get()->libraryManager()->toolLibraries()->createQuery(adsk::cam::LibraryLocations::LocalLibraryLocation);

toolQuery_var->criteria()->add("tool_description", adsk::core::ValueInput::createByString("TEST"));

std::vector<Ptr<ToolQueryResult>> toolQueryResult_var = toolQuery_var->execute();

adsk::core::Ptr<adsk::cam::ToolLibrary> library = toolQueryResult_var[0]->toolLibrary();

adsk::core::Ptr<adsk::core::URL> libraryURL = toolQueryResult_var[0]->toolLibraryURL();

adsk::cam::CAMManager::get()->libraryManager()->toolLibraries()->updateToolLibrary(libraryURL, library);

 

0 Likes
Message 27 of 61

ltomuta
Advisor
Advisor

Any idea why this parameter expression assignment would fail?

    ncParameters.itemByName('nc_program_post').expression = "'cloud://Excetek V500G.cps'"

The expression should point to a valid post in my cloud library yet I get an "Invalid enumeration value" exception

Creating NC Programs failed: Traceback (most recent call last):
  File "C:/Users/Lucian/OneDrive/WIP/_Posts/Add_in/Kokel/Kokel.py", line 731, in CreateNCPrograms
    ncParameters.itemByName('nc_program_post').expression = "'cloud://Excetek V500G.cps'"
  File "C:\Users/Lucian/AppData/Local/Autodesk/webdeploy/production/92ad8ab0bbe49f8eadd1a685ce38e69869d3a242/Api/Python/packages\adsk\cam.py", line 3312, in _set_expression
    return _cam.CAMParameter__set_expression(self, value)
RuntimeError: 3 : Invalid enumeration value.

 

0 Likes
Message 28 of 61

nicole.debowski
Autodesk
Autodesk

@ltomuta 

Using that parameter to set the post only works if the post also shows up in the dropdown in the UI. Unless you're certain it is in the dropdown, do not use the parameter to set the post.
Instead, set the post from your library by setting the NCProgram object's postConfiguration property like so:

# Initializes post library
camManager = adsk.cam.CAMManager.get()
libManager = camManager.libraryManager
postLib = libManager.postLibrary

# Queries post library to get milling posts by "Autodesk" vendor from the cloud library location
postquery = postLib.createQuery(adsk.cam.LibraryLocations.CloudLibraryLocation)
postquery.vendor = "autodesk"
postquery.capability = adsk.cam.PostCapabilities.Milling
# returns an array containing PostConfigutation objects
postConfigs = postquery.execute()

# Picks the first result
myNCProgram.postConfiguration = postConfigs[0]

 

0 Likes
Message 29 of 61

ltomuta
Advisor
Advisor

Yes, that post is in my dropdown as it is the post I use 99% of the time these days. In fact, that's likely the post I get in the NC Program if I don't set it from code and the field defaults to the last one used.

I want to set very specific posts in the NC Program depending on a setup's type and content. The library contains also other versions of the same post so a query like that looks error prone as unless I can narrow it down to precisely one post being returned today's postConfigs[0] may be tomorrow's postConfigs[1]

It also looks like 10 lines of code where there could be only one.

0 Likes
Message 30 of 61

echatzief
Advocate
Advocate

Hi, at first I want to thank you for your contribution to the Manufacturing API.

As explained on the post : https://forums.autodesk.com/t5/fusion-360-api-and-scripts/run-on-startup-addin-problem/m-p/11836068 I am having troubles running my add-in on startup. I was able to create a button on the F360 UI which when pressed runs my script, but will I ever be able to run my add-in on startup without the intervation of any buttons?

0 Likes
Message 31 of 61

en9y37
Advocate
Advocate

Hi all!

 

I've got a couple of doubts / suggestions about working with CAM via API.

 

When a design is inserted into another design breaking the link, the CAM information from the inserted design (setups and operations) is lost in the process.

Is there some way to avoid this via API? I can read the whole CAM information via API from the inserted design before the link is broken, I wonder whether there's a way to transfer or recover that information once the link is broken to the host design.

 

The workCoordinateSystem property from the setup object is read-only and I'd need to be be able to set the WCS when I create a new setup. Is in the roadmap to make this property get-set capable, or some other way to set the WCS of the setups? I've got the same need for the tool orientation when I set some operations.

 

Thanks in advance!

 

0 Likes
Message 32 of 61

nicole.debowski
Autodesk
Autodesk

Hi @en9y37,

you can set the world coordinate system (and tool coordinate system) by setting the associated parameters. Here's a more complicated example where the WCS is created by setting the X and Y axes to the edges of a model, rotatedBox:

orientationModeParam = setup.parameters.itemByName('wcs_orientation_mode')
orientationModeParam.value.value = 'axesXY'
xAxis = setup.parameters.itemByName('wcs_orientation_axisX')
xtargets = []
xtargets.append(rotatedBox.faces.item(3))
xAxis.value.value = xtargets
yAxis = setup.parameters.itemByName('wcs_orientation_axisY')
ytargets = []
ytargets.append(rotatedBox.faces.item(4))
yAxis.value.value = ytargets
originParam = setup.parameters.itemByName('wcs_origin_boxPoint')
originParam.value.value = "bottom 1"

You can set the coordinate system of the tool in an operation by using the equivalent parameters with the view_ prefix instead of the wcs_ one. To enable the tool coordinate system in a supported operation, you'll need to set

the overrideToolView parameter to true.

For the full list of possible boxPoint values please have a look at the 

class SetupWCSPoint(Enum)

in our Manufacturing Workflow API example. You can get the parameter names and possible choice values by hovering over the parameter in the UI while holding down the shift key.

Message 33 of 61

en9y37
Advocate
Advocate

WOW!! That was awesome!!

 

Thanks a lot @nicole.debowski, that's been really useful to me.

0 Likes
Message 34 of 61

myktron
Observer
Observer

Hello!

I encountered a few unexpected behaviours:

 

1) setting the stock mode for a milling operation works for the first setup in a document, but on subsequent execution defaults to 'previoussetup', the list of possible parameter values I am getting is
("'fixedbox'", "'default'", "'fixedcylinder'", "'relativecylinder'", "'fixedtube'", "'relativetube'", "'solid'", "'previoussetup'"), I would have expected for it to contain a 'relativebox' option.
Meanwhile I found out that I can set the intended stock mode via setupInput.stockMode = adsk.cam.SetupStockModes.RelativeBoxStock but this results in the same behaviour.

 

2) as per https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-F28C87D3-21E4-4368-B565-D7B96791AFD4 the pocket selection is experimentational but i wonder why the Pocket-Example given here https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-A08218F6-3885-4677-9CAD-7234BCEE85CC is not working.
the line
pocketSel: adsk.cam.PocketSelection = curveSelections.createNewPocketSelection()
produces:
../Api/Python/packages\adsk\cam.py", line 3920, in createNewPocketSelection
return _cam.CurveSelections_createNewPocketSelection(self)
RuntimeError: 2 : InternalValidationError : m_parameters.getPrimaryCadObject()
Unfortunately I wasn't able to find a workaround. Selecting the faces below the top height of the part with normals pointing upward, then feeding their edges into chain selections, did not produce the desired result but selected corresponding edges on the bottom of the part.

 

3) and a minor issue regarding the documentation: the information here https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7F3F9D48-ED88-451A-907C-82EAE67DEA93 is slightly confusing.
The line [s.title for s in strategies] should read [s.name for s in strategies] (in the screenshot above this is displayed correctly). It would be quite comfortable if the available parameters/values would be documented in the API-Help.

 

If there is some quick fix for the first or second problem, any hint would be greatly appreciated! I am happy to provide addon source code, screenshots etc. if you need further information.
Thank you for your efforts,
best regards,
Mike

0 Likes
Message 35 of 61

en9y37
Advocate
Advocate

Hi again!

 

I'd need to add attributes to manage properly my setups and operations created via API, and I've realised that maybe due to a bug or to some limitation, I'm not capable to do that.

 

Here I leave a simple script that simplifies the idea:

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        doc = app.activeDocument
        products = doc.products
        productCam:adsk.cam.CAM = products.itemByProductType('CAMProductType')
        setups = productCam.setups
        
        #Addition of an attribute to any setup
        for setup in setups:
            setup.attributes.add('TEST_group', 'TEST_name' , 'value')

            #Addition of an attribute to any operation in the setup
            for operation in setup.operations:
                operation.attributes.add('TEST_group', 'TEST_name' , 'value')
        
        
        for setup in setups:
            #Deletion of any operation which contains the attribute added    
            for operation in setup.operations:
                if operation.attributes.itemByName('TEST_group', 'TEST_name') != None:
                    operation.deleteMe()            
            
            #Deletion of any setup which contains the attribute added
            if setup.attributes.itemByName('TEST_group', 'TEST_name') != None:
                setup.deleteMe()
                   
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

With this script is meant that any setup or operation present in any design should be deleted since all of them are marked with an attribute. The result is that nothing happens and if I watch the count of atributes after the additions while debugging, it keeps at 0. This script has been tested with both, the design and the cam workspace activated.

 

Any idea or known issue about this?

0 Likes
Message 36 of 61

jeff.pek
Community Manager
Community Manager

Hi - Thanks for the question.

Attributes for CAM objects was added a couple of months back, but there were some problems with the initial implementation, which prevented them from working completely. There's a fix coming for this in the next update in September.

 

I think, though, that what you are trying to do SHOULD work (but is probably not sufficient for your needs), but need to verify that. One thing I should note is that deleting the setups & operations within the corresponding loop over the objects doesn't work as expected. To do that, you should gather up the objects to delete in a separate list within the first loop, and then delete the objects by processing that list in order separately.

 

Jeff

Message 37 of 61

nicole.debowski
Autodesk
Autodesk

@myktron

I'm sorry for the late reply. To your first point, the value you want to use for the relative box is "default". I'm not able to reproduce the second point, are you still seeing the crash with the new release?

0 Likes
Message 38 of 61

en9y37
Advocate
Advocate

Thanks for your response @jeff.pek 

 

I've just received the last update and this issue is completely solved. Thanks for the hint about the gathering of objects to proceed with the deletion of them.

Message 39 of 61

en9y37
Advocate
Advocate

Hi again @jeff.pek 

 

I'm testing the attributes for the CAM objects, and I'm sorry to say that I've found a bug.

 

Attributes are kept and work properly as long as you don't make any change in setups or operations. However, once a change is made on them, it doesn't matter whether it's done via API or user interface, the attributes on the changed setup or operation get lost.

 

I hope this help to improve.

0 Likes
Message 40 of 61

nicole.debowski
Autodesk
Autodesk

Hi @en9y37,

Attribute persistence is the bug Jeff was referring to in his comment:


Attributes for CAM objects was added a couple of months back, but there were some problems with the initial implementation, which prevented them from working completely. There's a fix coming for this in the next update in September.

Unfortunately, for this to work properly, you'll need to wait for the next release, the fix got in too late for the update you have received a couple of days ago.

0 Likes