I have done a nice little skript to generate Ropes, Coils and Cords along a users curve:
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()))
Solved! Go to Solution.
Solved by kandennti. Go to Solution.
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.
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()))
Can't find what you're looking for? Ask the community or share your knowledge.