Suppress a feature using a script

Suppress a feature using a script

martin.devarda
Explorer Explorer
1,889 Views
8 Replies
Message 1 of 9

Suppress a feature using a script

martin.devarda
Explorer
Explorer

Screenshot 2020-01-28 at 17.16.24.png
I need to conditionally suppress a feature using a script. 

I've found some threads about this issue, but no trial code nor working examples. I tried to do it by myself but unsuccessfully. I'm not a developer (just some Javascript for web pages) and I the learning curve of the scripting environment is too steep for me.

 

I share a basic design to play with. If anybody could drop some lines of code to conditionally suppress the last feature, it'd be very helpful.

 

 

0 Likes
1,890 Views
8 Replies
Replies (8)
Message 2 of 9

kandennti
Mentor
Mentor

Hi @martin.devarda .

 

I created a script for trial.
After running the script, select a timeline.
Toggles Suppress <-> Unsuppress.

1.png

#Fusion360API Python script

import adsk.core, adsk.fusion, traceback

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

        # user selection
        msg :str = 'Select Feature'
        selFiltter :str = 'Features,Occurrences'

        while True:
            sel :adsk.core.Selection = selectEnt(ui, msg ,selFiltter)

            if not sel:
                #Press ESC key
                break

            # Get the selected element
            # feature :adsk.fusion.Feature = sel.entity
            feature = sel.entity

            # Suppress <-> Unsuppress
            if hasattr(feature, 'isSuppressed'):
                # has isSuppressed Property
                feature.isSuppressed = not feature.isSuppressed
            elif hasattr(feature, 'timelineObject'):
                # Sketch object
                timeObj = feature.timelineObject
                timeObj.isSuppressed = not timeObj.isSuppressed
            else:
                # other
                ui.messageBox('Not Supported')

        # finish
        ui.messageBox('Done')

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

def selectEnt(
        ui :adsk.core.UserInterface,
        msg :str, 
        filtterStr :str) -> adsk.core.Selection:

    try:
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

 

 

Message 3 of 9

luca.giorcelli9CG7C
Contributor
Contributor

Thanks, very helpful.

 

2 more questions to reach my goal:

1. how can I access objects to be suppressed/unsuppressed by id (if any) instead of manually selecting them? Consider that my objects (e.g. an extrude feature) have been created manually via UI, not programmatically. I see them in timeline, but I cannot find any sort of ID to reference them.

2. how can I access a user defined parameter?


Thanks for your help

0 Likes
Message 4 of 9

kandennti
Mentor
Mentor

1. how can I access objects to be suppressed/unsuppressed by id (if any) ~

I did not understand the meaning of Id.

This script is suppresses all "Extrude Feature".

 

#Fusion360API Python script

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app :adsk.core.Application = adsk.core.Application.get()
        ui  :adsk.core.UserInterface = app.userInterface
        des :adsk.fusion.Design = app.activeProduct
        
        Suppressionlist = []
        for tlObj in des.timeline:
            if tlObj.entity.objectType == 'adsk::fusion::ExtrudeFeature':
                if tlObj.isSuppressed == False:
                    Suppressionlist.append(tlObj)

        if len(Suppressionlist) < 1:
            msg = 'No "Extrude Feature" to suppress'
            ui.messageBox(msg)
            return
        
        msg = 'Suppresses all "Extrude Feature". Is it OK?'
        resOk = adsk.core.DialogResults.DialogOK
        btnOkCancel = adsk.core.MessageBoxButtonTypes.OKCancelButtonType
        if ui.messageBox(msg, 'test', btnOkCancel) != resOk:
            return

        for tlObj in reversed(Suppressionlist):
            tlObj.entity.isSuppressed = True

        # finish
        ui.messageBox('Done')

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

 

 

 

2. how can I access a user defined parameter?


It is like this.

#Fusion360API Python script

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app :adsk.core.Application = adsk.core.Application.get()
        ui  :adsk.core.UserInterface = app.userInterface
        des :adsk.fusion.Design = app.activeProduct
        
        prm :adsk.fusion.UserParameter = des.userParameters.itemByName('my_param')
        ui.messageBox(str(prm.value))

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

 

 

