Message 1 of 2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I am trying to create a simple two side extrusion on a selected edge or line.
I have a preview button, and the preview handler works fine. However, when I click execute, the component is only created but fails to get the selected line.
In the snippet code (entry.py) writen below, I have 2 functions: drawSomething(args) which use the selected line/edge to create the extrusion, and drawSomething2(args) which create a component and extrusion hardcoded. One does not work while the other is OK.
Where am I wrong? After couple of days I am stuck on this issue.
import adsk.core
import adsk.fusion
import os
from ...lib import fusion360utils as futil
from ... import config
app = adsk.core.Application.get()
ui = app.userInterface
CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_duplicate_components'
CMD_NAME = 'Create Extrusion '
CMD_Description = 'Create a an Extrusion as new component'
IS_PROMOTED = True
# Working in DESIGN
WORKSPACE_ID = 'FusionSolidEnvironment'
PANEL_ID = 'SolidScriptsAddinsPanel' #TODO Change later# PANEL_ID = 'SolidCreatePanel'
COMMAND_BESIDE_ID = 'ScriptsManagerCommand'
ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '')
local_handlers = []
selectedEdges = []
# constants
DROPDOWN_GROUP_ID = 'drowdown_group'
DROPDOWN_ID = 'dropdown' #TODO
LINE_SELECTION = 'lineSelection'
PREVIEW_GROUP_ID = 'preview_group'
SHOW_PREVIEW_INPUT = 'show_preview'
SHOW_PREVIEW_MANUAL_INPUT = 'show_preview_manual'
def start():
# Create a command Definition.
cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER)
# Add command created handler. The function passed here will be executed when the command is executed.
futil.add_handler(cmd_def.commandCreated, command_created)
# ******** Add a button into the UI so the user can run the command. ********
# Get the target workspace the button will be created in.
workspace = ui.workspaces.itemById(WORKSPACE_ID)
# Get the panel the button will be created in.
panel = workspace.toolbarPanels.itemById(PANEL_ID)
# Create the button command control in the UI after the specified existing command.
control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False)
# Specify if the command is promoted to the main toolbar.
control.isPromoted = IS_PROMOTED
# Executed when add-in is stopped.
def stop():
# Get the various UI elements for this command
workspace = ui.workspaces.itemById(WORKSPACE_ID)
panel = workspace.toolbarPanels.itemById(PANEL_ID)
command_control = panel.controls.itemById(CMD_ID)
command_definition = ui.commandDefinitions.itemById(CMD_ID)
# Delete the button command control
if command_control:
command_control.deleteMe()
# Delete the command definition
if command_definition:
command_definition.deleteMe()
def command_created(args: adsk.core.CommandCreatedEventArgs):
# General logging for debug.
futil.log(f'{CMD_NAME} Command Created Event')
# TODO Create the event handlers you will need for this instance of the command
futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers)
futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers)
futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers)
futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers)
futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers)
# Create the user interface for your command by adding different inputs to the CommandInputs object
# https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs
inputs = args.command.commandInputs
# TODO ******************************** Define your UI Here ********************************
i1 = inputs.addSelectionInput(LINE_SELECTION, 'Edge', 'Please select a straight line or edge')
i1.setSelectionLimits(0)
i1.addSelectionFilter(adsk.core.SelectionCommandInput.Edges)
i1.addSelectionFilter(adsk.core.SelectionCommandInput.SketchLines)
# Dropdown group
profileGroup = inputs.addGroupCommandInput(DROPDOWN_GROUP_ID, 'Dropdown group')
# Drop Down
profileStandardDropdownInput = profileGroup.children.addDropDownCommandInput(DROPDOWN_ID,'Dropdown',adsk.core.DropDownStyles.TextListDropDownStyle)
profileStandardDropdownInput.listItems.add('Jim',True)
profileStandardDropdownInput.listItems.add('Jack',False)
profileStandardDropdownInput.listItems.add('Jim-Jack',False)
# Preview
previewGroup = inputs.addGroupCommandInput(PREVIEW_GROUP_ID, 'Preview')
#previewGroup.isExpanded = uiState.getGroupExpandedState(PREVIEW_GROUP_ID)
previewGroup.children.addBoolValueInput(SHOW_PREVIEW_INPUT, 'Show auto update preview (slow)', True, '', False)
showPreviewManual = previewGroup.children.addBoolValueInput(SHOW_PREVIEW_MANUAL_INPUT, 'Update preview once', False, '', False)
showPreviewManual.isFullWidth = True
def command_execute(args: adsk.core.CommandEventArgs):
# General logging for debug
futil.log(f'{CMD_NAME} Command Execute Event')
inputs = args.command.commandInputs
# TODO ******************************** Your code here ********************************
drawSomething(args)
# drawSomething2(args) #drawSomething2(args) does not contain any selection and works
# This function will be called when the command needs to compute a new preview in the graphics window
def command_preview(args: adsk.core.CommandEventArgs):
inputs = args.command.commandInputs
futil.log(f'{CMD_NAME} Command Preview Event')
if is_all_input_valid(inputs):
showPreview: adsk.core.BoolValueCommandInput = inputs.itemById(SHOW_PREVIEW_INPUT)
showPreviewManual: adsk.core.BoolValueCommandInput = inputs.itemById(SHOW_PREVIEW_MANUAL_INPUT)
if showPreview.value or showPreviewManual.value:
#args.isValidResult = drawSomething(args)
args.isValidResult = drawSomething(args) #drawSomething2(args) does not contain any selection and works
showPreviewManual.value = False
else:
args.executeFailed = True
args.executeFailedMessage = "Some inputs are invalid, unable to generate preview"
# This function will be called when the user changes anything in the command dialog
def command_input_changed(args: adsk.core.InputChangedEventArgs):
changed_input = args.input
inputs = args.inputs
futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}')
dropdown: adsk.core.DropDownCommandInput = inputs.itemById(DROPDOWN_ID)
lineSelectionInput: adsk.core.SelectionCommandInput = inputs.itemById(LINE_SELECTION)
try:
if changed_input.id == DROPDOWN_ID:
ui.messageBox('new player selected')
if changed_input.id == LINE_SELECTION:
pass
except:
ui.messageBox('error')
# This event handler is called when the user interacts with any of the inputs in the dialog
# which allows you to verify that all of the inputs are valid and enables the OK button.
def command_validate_input(args: adsk.core.ValidateInputsEventArgs):
# General logging for debug.
futil.log(f'{CMD_NAME} Validate Input Event')
inputs = args.inputs
# Verify the validity of the input values. This controls if the OK button is enabled or not.
args.areInputsValid = is_all_input_valid(inputs)
# This event handler is called when the command terminates.
def command_destroy(args: adsk.core.CommandEventArgs):
global local_handlers
local_handlers = []
futil.log(f'{CMD_NAME} Command Destroy Event')
def is_all_input_valid(inputs: adsk.core.CommandInputs):
result = True # TODO
return result
def createNewComponent():
# Get the active design.
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
rootComp = design.rootComponent
allOccs = rootComp.occurrences
newOcc = allOccs.addNewComponent(adsk.core.Matrix3D.create())
return newOcc.component
def drawSomething(args: adsk.core.CommandEventArgs):
inputs = args.command.commandInputs
lineSelectionInput: adsk.core.SelectionCommandInput = inputs.itemById(LINE_SELECTION)
try:
global newComp
newComp = createNewComponent()
if newComp is None:
ui.messageBox('New component failed to create', 'New Component Failed')
return
else:
ui.messageBox('Component created')
# Get the line or edge
selObj = lineSelectionInput.selection(0)
entity = selObj.entity
ui.messageBox('Line was selected from the selection')
lineLength = entity.length
ui.messageBox('The line length is :'+str(entity.length))
# create the normal plane
planes = newComp.constructionPlanes
planeInput = planes.createInput()
planeInput.setByDistanceOnPath(entity, adsk.core.ValueInput.createByReal(0.5))
plane = planes.add(planeInput)
ui.messageBox('Construction plane created')
# create the sketch
sketches = newComp.sketches
sketch = sketches.add(plane)
ui.messageBox('Sketch created')
# Draw the sketch #TODO replace by a defined profile sketch linked to profile name
pipeRadius = lineLength/20
center = plane.geometry.origin
center = sketch.modelToSketchSpace(center)
sketch.sketchCurves.sketchCircles.addByCenterRadius(center, pipeRadius)
profile = sketch.profiles[0]
ui.messageBox('sketch drawn')
# Extrude
feats = newComp.features
extrudeFeats = feats.extrudeFeatures
ui.messageBox('feature created')
extrudeInput = extrudeFeats.createInput(profile, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
extent_distance_1 = adsk.fusion.DistanceExtentDefinition.create(adsk.core.ValueInput.createByReal(lineLength/2))
extent_distance_2 = adsk.fusion.DistanceExtentDefinition.create(adsk.core.ValueInput.createByReal(lineLength/2))
deg5 = adsk.core.ValueInput.createByString("5 deg")
deg10 = adsk.core.ValueInput.createByString("10 deg")
extrudeInput.setTwoSidesExtent(extent_distance_1, extent_distance_2, deg5, deg10)
extrude7 = extrudeFeats.add(extrudeInput)
ui.messageBox('body extruded')
except:
if ui:
ui.messageBox('Failed to compute the extrusion: drawSomething()')
def drawSomething2(args: adsk.core.CommandEventArgs):
inputs = args.command.commandInputs
lineSelectionInput: adsk.core.SelectionCommandInput = inputs.itemById(LINE_SELECTION)
try:
# global newComp
newComp = createNewComponent()
if newComp is None:
ui.messageBox('New component failed to create', 'New Component Failed')
return
# create the normal plane
planes = newComp.constructionPlanes
planeInput = planes.createInput()
planeInput.setByOffset(newComp.xYConstructionPlane,adsk.core.ValueInput.createByReal(10))
plane = planes.add(planeInput)
# create the sketch
sketches = newComp.sketches
sketch = sketches.add(plane)
# Draw the sketch #TODO replace by a defined profile sketch linked to profile name
pipeRadius = 2 #lineLength/20
center = plane.geometry.origin
center = sketch.modelToSketchSpace(center)
sketch.sketchCurves.sketchCircles.addByCenterRadius(center, pipeRadius)
profile = sketch.profiles[0]
# Extrude
feats = newComp.features
extrudeFeats = feats.extrudeFeatures
extrudeInput = extrudeFeats.createInput(profile, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
extent_distance_1 = adsk.fusion.DistanceExtentDefinition.create(adsk.core.ValueInput.createByReal(5))
extent_distance_2 = adsk.fusion.DistanceExtentDefinition.create(adsk.core.ValueInput.createByReal(5))
deg5 = adsk.core.ValueInput.createByString("5 deg")
deg10 = adsk.core.ValueInput.createByString("10 deg")
extrudeInput.setTwoSidesExtent(extent_distance_1, extent_distance_2, deg5, deg10)
extrude7 = extrudeFeats.add(extrudeInput)
except:
if ui:
ui.messageBox('Failed to compute the Extrusion. drawSomething2()')
Solved! Go to Solution.