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: 

Operation using the SelectionCommandInput.addSelection method

1 REPLY 1
SOLVED
Reply
Message 1 of 2
kandennti
315 Views, 1 Reply

Operation using the SelectionCommandInput.addSelection method

Hi there.

 

SelectionCommandInput is used to create an add-in that appears pre-selected when the dialog is displayed.
I'm having trouble getting it to work the way I want it to, so if you know of a way to get around this, please let me know.

 

I have created a script to reproduce the behavior.

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

_app: adsk.core.Application = None
_ui: adsk.core.UserInterface = None
_handlers = []
_selIpt: adsk.core.SelectionCommandInput = None

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandCreatedEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)
        try:
            global _handlers
            cmd: adsk.core.Command = adsk.core.Command.cast(args.command)
            inputs: adsk.core.CommandInputs = cmd.commandInputs

            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            onExecute = MyExecuteHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)

            onActivate = MyActivateHandler()
            cmd.activate.add(onActivate)
            _handlers.append(onActivate)


            global _selIpt
            _selIpt = inputs.addSelectionInput(
                'selIptId',
                'sketch curves',
                'select sketch curves'
            )
            _selIpt.setSelectionLimits(0)
            _selIpt.addSelectionFilter(
                adsk.core.SelectionCommandInput.SketchCurves
            )

            # Preselect sketch lines
            global _app
            des: adsk.fusion.Design = _app.activeProduct
            root: adsk.fusion.Component = des.rootComponent
            sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
            _selIpt.clearSelection()
            _selIpt.addSelection(sktLines[0])
            _selIpt.addSelection(sktLines[1])

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

class MyActivateHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: adsk.core.CommandEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)

        # Preselect sketch lines
        global _app, _selIpt
        des: adsk.fusion.Design = _app.activeProduct
        root: adsk.fusion.Component = des.rootComponent
        sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
        _selIpt.clearSelection()
        _selIpt.addSelection(sktLines[0])
        _selIpt.addSelection(sktLines[1])
        pass


class MyExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)

        global _app, _selIpt
        selCount = _selIpt.selectionCount
        _app.log(f'selectionCount:{selCount}')
        for idx in range(selCount):
             _app.log(f' {_selIpt.selection(idx).entity.entityToken}')


class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)
        adsk.terminate()


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

        initSketchLines()

        cmdDef: adsk.core.CommandDefinition = _ui.commandDefinitions.itemById(
            'test_cmd'
        )

        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition(
                'test_cmd',
                'Test',
                'Test'
            )

        global _handlers
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmdDef.execute()

        adsk.autoTerminate(False)

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


def initSketchLines():
    app: adsk.core.Application = adsk.core.Application.get()
    app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
    des: adsk.fusion.Design = app.activeProduct
    root: adsk.fusion.Component = des.rootComponent

    skt: adsk.fusion.Sketch = root.sketches.add(
        root.xYConstructionPlane
    )
    sktLines: adsk.fusion.SketchLines = skt.sketchCurves.sketchLines

    P3D = adsk.core.Point3D
    points =[
        (P3D.create(1,0,0), P3D.create(1,2,0)),
        (P3D.create(2,0,0), P3D.create(2,2,0)),
        (P3D.create(3,0,0), P3D.create(3,2,0)),
        (P3D.create(4,0,0), P3D.create(4,2,0)),
    ]
    for p1, p2 in points:
        sktLines.addByTwoPoints(p1, p2)

    app.activeViewport.fit()

 

When I run it, it creates a sketch in a new document and draws 4 straight lines.
When the dialog appears, two of the lines are selected.

1.png

 

I was hoping that if I click on them, which are already selected, they will be deselected. However, the number of selections increases.

2.png

 

Furthermore, when the OK button is pressed in this state, the number of selections and the entityToken of the selected elements are output to the text command window, but duplicate entityTokens are output.
This is an example of the output.

 selectionCount:3
  /v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCsYAAAqQ064ZIAAAA=
  /v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCmYAAAQs/x55IAAAA=
  /v4BAAAARlJLZXkAH4sIAAAAAAAA/zNQsFAwAEJDBSMgBrOMLIAsQwUTkIiZgsKhrUV5HR7hbUZM/Esmpt0CqjBSMDZTSDVJMjJNNDPUNU00MdY1sUgz000yN7bQTU00tkhKSbU0M7UwBKsFmsGABsD2GSiArTM1NIJYaw5UamCmYAAAQs/x55IAAAA=

 

