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: 

User Command Preview does not work, execute does.

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
adminTCYL2
398 Views, 2 Replies

User Command Preview does not work, execute does.

I have done a nice little skript to generate Ropes, Coils and Cords along a users curve: 

adminTCYL2_0-1627493951668.png

adminTCYL2_0-1627496231440.png

 

By now the script works only after pressing "OK". As seen in the montage-picture, the User should see what his settings do while the settings-window is opened. But he sees the result only after pressing Ok and thereby closing this window. This is, because the  Class "MyInputChangeHandler" does not work right. But it is not written by me and I am confused. I wrote a boolean named "execute" into line 35. The MyInputChangeHandler sets this to False, so the rest of the skript is only done by MyExecuteHandler. Otherwise it tries to make previews, but this leads to failures.


Can someone help me to improve this skript? I want to give it for free to the Autocad Website:

 

 

 

import adsk.core, adsk.fusion, adsk.cam, traceback, os, math
# Global variables to keep them referenced for the duration of the command
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
_handlers = []
_dropdownInput3 = adsk.core.DropDownCommandInput.cast(None)
_inputs = adsk.core.CommandInputs.cast(None)

def makeIt(execute): 
    try:
        # Here is my code that is done with every change in User-Selections:

        # Get UserCommand-Values
        curve = _inputs.itemById('selection').selection(0).entity
        broadness = _inputs.itemById('broadness').value
        thickness = _inputs.itemById('thickness').value
        rotations = _inputs.itemById('rotations').value
        shape = _dropdownInput3.selectedItem.name

        design = _app.activeProduct
        root_comp = design.rootComponent
        # create new component
        # newOcc1 = rootComp.occurrences.addNewComponent(adsk.core.Matrix3D.create())
        # root_comp = newOcc1.component
        # root_comp.name = 'Windings'
        path = root_comp.features.createPath(curve)
        planes = root_comp.constructionPlanes
        planeInput = planes.createInput()
        distance = adsk.core.ValueInput.createByReal(0)
        planeInput.setByDistanceOnPath(path, distance)
        
        #execute = True
        if execute:
            plane = planes.add(planeInput)
            sketches = root_comp.sketches
            sketch = sketches.add(plane)

            # Define lines for linear profiles
            point1a = sketch.sketchPoints.add(adsk.core.Point3D.create(broadness, 0, 0))
            point1b = sketch.sketchPoints.add(adsk.core.Point3D.create(-broadness,0, 0))
            point2a = sketch.sketchPoints.add(adsk.core.Point3D.create(0, broadness, 0))
            point2b = sketch.sketchPoints.add(adsk.core.Point3D.create(0,-broadness, 0))
            line1 = sketch.sketchCurves.sketchLines.addByTwoPoints(point1a, point1b)
            line2 = sketch.sketchCurves.sketchLines.addByTwoPoints(point2a, point2b)
        

            if shape == 'Rope': loops = 2
            else: loops = 1
            for p in range (0,loops): 
                #create the correct sweep witch edge is used as Path. 
                if p==1: 
                    prof = root_comp.createOpenProfile(line1, False) 
                else:
                    prof = root_comp.createOpenProfile(line2, False) 
                sweeps = root_comp.features.sweepFeatures 
                sweepInput = sweeps.createInput(prof, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
                sweepInput.twistAngle = adsk.core.ValueInput.createByReal(rotations*math.pi*2)
                sweepInput.isSolid = False
                sweep = sweeps.add(sweepInput)
                lastBody = root_comp.bRepBodies.count-1
                body = root_comp.bRepBodies.item(lastBody)
                body.isLightBulbOn = False

                loop = 2
                if shape == 'Coil': loop = 1
                for k in range(0, loop):
                    if k ==0: edge = body.edges.item(1)
                    else: edge = body.edges.item(3)
                    twist = 0
                    # The edge of the flat sweep is now used as path for the solid sweeps
                    path1 = root_comp.features.createPath(edge, False)
                    planeInput = planes.createInput()
                    distance = adsk.core.ValueInput.createByReal(0)
                    planeInput.setByDistanceOnPath(path1, distance)
                    plane1 = planes.add(planeInput)
                    sketches1 = root_comp.sketches
                    sketch1 = sketches1.add(plane1)
                    circle1 = sketch1.sketchCurves.sketchCircles.addByCenterRadius(adsk.core.Point3D.create(0,0,0), thickness/2)
                    prof1 = sketch1.profiles.item(0)

                    # create solid sweep
                    itemIndex1 = root_comp.bRepBodies.count
                    sweeps = root_comp.features.sweepFeatures 
                    sweepInput1 = sweeps.createInput(prof1, path1, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
                    sweepInput1.twistAngle = adsk.core.ValueInput.createByReal(twist)
                    sweepInput1.isSolid = True
                    sweep = sweeps.add(sweepInput1)

            # Here is my code that is additionaly done when User presses OK:
            _ui.messageBox("your Selection was: Shape: "+shape + ", Broadness: "+ str(broadness)+ ", Thickness: "+ str(thickness)+", Rotations: "+ str(rotations))

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

# Event handler for the inputChanged event.
class MyInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            changedInput = eventArgs.input
            execute = False
            makeIt(execute)
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the execute event.
class MyExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            execute=True
            makeIt(execute)
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the destroy event.
class MyDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        adsk.terminate()

# Event handler for the commandCreated event.
# Here you create your UserCommands
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
            global _inputs
            _inputs = adsk.core.CommandInputs.cast(eventArgs.command.commandInputs)

            message = '<div align="center">See also my <a href="http:picsandpixels.at/windings">windings-AddIn</a></div>'
            _inputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 1, True)  

            selInput = _inputs.addSelectionInput('selection', 'Select open curve', 'SketchCurves')
            selInput.setSelectionLimits(1)
            selInput.addSelectionFilter('SketchCurves')

            global _dropdownInput3     
            _dropdownInput3 = _inputs.addDropDownCommandInput('dropdown3', 'shape', adsk.core.DropDownStyles.LabeledIconDropDownStyle)
            _dropdownInput3.listItems.add('Cord', False, '')
            _dropdownInput3.listItems.add('Rope', True, '')
            _dropdownInput3.listItems.add('Coil', False, '')

            _inputs.addValueInput('broadness', 'Broadness', 'mm', adsk.core.ValueInput.createByReal(0.4))
            _inputs.addValueInput('thickness', 'Thickness', 'mm', adsk.core.ValueInput.createByReal(0.2))
            _inputs.addIntegerSpinnerCommandInput('rotations', 'Rotations', 0, 20, 1, 10)

            # Connect to command execute.
            onExecute = MyExecuteHandler()
            eventArgs.command.execute.add(onExecute)
            _handlers.append(onExecute)

            # Connect to input changed.
            onInputChanged = MyInputChangedHandler()
            eventArgs.command.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)

            # Connect to the command terminate.
            onDestroy = MyDestroyHandler()
            eventArgs.command.destroy.add(onDestroy)
            _handlers.append(onDestroy)  
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
        
