Message 1 of 9
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I wrote a script to load the f3d file I selected and change the user parameter values. The program loads the file 'file1.f3d' or 'file2.f3d' of my choice and immediately updates the user parameters ("width", "depth", "height"). Up to this point everything is OK. The problem is when I only change parameters. I get this message: AttributeError: 'NoneType' object has no attribute 'expression'. I displayed all_parameters.count while changing the value and it turns out that the MyExecutePreviewHandler call deletes the loaded file and user parameters. I don't know if I'm doing something wrong or it's a bug
import adsk.core, adsk.fusion, adsk.cam, traceback, os
_app = adsk.core.Application.get()
_ui = _app.userInterface
# Global set of event handlers to keep them referenced for the duration of the command
_handlers = []
CMD_ID = "f3dTest"
RES_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "")
old_file = None
# 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)
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)
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()
class MyExecutePreviewHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args: adsk.core.CommandEventArgs):
try:
eventArgs = adsk.core.CommandEventArgs.cast(args)
inputs = eventArgs.command.commandInputs
file = inputs.itemById(CMD_ID + "f3d_file_input").selectedItem.name
_app.log(f"{file = }")
global old_file
if old_file != file:
old_file = file
load_local_file(RES_FOLDER, file)
product = _app.activeProduct
design = adsk.fusion.Design.cast(product)
all_parameters = design.allParameters
_app.log(f"{all_parameters.count = }")
width = str(int(inputs.itemById(CMD_ID + "width").value * 10))
param_width = all_parameters.itemByName("width")
_app.log(f"{width = }")
param_width.expression = width
depth = str(int(inputs.itemById(CMD_ID + "depth").value * 10))
param_depth = all_parameters.itemByName("depth")
param_depth.expression = depth
height = str(int(inputs.itemById(CMD_ID + "height").value * 10))
param_height = all_parameters.itemByName("height")
param_height.expression = height
except:
if _ui:
_ui.messageBox("Failed:\n{}".format(traceback.format_exc()))
# Event handler for the commandCreated event.
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
inputs = adsk.core.CommandInputs.cast(eventArgs.command.commandInputs)
globalUnits = _app.activeProduct.unitsManager.defaultLengthUnits
f3d_file = adsk.core.DropDownStyles.LabeledIconDropDownStyle
f3d_file_input = inputs.addDropDownCommandInput(
CMD_ID + "f3d_file_input", "f3d file", f3d_file
)
f3d_file_items = f3d_file_input.listItems
f3d_file_items.add("file1", True)
f3d_file_items.add("file2", False)
width = adsk.core.ValueInput.createByString("1000")
input_width = inputs.addValueInput(
CMD_ID + "width",
"width",
globalUnits,
width,
)
depth = adsk.core.ValueInput.createByString("2000")
input_depth = inputs.addValueInput(
CMD_ID + "depth",
"depth",
globalUnits,
depth,
)
height = adsk.core.ValueInput.createByString("3000")
input_height = inputs.addValueInput(
CMD_ID + "height",
"height",
globalUnits,
height,
)
# 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)
onExecutePreview = MyExecutePreviewHandler()
eventArgs.command.executePreview.add(onExecutePreview)
_handlers.append(onExecutePreview)
# 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("f3dTest")
if cmd:
cmd.deleteMe()
cmd = _ui.commandDefinitions.addButtonDefinition(
"f3dTest", "f3d load test", "Load Test", ""
)
# Connect to the command create event.
onCommandCreated = MyCommandCreatedHandler()
cmd.commandCreated.add(onCommandCreated)
_handlers.append(onCommandCreated)
# Execute the command.
cmd.execute()
# Set this so the script continues to run.
adsk.autoTerminate(False)
except:
if _ui:
_ui.messageBox("Failed:\n{}".format(traceback.format_exc()))
def load_local_file(folder, file_name):
try:
load_file = os.path.join(folder, f"{file_name}.f3d")
if os.path.exists(load_file):
design = _app.activeProduct
root = design.rootComponent
importManager = _app.importManager
archiveOptions = importManager.createFusionArchiveImportOptions(load_file)
importManager.importToTarget(archiveOptions, root)
except:
_app.log("Failed:\n{}".format(traceback.format_exc()))
Solved! Go to Solution.