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: 

Problem adding to active selections

5 REPLIES 5
Reply
Message 1 of 6
robduarte
762 Views, 5 Replies

Problem adding to active selections

Hi, I'm able to add to the active selections using the following code in my add-in but when the command completes the selection is lost. Is this a feature? The only function of this add-in is to select curves. (The code below does select the one circle in my sketch and the message box shows 1 as expected - it's just that the circle is unselected after the message box is dismissed). Thanks for any help.

 

class Selections:
    def Execute(self, entityOne):
        sketch = entityOne.parentSketch
        curves = sketch.sketchCurves   
        
        selections = ui.activeSelections
        selections.clear()
        
        for curve in curves:
            if (type(curve) is adsk.fusion.SketchCircle):
                selections.add(curve)
                ui.messageBox(str(selections.count))

Rob Duarte
Associate Professor in Art, Florida State University
Co-Director FSU Facility for Arts Research
http://art.fsu.edu/rob-duarte/

Twitter | YouTube

5 REPLIES 5
Message 2 of 6
robduarte
in reply to: robduarte

Actually, let me be more specific... I tried to pare down both a script and an add-in to the bare minimum to reproduce the problems I'm having (they are both supposed to do the same thing).

 

The first listing is a python "script" that mostly functions as intended. If you select a sketch curve, it selects ALL curves in that same sketch. There is one issue with this one that hopefully someone can answer: Why doesn't the ui.selectEntity function display the prompt as it's supposed to. (On my computer it shows nothing, although it does accept my selection).

 

The second listing is a python "add-in" with a command definition that allows the user to select that initial curve. The problem with this one is as I originally described: it doesn't keep the selections that are made. In addition, it seems to only select ONE of the curves, even though all of the "add" methods ARE being called within the loop (ie: it seems to only keep the LAST "add" since the message box shows 1 instead of the actual number of curves in the sketch).

 

Again, my 3 questions are:

 

  1. Why doesn't ui.selectEntity display the prompt as it's supposed to according to the api docs
  2. Why doesn't the add-in version of the script keep the selections after closing the messagebox?
  3. Why is it only selecting ONE of the curves instead of all of them (the loop is the same in both versions below)

Thanks for any help...

 

----- SCRIPT VERSION ------

#Author-
#Description-

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        sel = ui.selectEntity("Select a curve", "SketchCurves")
        selcurve = sel.entity        

        sketch = selcurve.parentSketch
        curves = sketch.sketchCurves
        
        selections = ui.activeSelections
        selections.clear()

        for curve in curves:
            selections.add(curve)
            
        ui.messageBox(str(selections.count))
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

--- ADD-IN VERSION ----

import adsk.core, adsk.fusion, traceback
import os

handlers = []
app = adsk.core.Application.get()
if app:
    ui = app.userInterface

class SelectionCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            command = args.firingEvent.sender
            inputs = command.commandInputs

            input0 = inputs[0];
            sel = input0.selection(0);
            selcurve = sel.entity

            sketch = selcurve.parentSketch
            curves = sketch.sketchCurves
        
            selections = ui.activeSelections
            selections.clear()

            for curve in curves:
                selections.add(curve)
            
            ui.messageBox(str(selections.count))
            
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            # when the command is done, terminate the script
            # this will release all globals which will remove all event handlers
            adsk.terminate()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionValidateInputHandler(adsk.core.ValidateInputsEventHandler):
    def __init__(self):
        super().__init__()
       
    def notify(self, args):
        try:
            sels = ui.activeSelections;
            if len(sels) == 1:
                args.areInputsValid = True
            else:
                args.areInputsValid = False
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            cmd = args.command
            onExecute = SelectionCommandExecuteHandler()
            cmd.execute.add(onExecute)
            onDestroy = SelectionCommandDestroyHandler()
            cmd.destroy.add(onDestroy)

            onValidateInput = SelectionValidateInputHandler()
            cmd.validateInputs.add(onValidateInput)
            # keep the handler referenced beyond this function
            handlers.append(onExecute)
            handlers.append(onDestroy)
            handlers.append(onValidateInput)
            #define the inputs
            inputs = cmd.commandInputs
            i1 = inputs.addSelectionInput('entity', 'Sketch Curve', 'Please select a sketch curve')

            i1.addSelectionFilter(adsk.core.SelectionCommandInput.SketchCurves);

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
def run(context):
    try:
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        if not design:
            ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.')
            return
        commandDefinitions = ui.commandDefinitions
        # check the command exists or not
        cmdDef = commandDefinitions.itemById('SelectionCMDDef')
        
        if not cmdDef:
            resourceDir = os.path.dirname(os.path.realpath(__file__)) # os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources') # absolute resource file path is specified
            cmdDef = commandDefinitions.addButtonDefinition('SelectionCMDDef',
                    'Select Curves',
                    'Select sketch curves',
                    resourceDir)

        onCommandCreated = SelectionCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        # keep the handler referenced beyond this function
        handlers.append(onCommandCreated)
        inputs = adsk.core.NamedValues.create()
        cmdDef.execute(inputs)

        # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
        adsk.autoTerminate(False)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Rob Duarte