def run(context):  
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui  = _app.userInterface
        
        # Create a command.
        cmd = _ui.commandDefinitions.itemById('tableTest')
        if cmd:
            cmd.deleteMe()
# Rename the script in the following line:
        cmd = _ui.commandDefinitions.addButtonDefinition('tableTest', 'Cord, Rope, Coil -Maker', 'Table Test', '')
        onCommandCreated = MyCommandCreatedHandler()
        cmd.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmd.execute()
        # Set this so the script continues to run.
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

 

 

2 REPLIES 2
Message 2 of 3
kandennti
in reply to: adminTCYL2

Hi @adminTCYL2 .

 

For preview, use the executePreview event instead of the inputChanged event.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-dbecfaf8-9bb6-4e40-9df3-0a3e48136a4b 


I modified it like this, and it works correctly.

・・・
class MyInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            # changedInput = eventArgs.input
            # execute = False
            # makeIt(execute)
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

・・・

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
・・・
            onExecutePreview = MyExecutePreviewHandler()
            eventArgs.command.executePreview.add(onExecutePreview)
            _handlers.append(onExecutePreview)
・・・

class MyExecutePreviewHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        eventArgs = adsk.core.CommandEventArgs.cast(args)

        execute = True
        makeIt(execute)

Items created by the executePreview event will be deleted on their own without the need to delete them.

Message 3 of 3
adminTCYL2
in reply to: adminTCYL2

Yes! It works. Thank you kanndenti, 
I cleaned the code a bit, to put it here as an example for a working user selection. 

import adsk.core, adsk.fusion, adsk.cam, traceback, os, math
# Global variables to keep them referenced for the duration of the command
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
_handlers = []
_dropdownInput3 = adsk.core.DropDownCommandInput.cast(None)
_inputs = adsk.core.CommandInputs.cast(None)

