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: 

MouseEventArgs.position

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
SaeedHamza
188 Views, 4 Replies

MouseEventArgs.position

Hi,

 

So I'm trying to create a copy tool that works similar to the copy tool in AutoCAD (for sketch entities only), which by the way does already exist in Fusion 360 here : drawings workspace > Create Menu > Create Sketch > Modify Menu > Copy.

 

I already created everything I need for the add-in but only one thing is left and that is the position of the mouse left click when the user presses it ...

so I need to get the mouse position in the viewport the moment the user clicks it, also to specify that the click should be a left-click for it to work.

 

The problem I'm facing is with the MouseEventArgs, I just don't know where or how exactly to use it. I read almost every topic on the forums regarding this matter but didn't get a clear answer on how to do it, so if there is a sample on how to do it, it would be much appreciated, thanks.

 

Saeed

 

Capture.PNG

 

4 REPLIES 4
Message 2 of 5
kandennti
in reply to: SaeedHamza

Hi @SaeedHamza .

 

When I tried this in the past, I was able to get the coordinates I wanted by using MouseEventArgs.viewportPosition.
However, since the object obtained was a Point2D, it needed to be calculated.

 

The following sample shows how to run the script while working on a sketch, and it will display the coordinate values on the sketch every time you click on it.

# Fusion360API Python script

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

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


class MyMouseClickHandler(adsk.core.MouseEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args: adsk.core.MouseEventArgs):
        adsk.core.Application.get().log(args.firingEvent.name)

        # Current mouse cursor position.
        cursor2D: adsk.core.Point2D = args.viewportPosition

        # get viewport.
        vp: adsk.core.Viewport = args.viewport

        # Convert from view coordinates to 3D coordinates.
        pos3d: adsk.core.Point3D = vp.viewToModelSpace(cursor2D)

        # Get a sketch of the work in progress.
        global _app
        skt: adsk.fusion.Sketch = _app.activeEditObject

        # Get the geometry of the sketch plane.
        # But I think this method does not work in direct mode.
        refPlane = skt.referencePlane
        plane: adsk.core.Plane = refPlane.geometry

        # Get vector of eye-target from camera.
        # In short, get the direction you are facing.
        cam: adsk.core.Camera = vp.camera
        vec: adsk.core.Vector3D = cam.eye.vectorTo(cam.target)

        # Create an infinite line of the camera direction passing through the mouse cursor position.
        infiniteLine: adsk.core.InfiniteLine3D = adsk.core.InfiniteLine3D.create(
            pos3d, vec
        )

        # Obtain the intersection of a plane and an infinite line.
        interPnt: adsk.core.Point3D = plane.intersectWithLine(infiniteLine)

        # Convert to coordinates on the sketch.
        posSkt: adsk.core.Point3D = skt.modelToSketchSpace(interPnt)

        # Calculate the ratio for unit conversion.
        des: adsk.fusion.Design = _app.activeProduct
        unitMgr: adsk.core.UnitsManager = des.unitsManager
        unitInter = unitMgr.internalUnits
        unitDef = unitMgr.defaultLengthUnits

        ratio: float = unitMgr.convert(1, unitInter, unitDef)

        # Update the coordinate values of the dialog.
        global _txtIptInfo
        inputs: adsk.core.CommandInputs = args.firingEvent.sender.commandInputs
        txtIpt: adsk.core.TextBoxCommandInput = inputs.itemById('txtIpt')

        txtIpt.text = f'X:{posSkt.x * ratio}\nY:{posSkt.y * ratio}\nZ:{posSkt.z * ratio}'


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)
            cmd.isOKButtonVisible = False

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

            onMouseClick = MyMouseClickHandler()
            cmd.mouseClick.add(onMouseClick)
            _handlers.append(onMouseClick)

            # inputs
            inputs: adsk.core.CommandInputs = cmd.commandInputs

            inputs.addTextBoxCommandInput(
                'txtIpt',
                'position',
                '-',
                3,
                True
            )

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


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

        # Quit the script when you are not working on a sketch.
        actEditObj = _app.activeProduct.activeEditObject
        if actEditObj.classType() != adsk.fusion.Sketch.classType():
            _ui.messageBox(
                'This can only be done in a sketch task.'
            )
            return

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

I don't think it will work correctly in direct mode or sketching in deep Occurrence.

 

There may be an easier way to get the coordinate values, but this is the only way I could find.

Message 3 of 5
SaeedHamza
in reply to: kandennti

Hi @kandennti ,

 

Thanks so much for the above example, this showed me a lot of things that I was missing, definitely gonna help!

 

Also, I found a mouse example that shows how to get the coordinates and pretty much every mouse event that occurs by the user, and with your example above I'm confident I  got all I need.

 

Here is the Mouse Example : https://adndevblog.typepad.com/manufacturing/2016/09/fusion-api-usage-of-mouse-event.html

Message 4 of 5
kandennti
in reply to: SaeedHamza

@SaeedHamza .

 

1.png

The viewportPosition property (0,0) means the top-left corner of Fusion360.

 

The position property (0,0) means the top-left corner of the display.
Therefore, you will not be able to get the correct coordinates due to the position of the Fusion360 window.

 

On the other hand, if you want to know the position of the Fusion360 window, the position property will be useful.

Message 5 of 5
BrianEkins
in reply to: SaeedHamza

The Viewport object also contains several methods that will convert points in different spaces to another space. For example, there is screenToView and viewToModelSpace.

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

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