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: 

Getting user seletions halfway through a script

10 REPLIES 10
Reply
Message 1 of 11
__JP
458 Views, 10 Replies

Getting user seletions halfway through a script

I have a high level question about how to get user selection halfway through a script execution.

Basically I have a C++ script that when run has this process:

 

  1. Get user input via a command dialog at the start of the script. (Works great)
  2. Draw some kind of sketch that has profiles (Sketch draws ok, no problems)
  3. Get user to select more than one profile (<- How to do?)
  4. Do something with the profiles (extrude etc)

Do I need a second dialog command, if so how? Or is there an easier way?

Do I need to change from script to an addin?

10 REPLIES 10
Message 2 of 11
JeromeBriot
in reply to: __JP

Hello,

 

I though it could be possible to run the UserInterface.selectEntity method inside a while loop to populate an ObjectCollection object. But I faced an issue as reported here.

 

Here is the idea (in Python):

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

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

        design = app.activeProduct

        # Get the root component of the active design.
        rootComp = design.rootComponent

        # Create a new sketch on the xy plane.
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        sketch = sketches.add(xyPlane)

        # Draw some circles.
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), 2)
        circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(8, 3, 0), 3)

        # Add a circle at the center of one of the existing circles.
        circle3 = circles.addByCenterRadius(circle2.centerSketchPoint, 4)

        profiles = adsk.core.ObjectCollection.create()

        while 1:
            selection = ui.selectEntity('Select profiles', 'Profiles')
            if selection:
                profiles.add(selection.entity)
            else:
                break

        if profiles.count > 0:
            # Create an extrusion input
            extrudes = rootComp.features.extrudeFeatures
            extInput = extrudes.createInput(profiles, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

            # Define that the extent is a distance extent of 5 cm
            distance = adsk.core.ValueInput.createByReal(5.0)
            # Set the distance extent
            extInput.setDistanceExtent(False, distance)
            # Set the extrude type to be solid
            extInput.isSolid = True

            # Create the extrusion
            ext = extrudes.add(extInput)

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

 

Message 3 of 11
JeromeBriot
in reply to: __JP


@JeromeBriot wrote:

 But I faced an issue as reported here.

Here is a code with a workaround suggested by @kandennti  in this discussion:

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

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

        design = app.activeProduct

        # Get the root component of the active design.
        rootComp = design.rootComponent

        # Create a new sketch on the xy plane.
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        sketch = sketches.add(xyPlane)

        # Draw some circles.
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), 2)
        circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(8, 3, 0), 3)

        # Add a circle at the center of one of the existing circles.
        circle3 = circles.addByCenterRadius(circle2.centerSketchPoint, 4)

        profiles = adsk.core.ObjectCollection.create()

        while 1:
            try:
                selection = ui.selectEntity('Select profiles', 'Profiles')
                if selection:
                    profiles.add(selection.entity)
                else:
                    break
            except:
                break

        if profiles.count > 0:
            # Create an extrusion input
            extrudes = rootComp.features.extrudeFeatures
            extInput = extrudes.createInput(profiles, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

            # Define that the extent is a distance extent of 5 cm
            distance = adsk.core.ValueInput.createByReal(5.0)
            # Set the distance extent
            extInput.setDistanceExtent(False, distance)
            # Set the extrude type to be solid
            extInput.isSolid = True

            # Create the extrusion
            ext = extrudes.add(extInput)

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

You should be able to translate this code in C++

Message 4 of 11
__JP
in reply to: JeromeBriot

 

 
 

Well this is annoying... fusion forum posting is giving issues...

 

Trying to post for a 5th %/#&%ing time...

while (true)
		{
			try 
			{
				Ptr<Selection> selection = ui->selectEntity("Select the clips profiles", "Profiles");

				if (selection)
				{
					profilesCollection->add(selection->entity());
				}
				else
				{
					break;
				}
			}
			catch (int ex)
			{
				break;
			}
		}

green bar of death.png

The script can be debugged with the break tool until selectEntity, then Fusion hangs forever.


Is there an alternative method to try?

 

Message 5 of 11
JeromeBriot
in reply to: __JP

You have to hit the Esc key to stop the while loop.

Message 6 of 11
__JP
in reply to: JeromeBriot

Thanks for the help.

I'm going to conclude selecting profiles mid-script is not possible.

 

I have changed the way the design is built so to produce only easily identifiable profiles in the sketches.

If someone finds an answer in the future, please add a reply.

Message 7 of 11
JeromeBriot
in reply to: __JP


@__JP wrote:

I'm going to conclude selecting profiles mid-script is not possible.

Did you try to run the Python script I posted?

 

First it creates 3 profiles.

Then it asks the user for selection until the Esc key is pressed.

Finally it extrudes the selected profiles.

 

It works on my machine.

Message 8 of 11
__JP
in reply to: JeromeBriot

I tried it, but I didn't see a dialog box or even anything to select (no sketches etc).

All I saw was the green bar.

 

That all happens inside the CommandExecuteEventHandler maybe thats the difference?

Message 9 of 11
JeromeBriot
in reply to: __JP


@__JP wrote:

That all happens inside the CommandExecuteEventHandler maybe thats the difference?


You're right. The code doesn't work when selectEntity is used inside the CommandExecuteEventHandler.

The documentation says that the method provides a simple way to prompt the user for a selection in a script.

Maybe @BrianEkins or @goyals can give us more information?

 

Warning: the code below make Fusion 360 to crash. Save your work before trying it.

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

_handlers = []

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

        cmdDefs = ui.commandDefinitions

        profilesSelectionButton = cmdDefs.addButtonDefinition('profilesSelectionButton',
                                                'Profiles Selection',
                                                '',
                                                '')

        profilesSelectionCommandCreated = profilesSelectionCommandCreatedEventHandler()
        profilesSelectionButton.commandCreated.add(profilesSelectionCommandCreated)
        _handlers.append(profilesSelectionCommandCreated)

        makePanel = ui.allToolbarPanels.itemById('MakePanel')

        makePanel.controls.addCommand(profilesSelectionButton, '', False)

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

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

        cmdDef = ui.commandDefinitions.itemById('profilesSelectionButton')
        if cmdDef:
            cmdDef.deleteMe()

        makePanel = ui.allToolbarPanels.itemById('MakePanel')
        cntrl = makePanel.controls.itemById('profilesSelectionButton')
        if cntrl:
            cntrl.deleteMe()

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

# Event handler for the commandCreated event.
class profilesSelectionCommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler):

    def __init__(self):
        super().__init__()

    def notify(self, args):

        try:

            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)

            cmd = eventArgs.command

            inputs = cmd.commandInputs

            inputs.addTextBoxCommandInput('myTextBox', '', 'Click OK', 1, True)

            # Connect to the execute event.
            onExecute = profilesSelectionCommandOKHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()), '')
                