def makeIt(): 
    try:
        # Here is my code that is done with every change in User-Selections:
        # Get UserCommand-Values
        curve = _inputs.itemById('selection').selection(0).entity
        broadness = _inputs.itemById('broadness').value/4
        thickness = _inputs.itemById('thickness').value/2
        rotations = _inputs.itemById('rotations').value
        shape = _dropdownInput3.selectedItem.name

        design = _app.activeProduct
        rootComp = design.rootComponent
        # create new component
        newOcc1 = rootComp.occurrences.addNewComponent(adsk.core.Matrix3D.create())
        root_comp = newOcc1.component
        root_comp.name = 'CordRopeCoil'
        #path = adsk.fusion.Path.create(curve,1) 
        # #see https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1728AD08-743F-4ABB-AA10-C2B2C53A0757
        path = root_comp.features.createPath(curve)
        planes = root_comp.constructionPlanes
        planeInput = planes.createInput()
        distance = adsk.core.ValueInput.createByReal(0)
        planeInput.setByDistanceOnPath(path, distance)
        
        plane = planes.add(planeInput)
        sketches = root_comp.sketches
        sketch = sketches.add(plane)

        # Define lines for linear profiles
        point1a = sketch.sketchPoints.add(adsk.core.Point3D.create(broadness, 0, 0))
        point1b = sketch.sketchPoints.add(adsk.core.Point3D.create(-broadness,0, 0))
        point2a = sketch.sketchPoints.add(adsk.core.Point3D.create(0, broadness, 0))
        point2b = sketch.sketchPoints.add(adsk.core.Point3D.create(0,-broadness, 0))
        line1 = sketch.sketchCurves.sketchLines.addByTwoPoints(point1a, point1b)
        line2 = sketch.sketchCurves.sketchLines.addByTwoPoints(point2a, point2b)
    
        if shape == 'Rope': loops = 2
        else: loops = 1
        for p in range (0,loops): 
            #create the correct sweep witch edge is used as Path. 
            if p==1: 
                prof = root_comp.createOpenProfile(line1, False) 
            else:
                prof = root_comp.createOpenProfile(line2, False) 
            sweeps = root_comp.features.sweepFeatures 
            sweepInput = sweeps.createInput(prof, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
            sweepInput.twistAngle = adsk.core.ValueInput.createByReal(rotations*math.pi*2)
            sweepInput.isSolid = False
            sweep = sweeps.add(sweepInput)
            lastBody = root_comp.bRepBodies.count-1
            body = root_comp.bRepBodies.item(lastBody)
            body.isLightBulbOn = False

            loop = 2
            if shape == 'Coil': loop = 1
            for k in range(0, loop):
                if k ==0: edge = body.edges.item(1)
                else: edge = body.edges.item(3)
                twist = 0
                # The edge of the flat sweep is now used as path for the solid sweeps
                path1 = root_comp.features.createPath(edge, False)
                planeInput = planes.createInput()
                distance = adsk.core.ValueInput.createByReal(0)
                planeInput.setByDistanceOnPath(path1, distance)
                plane1 = planes.add(planeInput)
                sketches1 = root_comp.sketches
                sketch1 = sketches1.add(plane1)
                circle1 = sketch1.sketchCurves.sketchCircles.addByCenterRadius(adsk.core.Point3D.create(0,0,0), thickness/2)
                prof1 = sketch1.profiles.item(0)

                # create solid sweep
                itemIndex1 = root_comp.bRepBodies.count
                sweeps = root_comp.features.sweepFeatures 
                sweepInput1 = sweeps.createInput(prof1, path1, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
                sweepInput1.twistAngle = adsk.core.ValueInput.createByReal(twist)
                sweepInput1.isSolid = True
                sweep = sweeps.add(sweepInput1)
                #_ui.messageBox("your Selection was: Shape: "+shape)

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

class MyExecutePreviewHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        eventArgs = adsk.core.CommandEventArgs.cast(args)
        makeIt()

class MyExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            makeIt()
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

class MyDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        adsk.terminate()

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
# Here the your UserCommands are created
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
            global _inputs
            _inputs = adsk.core.CommandInputs.cast(eventArgs.command.commandInputs)

            message = '<div align="center">See also my <a href="http:picsandpixels.at/fusion360">windings-AddIn</a></div>'
            _inputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 1, True)  

            selInput = _inputs.addSelectionInput('selection', 'Select open curve', 'SketchCurves')
            selInput.setSelectionLimits(1)
            selInput.addSelectionFilter('SketchCurves')

            global _dropdownInput3     
            _dropdownInput3 = _inputs.addDropDownCommandInput('dropdown3', 'shape', adsk.core.DropDownStyles.LabeledIconDropDownStyle)
            _dropdownInput3.listItems.add('Cord', False, '')
            _dropdownInput3.listItems.add('Rope', True, '')
            _dropdownInput3.listItems.add('Coil', False, '')

            _inputs.addValueInput('broadness', 'Broadness', 'mm', adsk.core.ValueInput.createByReal(0.2))
            _inputs.addValueInput('thickness', 'Thickness', 'mm', adsk.core.ValueInput.createByReal(0.2))
            _inputs.addIntegerSpinnerCommandInput('rotations', 'Rotations', 0, 50, 1, 10)

            onExecutePreview = MyExecutePreviewHandler()
            eventArgs.command.executePreview.add(onExecutePreview)
            _handlers.append(onExecutePreview)

            onExecute = MyExecuteHandler()
            eventArgs.command.execute.add(onExecute)
            _handlers.append(onExecute)

            onDestroy = MyDestroyHandler()
            eventArgs.command.destroy.add(onDestroy)
            _handlers.append(onDestroy)  

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

        
def run(context):  
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui  = _app.userInterface
        
        # Create a command.
        cmd = _ui.commandDefinitions.itemById('tableTest')
        if cmd:
            cmd.deleteMe()
# Rename the script in the following line:
        cmd = _ui.commandDefinitions.addButtonDefinition('tableTest', 'Cord, Rope, Coil -Maker', 'Table Test', '')
        onCommandCreated = MyCommandCreatedHandler()
        cmd.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)

        cmd.execute()
        # Set this so the script continues to run.
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

adminTCYL2_0-1627724417652.png

 

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report