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: 

Cryptic exception

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
brad.bylls
316 Views, 7 Replies

Cryptic exception

When running my project a sketch script, I get an error message that I don't understand.

Untitled.png

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The code is this:

50    def on_execute(self, command, inputs, args, input_values):
51
52        global strResult
53
54        sketches = activeComp.sketches
55        newSketch = sketches.addWithoutEdges(xyPlane) # xyPlane is user selected
56        newSketch.name = strResult # sketch to project from
57        sketchPoints = moldBaseComp.sketches.itemByName(strResult).sketchPoints
58        [newSketch.project(p) for p in sketchPoints]
59
60        strResult = ''

newSketch is created properly. It shows in the history.

sketchPoints has the proper number of points based on the original sketch.

I know that line 58 can also be written

    for p in sketchPoints:

        newSketch.project(p)

But the error is the same.

 

I don't understand what the RuntimeError: 2: means.

Can someone please explain it so I can fix the problem.

Thank you.

Brad Bylls
7 REPLIES 7
Message 2 of 8
BrianEkins
in reply to: brad.bylls

A lot of the API functions don't return a very help message when they fail.  This is in part due to the fact the internal function the API calls doesn't provide useful information either.  In any case, rather than try to make sense from the error it's best to post a simple f3d and the accompanying code that can be used to reproduce the problem and the development team can take a closer look.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 8
brad.bylls
in reply to: BrianEkins

Brian,

Here is the link to the file:  https://a360.co/3Ddw9Mf

And here is the script.

I had to re-write it from the original add-in to be just a script.

It was part of a Patrick Rainsberry APPER add-in.

import adsk.core, adsk.fusion, traceback
import math

# Globals
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
strResult = ''

_handlers = []

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui  = _app.userInterface

        cmdDef = _ui.commandDefinitions.itemById('adskSpurGearPythonScript')
        if not cmdDef:
            # Create a command definition.
            cmdDef = _ui.commandDefinitions.addButtonDefinition('adskSpurGearPythonScript', 'Spur Gear', 'Creates a spur gear component', 'Resources/SpurGear') 
        
        # Connect to the command created event.
        onCommandCreated = SketchCommandCreatedHandler()
        cmdDef.commandCreated.add(onCommandCreated)
        _handlers.append(onCommandCreated)
        
        # Execute the command.
        cmdDef.execute()

        # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
        adsk.autoTerminate(False)
    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

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

            # when the command is done, terminate the script
            # this will release all globals which will remove all event handlers
            adsk.terminate()
        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the commandCreated event.
class SketchCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
            
            cmd = eventArgs.command
            cmd.isExecutedWhenPreEmpted = False
            inputs = cmd.commandInputs

            global _inputSelectSketch, activeComp, moldBaseComp, _inputErrMessage, _inputSelectFace, dropdown1Items, des
                
            product = _app.activeProduct
            des = adsk.fusion.Design.cast(product)
            rootComp = des.rootComponent
            moldBase = rootComp.occurrences.asList.item(0)
            moldBaseComp = adsk.fusion.Component.cast(moldBase.component)
            activeComp = des.activeComponent

            # Verify that a Fusion design is active.
            if not des:
                _ui.messageBox('A Fusion design must be active when invoking this command.')
                return()

            cmd.okButtonText = ("Project the Sketch") # text in "OK" button
            cmd.isExecutedWhenPreEmpted = False

            # Create the command dialog
            _inputSelectFace = inputs.addSelectionInput('face', 'Select Planar Face', 'Select a Planar Face\nfot the new Sketch Plane')
            _inputSelectFace.addSelectionFilter(adsk.core.SelectionCommandInput.PlanarFaces)
            _inputSelectFace.setSelectionLimits(1,1)

            _inputSelectSketch = inputs.addDropDownCommandInput('sketch', 'Select a Sketch', adsk.core.DropDownStyles.TextListDropDownStyle)
            _inputSelectSketch.isVisible = False
            dropdown1Items = _inputSelectSketch.listItems
            dropdown1Items.add(' ', True, '')

            moldBaseSketches = moldBaseComp.sketches
            for sketch in moldBaseSketches:
                dropdown1Items.add(sketch.name, False, '')

            _inputErrMessage = inputs.addTextBoxCommandInput('errMessage', '', '', 2, True)
            _inputErrMessage.isFullWidth = True
            
            # Connect to the command related events.
            onExecute = SketchCommandExecuteHandler()
            cmd.execute.add(onExecute)
            _handlers.append(onExecute)        
            
            onInputChanged = SketchCommandInputChangedHandler()
            cmd.inputChanged.add(onInputChanged)
            _handlers.append(onInputChanged)     
            
            onValidateInputs = SketchCommandValidateInputsHandler()
            cmd.validateInputs.add(onValidateInputs)
            _handlers.append(onValidateInputs)

            onDestroy = SketchCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            _handlers.append(onDestroy)

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


# Event handler for the execute event.
class SketchCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)

            global strResult, activeComp, moldBaseComp

            sketches = activeComp.sketches
            newSketch = sketches.addWithoutEdges(xyPlane)
            newSketch.name = strResult
            sketchPoints = moldBaseComp.sketches.itemByName(strResult).sketchPoints
            [newSketch.project(p) for p in sketchPoints]
            sketchCurves = moldBaseComp.sketches.itemByName(strResult).sketchCurves
            [newSketch.project(c) for c in sketchCurves]

            strResult = ''

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))   
        
