Allowing click-drag input for UserInterface.selectEntity ("Faces")

Allowing click-drag input for UserInterface.selectEntity ("Faces")

CADacombs
Enthusiast Enthusiast
543 Views
4 Replies
Message 1 of 5

Allowing click-drag input for UserInterface.selectEntity ("Faces")

CADacombs
Enthusiast
Enthusiast

When the mouse pointer is moving (but over a face) during the mouse click, the exception, 

2 : InternalValidationError : selections.size() > 0

is thrown for UserInterface.selectEntity.

The same exception is thrown when a key is pressed.  The script below can be used to demonstrate this.  While running it, click various location quickly on one or more faces.

 

I am looking for a way to accept click-drag input, similar to the GUI's Select Sketch, where a click-drag behaves the same as a click.

 

Otherwise, does anyone have a suggestion on how to distinguish a click-drag from a key press for UserInterface.selectEntity?

 

Thank you

 

import adsk.core, traceback


def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        
        app.log('-'*80)

        while True:
            try:
                returnValue = ui.selectEntity('Select a face', 'Faces')
                app.log("Successfully selected a face.")
            except Exception as err:
                app.log(str(err))
                break

    except:
        app.log('Failed:\n{}'.format(traceback.format_exc()))
    
    app.log("End of script.")

 

Fusion 360 2.0.12670

0 Likes
544 Views
4 Replies
Replies (4)
Message 2 of 5

kandennti
Mentor
Mentor

Hi @CADacombs .

 

When you say click-drag input, do you mean you want to select multiple surfaces?

The selectEntity method should only select a single element.

0 Likes
Message 3 of 5

CADacombs
Enthusiast
Enthusiast

Hi @kandennti
No, single entity picks are intended because the pick point for each is also needed. A practical script would be your
https://forums.autodesk.com/t5/fusion-360-api-and-scripts/surface-normal-of-brepface/m-p/10543256#M1...
When I run it and quickly pick different points on faces, I need to be careful that the mouse pointer is not moving. Otherwise, selectEntity fails.
0 Likes
Message 4 of 5

kandennti
Mentor
Mentor

@CADacombs .

 

It sounds like a problem with the way you operate.
How about using SelectionCommandInput?

# 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)

            onExecutePreview = MyExecutePreviewHandler()
            cmd.executePreview.add(onExecutePreview)
            _handlers.append(onExecutePreview)

            global _selIpt
            _selIpt = inputs.addSelectionInput(
                'select faces',
                'Faces',
                'select faces'
            )
            _selIpt.setSelectionLimits(0)
            _selIpt.addSelectionFilter('Faces')

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


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

        global _selIpt
        selFaces = []
        for idx in range(_selIpt.selectionCount):
            selFaces.append(_selIpt.selection(idx))

        createNormalLines(selFaces)

        args.isValidResult = True


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

        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 createNormalLines(
    selFaces: list):

    global _app
    des: adsk.fusion.Design = _app.activeProduct
    root: adsk.fusion.Component = des.rootComponent
    skt: adsk.fusion.Sketch = None

    sel: adsk.core.Selection
    for sel in selFaces:
        face: adsk.fusion.BRepFace = sel.entity
        click: adsk.core.Point3D = sel.point

        # get SurfaceEvaluator
        eva: adsk.core.SurfaceEvaluator = face.evaluator

        # get Normal
        normal: adsk.core.Vector3D
        _, normal = eva.getNormalAtPoint(click)
        normal.normalize()

        # target point
        target: adsk.core.Point3D = click.copy()
        target.translateBy(normal)

        # sketch
        if not skt:
            skt = root.sketches.add(root.xYConstructionPlane)
            skt.name = 'Normal'

        # create Normal Line
        skt.sketchCurves.sketchLines.addByTwoPoints(click, target)
Message 5 of 5

CADacombs
Enthusiast
Enthusiast

@kandennti ,

Thank you for your effort in preparing this. I may try to modify your procedure to get it work closer to UserInterface.selectEntity but without the behavior that I am reporting.

 

@ Autodesk ,

As a recap of the problem, the GIF below shows that when the mouse was moving during the 4th pick, UserInterface.selectEntity was tripped up.  Not only was the 4th pick not captured, but the previous results were lost.

 

UserInterface_selectEntity.gif

0 Likes