Associate Professor in Art, Florida State University
Co-Director FSU Facility for Arts Research
http://art.fsu.edu/rob-duarte/

Twitter | YouTube

Message 3 of 6
liujac
in reply to: robduarte

Hi,

 

  1. The prompt is displayed at the mouse cursor. There is no dialog or message box to be displayed for UserInterface.selectEntity.
  2. Clear all selection after the command dialog is closed, the behavior is as expected. You can see the UI commands also have the same behavior.
  3. Selections within command are limited to selection command inputs. When add a selection command input, the default behavior is that only one entity can be selected and it can be of any type. You can set the selection filters and limits on the selection command input as below.
  4.             i1 = inputs.addSelectionInput('entity', 'Sketch Curve', 'Please select a sketch curve')
                i1.addSelectionFilter(adsk.core.SelectionCommandInput.SketchCurves);
                i1.setSelectionLimits(1, 0) #A value of zero means that there is no limit

Also you need to change the line "if len(sels) == 1:" to "if len(sels) >= 1:" in SelectionValidateInputHandler to enable the OK button when the selections count is equal or greater than 1.

 

Thanks,

Jack

Message 4 of 6
robduarte
in reply to: liujac

Thank you for the answers. Just to make sure I understand: it is not possible to make an add-in (with a command dialog) that selects curves for future operations by the user? That was my goal.. to allow the user to select a curve and have the command select similar curves based on attributes like length, approximate length, type of curve, etc.

Rob Duarte
Associate Professor in Art, Florida State University
Co-Director FSU Facility for Arts Research
http://art.fsu.edu/rob-duarte/

Twitter | YouTube

Message 5 of 6
liujac
in reply to: robduarte

Right, all selections made in a command will be cleared after the command is terminated. Could you keep the dialog open, and make the additional selections in selection event of the command for your workflow? Please try the addin below:

 

 

import adsk.core, adsk.fusion, traceback
import os

handlers = []
app = adsk.core.Application.get()
if app:
    ui = app.userInterface

class SelectionCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            command = args.firingEvent.sender
            inputs = command.commandInputs
            
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            # when the command is done, terminate the script
            # this will release all globals which will remove all event handlers
            adsk.terminate()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionCommandSelectionEventHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
       
    def notify(self, args):
        try:
            if args.selection:
                selcurve = args.selection.entity
    
                sketch = selcurve.parentSketch
                curves = sketch.sketchCurves
                
                additionalEntities = adsk.core.ObjectCollection.create()
                for curve in curves:
                    if curve != selcurve:
                        additionalEntities.add(curve)
                args.additionalEntities = additionalEntities
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class SelectionCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            cmd = args.command
            onExecute = SelectionCommandExecuteHandler()
            cmd.execute.add(onExecute)
            onDestroy = SelectionCommandDestroyHandler()
            cmd.destroy.add(onDestroy)

            onSelect = SelectionCommandSelectionEventHandler()
            cmd.selectionEvent.add(onSelect)
            # keep the handler referenced beyond this function
            handlers.append(onExecute)
            handlers.append(onDestroy)
            handlers.append(onSelect)
            #define the inputs
            inputs = cmd.commandInputs
            i1 = inputs.addSelectionInput('entity', 'Sketch Curve', 'Please select a sketch curve')
            i1.addSelectionFilter(adsk.core.SelectionCommandInput.SketchCurves);
            i1.setSelectionLimits(1, 0) #A value of zero means that there is no limit

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
def run(context):
    try:
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        if not design:
            ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.')
            return
        commandDefinitions = ui.commandDefinitions
        # check the command exists or not
        cmdDef = commandDefinitions.itemById('SelectionCMDDef')
        
        if not cmdDef:
            resourceDir = os.path.dirname(os.path.realpath(__file__)) # os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources') # absolute resource file path is specified
            cmdDef = commandDefinitions.addButtonDefinition('SelectionCMDDef',
                    'Select Curves',
                    'Select sketch curves',
                    resourceDir)

        onCommandCreated = SelectionCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        # keep the handler referenced beyond this function
        handlers.append(onCommandCreated)
        inputs = adsk.core.NamedValues.create()
        cmdDef.execute(inputs)

        # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
        adsk.autoTerminate(False)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Thanks,

Jack

Message 6 of 6
Anonymous
in reply to: liujac


@liujac wrote:

Right, all selections made in a command will be cleared after the command is terminated.


 

 

Is this still valid for the current version of Fusion 360?

 

So if I want to pass a program-generated selection of objects to the user I have to use a script instead of an Add-In?

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