# Event handler for the execute event.
class profilesSelectionCommandOKHandler(adsk.core.CommandEventHandler):

    def __init__(self):
        super().__init__()

    def notify(self, args):

        try:

            app = adsk.core.Application.get()
            ui  = app.userInterface

            design = app.activeProduct

            # Get the root component of the active design.
            rootComp = design.rootComponent

            # Create a new sketch on the xy plane.
            sketches = rootComp.sketches
            xyPlane = rootComp.xYConstructionPlane
            sketch = sketches.add(xyPlane)

            # Draw some circles.
            circles = sketch.sketchCurves.sketchCircles
            circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), 2)
            circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(8, 3, 0), 3)

            # Add a circle at the center of one of the existing circles.
            circle3 = circles.addByCenterRadius(circle2.centerSketchPoint, 4)

            profiles = adsk.core.ObjectCollection.create()

            selection = ui.selectEntity('Select profiles', 'Profiles')
            if selection:
                profiles.add(selection.entity)

            # while 1:
            #     try:
            #         selection = ui.selectEntity('Select profiles', 'Profiles')
            #         if selection:
            #             profiles.add(selection.entity)
            #         else:
            #             break
            #     except:
            #         break

            if profiles.count > 0:
                # Create an extrusion input
                extrudes = rootComp.features.extrudeFeatures
                extInput = extrudes.createInput(profiles, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

                # Define that the extent is a distance extent of 5 cm
                distance = adsk.core.ValueInput.createByReal(5.0)
                # Set the distance extent
                extInput.setDistanceExtent(False, distance)
                # Set the extrude type to be solid
                extInput.isSolid = True

                # Create the extrusion
                ext = extrudes.add(extInput)

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()), '')
Message 10 of 11
kandennti
in reply to: JeromeBriot

I hope the API will provide methods that allow multiple selections like 'UserInterface.selectEntities'.
(CATIA macros have this function...)

 

There are commandInputs, but it takes a lot of work.

Message 11 of 11
kandennti
in reply to: JeromeBriot

The only way to make this work is now using CommandInputs.
Since the source code is too long, attach the file.

 

・class profilesSelectionCommandCreatedEventHandler
Create dialog.
Event registration.
Use SelectionCommandInput to manage profile selection.

Call sketch creation.

 

・class profilesSelectionValidateInputsHandler
Manage dialog OK buttons.

 

・class profilesSelectionCommandOKHandler
Extract selection profile.
Invoke Create Extrude.

 

・class InitSketch

Create sketch.

 

・class InitExtrude
Creating an extrusion.

 

I wrote in this link, probably command.inputs and
I think userInterface.selectEntity cannot be used together.

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/how-to-use-mousedown-up-click-move-handler... 

 

I hope want 'UserInterface.selectEntities'.

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