I tried addSelection with the commandCreated and activate events, but they did not work as expected.

 

Does anyone know a good way to make addSelection deselect a selected element when it is clicked from the selected state and the dialog is displayed?
Please advise.

1 REPLY 1
Message 2 of 2
kandennti
in reply to: kandennti

I got the behavior I wanted by using the inputChanged event, so I will share it with you.

 

The InputChangedHandler checks for elements selected by SelectionCommandInput, deems duplicates as "unselect," and makes them unselectable.

 

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

_app: adsk.core.Application = None
_ui: adsk.core.UserInterface = None
_handlers = []
_selIpt: adsk.core.SelectionCommandInput = None

class MyInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: adsk.core.InputChangedEventArgs):
        adsk.core.Application.get().log(args.firingEvent.name)

        global  _selIpt
        if args.input != _selIpt:
            return

        ents = [_selIpt.selection(i).entity for i in range(_selIpt.selectionCount)]

        unique = []
        [unique.append(x) for x in ents if x not in unique]

        if len(ents) == len(unique):
            return

        singles = [x for x in unique if ents.count(x) == 1]
        _selIpt.clearSelection()
        [_selIpt.addSelection(x) for x in singles]


class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandCreatedEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)
        try:
            global _handlers
            cmd: adsk.core.Command = adsk.core.Command.cast(args.command)
            inputs: adsk.core.CommandInputs = cmd.commandInputs

            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

            onExecute = MyExecuteHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)

            onActivate = MyActivateHandler()
            cmd.activate.add(onActivate)
            _handlers.append(onActivate)

            onInputChanged = MyInputChangedHandler()
            cmd.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)


            global _selIpt
            _selIpt = inputs.addSelectionInput(
                'selIptId',
                'sketch curves',
                'select sketch curves'
            )
            _selIpt.setSelectionLimits(0)
            _selIpt.addSelectionFilter(
                adsk.core.SelectionCommandInput.SketchCurves
            )

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

class MyActivateHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: adsk.core.CommandEventArgs):
        adsk.core.Application.get().log(args.firingEvent.name)

        # Preselect sketch lines
        global _app, _selIpt
        des: adsk.fusion.Design = _app.activeProduct
        root: adsk.fusion.Component = des.rootComponent
        sktLines: adsk.fusion.SketchLines = root.sketches[0].sketchCurves.sketchLines
        _selIpt.clearSelection()
        _selIpt.addSelection(sktLines[0])
        _selIpt.addSelection(sktLines[1])


class MyExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)

        global _app, _selIpt
        selCount = _selIpt.selectionCount
        _app.log(f'selectionCount:{selCount}')
        for idx in range(selCount):
             _app.log(f' {_selIpt.selection(idx).entity.entityToken}')


class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args: adsk.core.CommandEventArgs):
        # adsk.core.Application.get().log(args.firingEvent.name)
        adsk.terminate()


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

        initSketchLines()

        cmdDef: adsk.core.CommandDefinition = _ui.commandDefinitions.itemById(
            'test_cmd'
        )

        if not cmdDef:
            cmdDef = _ui.commandDefinitions.addButtonDefinition(
                'test_cmd',
                'Test',
                'Test'
            )

        global _handlers
        onCommandCreated = MyCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmdDef.execute()

        adsk.autoTerminate(False)

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


def initSketchLines():
    app: adsk.core.Application = adsk.core.Application.get()
    app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
    des: adsk.fusion.Design = app.activeProduct
    root: adsk.fusion.Component = des.rootComponent

    skt: adsk.fusion.Sketch = root.sketches.add(
        root.xYConstructionPlane
    )
    sktLines: adsk.fusion.SketchLines = skt.sketchCurves.sketchLines

    P3D = adsk.core.Point3D
    points =[
        (P3D.create(1,0,0), P3D.create(1,2,0)),
        (P3D.create(2,0,0), P3D.create(2,2,0)),
        (P3D.create(3,0,0), P3D.create(3,2,0)),
        (P3D.create(4,0,0), P3D.create(4,2,0)),
    ]
    for p1, p2 in points:
        sktLines.addByTwoPoints(p1, p2)

    app.activeViewport.fit()

 

What was a little odd was that using the addSelection method in ActivateHandler would trigger the inputChanged event, but using the addSelection method in inputChanged would not trigger the inputChanged event.

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

Post to forums  

Autodesk Design & Make Report