Getting user seletions halfway through a script

Getting user seletions halfway through a script

Anonymous
Not applicable
1,677 Views
10 Replies
Message 1 of 11

Getting user seletions halfway through a script

Anonymous
Not applicable

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?

0 Likes
1,678 Views
10 Replies
Replies (10)
Message 2 of 11

JeromeBriot
Mentor
Mentor

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

 

0 Likes
Message 3 of 11

JeromeBriot
Mentor
Mentor

@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

Anonymous
Not applicable

 

 
 

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?

 

0 Likes
Message 5 of 11

JeromeBriot
Mentor
Mentor

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

Message 6 of 11

Anonymous
Not applicable

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.

0 Likes
Message 7 of 11

JeromeBriot
Mentor
Mentor

@Anonymous 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.

0 Likes
Message 8 of 11

Anonymous
Not applicable

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?

0 Likes
Message 9 of 11

JeromeBriot
Mentor
Mentor

@Anonymous 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
Mentor
Mentor

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
Mentor
Mentor

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'.

0 Likes