# Event handler for the inputChanged event.
class SketchCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.InputChangedEventArgs.cast(args)
            changedInput = eventArgs.input
            inputs :adsk.core.CommandInputs = eventArgs.inputs
            
            global _inputSelectSketch, _inputErrMessage, strResult, xyPlane, clickPoint

            if changedInput.id == 'face':
                selection_input = inputs.itemById('face')
                selection = selection_input.selection(0)
                xyPlane = selection.entity

                _inputSelectSketch.isVisible = True

            elif changedInput.id == 'sketch':
                strResult = inputs.itemById('sketch').selectedItem.name

        except:
            if _ui:
                _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))        
        
# Event handler for the validateInputs event.
class SketchCommandValidateInputsHandler(adsk.core.ValidateInputsEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.ValidateInputsEventArgs.cast(args)
            
            if strResult != ' ':
                return True
            else:
                return False

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

Here is the error message to this script (same message as before, different line number)

Untitled.png

Thank you for the help.

This is the last stepping stone for my add-in. (I think)

Brad Bylls
Message 4 of 8
BrianEkins
in reply to: brad.bylls

Thanks for posting the sample.  The error is very cryptic but I should have recognized that the message contained "path". Once I saw your code I realized what it is. The problem is proxies and the assembly context. The projection is happening at the top-level assembly but the sketch curves and points you've gotten are in the context of another component.  I've modified the execute event so it now works.

 

# Event handler for the execute event.
class SketchCommandExecuteHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            eventArgs = adsk.core.CommandEventArgs.cast(args)

            global strResult, activeComp, moldBaseComp

            sketches = activeComp.sketches
            newSketch = sketches.addWithoutEdges(xyPlane)
            newSketch.name = strResult
            sketchPoints = moldBaseComp.sketches.itemByName(strResult).sketchPoints
            rootComp = _app.activeProduct.rootComponent
            moldBaseOcc: adsk.fusion.Occurrence = rootComp.occurrences.itemByName('Component1:1')

            [newSketch.project(p.createForAssemblyContext(moldBaseOcc)) for p in sketchPoints]
            sketchCurves = moldBaseComp.sketches.itemByName(strResult).sketchCurves
            [newSketch.project(c.createForAssemblyContext(moldBaseOcc)) for c in sketchCurves]

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

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 5 of 8
brad.bylls
in reply to: BrianEkins

Brian,

Thank you so much for the help.

That worked.

Now I must apologize and I am so sorry.

I sent you a bad model.

Comoponent1:1 and Component2:1 are both sub-components of MoldBase:1 where the original sketches are.

Here is a new model:  https://a360.co/3Ddw9Mf

It causes a different error now.

I am truly sorry because I really don't know how to fix it. I've been working with it for hours.

Thank you.

Brad Bylls
Message 6 of 8
BrianEkins
in reply to: brad.bylls

Here's a modified version of the original program that works with the new assembly.  I'm not sure where the new sketch is supposed to be created so this creates it in the component that owns the selected face.  The new program is attached.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 7 of 8
brad.bylls
in reply to: BrianEkins

Brian,

Thanks so much for the help.

Just what I needed.

Perfect.

Brad Bylls
Message 8 of 8
brad.bylls
in reply to: BrianEkins

Brian,

This works better than I expected.

And because you made the new sketch on the occurrence of the face selected, I am trying to activate that occurrence as well.

According to the documentation:

"Makes the occurrence the active edit target in the user interface. This is the same as enabling the radio button next to the occurrence in the browser."

So I added some lines to your code (I modified it for my add-in script)

        selFace: adsk.fusion.BRepFace = _inputSelectFace.selection(0).entity
        faceComp = selFace.nativeObject.body.parentComponent
        faceCompName = faceComp.name + ':1'
        newActiveOcc: adsk.fusion.Occurrence = moldBaseComp.occurrences.itemByName(faceCompName)
        newActiveOcc.activate()
        newSketch: adsk.fusion.Sketch = faceComp.sketches.addWithoutEdges(selFace.nativeObject)
        newSketch.createForAssemblyContext(selFace.assemblyContext)       
        newSketch.name = strResult
        sketchPoints = moldBaseComp.sketches.itemByName(strResult).sketchPoints
        rootComp = _app.activeProduct.rootComponent
        moldBaseOcc: adsk.fusion.Occurrence = rootComp.occurrences.itemByName(moldBaseName)

        [newSketch.project(p.createForAssemblyContext(moldBaseOcc)) for p in sketchPoints]
        sketchCurves = moldBaseComp.sketches.itemByName(strResult).sketchCurves
        [newSketch.project(c.createForAssemblyContext(moldBaseOcc)) for c in sketchCurves] 

The "newActiveOcc.activate()" does nothing.

The script works correctly except making the faceComp the active occurrence.

What am I missing?

According the documentation this should work.

newActiveOcc is the correct occurrence object.

Thank you for your help.

Brad Bylls

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