0 Likes
Message 5 of 9

martin.devarda
Explorer
Explorer
# Get the selected element
            # feature :adsk.fusion.Feature = sel.entity
            feature = sel.entity

According to lines above,  the feature to be suppressed must be manually selected in timeline, which is not my case. I'd like to reference the feature programmatically, without manually selecting them in timeline.

 

How can I reference features programmatically? Does Fusion assign names (or unique ID) to features? If yes, how can I know the name (or ID) of a feature in my timeline?

Thanks

0 Likes
Message 6 of 9

kandennti
Mentor
Mentor

Since there are no methods such as "itemByName" and "itemById" in the timeline, it is necessary to find the necessary one from all the elements with a loop.

 

This toggles control of the feature with the name Key (Fillet).

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        des  :adsk.fusion.Design = _app.activeProduct

        # get timeline
        tl :adsk.fusion.Timeline = des.timeline

        # Get the future with the name of Key
        key = 'Fillet'
        features = findByLikeName(tl, key)

        for feature in features:
            if hasattr(feature, 'isSuppressed'):
                # has isSuppressed Property
                feature.isSuppressed = not feature.isSuppressed

            elif hasattr(feature, 'timelineObject'):
                # Sketch object
                timeObj = feature.timelineObject
                timeObj.isSuppressed = not timeObj.isSuppressed

            else:
                # other
                _ui.messageBox('Not Supported')

        # finish
        _ui.messageBox('Done')

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

def findByLikeName(
    tl :adsk.fusion.Timeline,
    name :str) -> list:

    import re

    lst = []
    tlo = adsk.fusion.TimelineObject.cast(None)
    for tlo in tl:
        if re.search(name, tlo.name):
            lst.append(tlo)

    return lst
0 Likes
Message 7 of 9

BrianEkins
Mentor
Mentor

One thing to be aware of and also why the timeline doesn't have a findByName method is that it's possible to have duplicate names in the timeline.  For example, features are owned by a component and each feature must have a unique name but only within that component.  If you have a design with two components, each one can have a feature named "Extrude1".  Both of these features will show up as nodes in the timeline so just specifying a name is ambiguous.  Because of this, the solution @kandennti provided by looking through the timeline will find the first item with the specified name, not necessarily the one you want. 

 

Also, because the timeline contains a mix of different types of entities, you can have duplicate names within the same component.  For example, I can have an extrusion named "Bill" and a construction plane named "Bill", both in the same component and both of them in the timeline.

 

In the real-world it's likely things will have unique names and the solution of iterating over the timeline will give you the result you're looking for but I just want to point out there are other possibilities and there's a reason the API is like it is.  The itemByName method is supported in places where a name is guaranteed to be a unique identifier.  For example, the ConstructionPlanes collection supports it because the collection only provides access to construction planes and only the construction planes within a specific component so the names are guaranteed to be unique.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 8 of 9

agibson2
Explorer
Explorer

It would be very useful to have a new parameter type for suppression or just use a regular variable as an enable or suppress option for features.  You could then assign that suppression name to the features you want to be able to enable/disable.  If the value is 0 then the features assigned to that parameter name would be suppressed.  I already use variables for enabling of adding or subtracting measurements.

 

Use a parameter called EnableBoltVersion and I assign it to a 0 or 1 (0 disabled, 1 enabled)

I then use EnableBoltVersion in dimensions like this...

45mm + (EnableBoltVersion * 43.2)

 

When EnableBoltVersion is 0 43.2 is not added.  When it is 1, 43.2 is added.

 

It would be very useful to be able to assign EnableBoltVersion to a few features that I need to enable or suppress.  If it is 0 then the feature is suppressed and if it is not equal to 0 (negative or positive value), it is enabled.

 

Using a script to suppress features is a bit cumbersome and just another thing to manage and debug when a really simple feature added to fusion360 would really make it much easier to do.

 

 

Message 9 of 9

BrianEkins
Mentor
Mentor

I think that is a great idea.  It's not really an API feature but would be a core Fusion 360 feature that you could take advantage of through the API.  I suggest posting it on the Feedback Hub.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes