This script works with Fusion 360, tested 04/16/2024. However, if it's good, I don't know!
import adsk.core, adsk.fusion, adsk.cam, traceback
import math
def createCycloidalDrive(centerPoint, numTeeth, baseCircleRadius, eccentricity):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
design = adsk.fusion.Design.cast(app.activeProduct)
rootComp = design.rootComponent
# Convert input parameters
num_teeth = numTeeth
eccentricity = eccentricity
base_circle_radius = baseCircleRadius
rolling_circle_radius = base_circle_radius / num_teeth
# Calculate cycloidal curve points
points = adsk.core.ObjectCollection.create()
for i in range(361): # 0 to 360 degrees in steps of 1 degree
angle_rad = math.radians(i)
# Parametric equations for cycloidal curve
x = (base_circle_radius + rolling_circle_radius) * math.cos(angle_rad) - eccentricity * math.cos(((base_circle_radius + rolling_circle_radius) / rolling_circle_radius) * angle_rad) + centerPoint.worldGeometry.x
y = (base_circle_radius + rolling_circle_radius) * math.sin(angle_rad) - eccentricity * math.sin(((base_circle_radius + rolling_circle_radius) / rolling_circle_radius) * angle_rad) + centerPoint.worldGeometry.y
point = adsk.core.Point3D.create(x, y, centerPoint.worldGeometry.z) # Use the Z coordinate of the center point
points.add(point)
# Create the cycloidal curve in the active sketch
activeComponent = design.activeComponent
activeSketch = None
for sketch in activeComponent.sketches:
if sketch.isVisible:
activeSketch = sketch
break
if activeSketch:
activeSketch.sketchCurves.sketchFittedSplines.add(points)
else:
ui.messageBox('Active sketch not found. Please ensure you are editing a sketch.', 'No Active Sketch')
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()), 'Error')
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
# Create a command definition
# cmdDef = ui.commandDefinitions.addButtonDefinition('createCycloidalDriveCmd', 'Create Cycloidal Drive', 'Create a cycloidal drive with specified parameters')
# Check if the command definition already exists
solidTab = ui.allToolbarTabs.itemById('SketchTab')
createPanel = solidTab.toolbarPanels.itemById('SketchCreatePanel') # Example panel ID
cmdDef = ui.commandDefinitions.itemById('createCycloidalDriveCmd')
if not cmdDef:
cmdDef = ui.commandDefinitions.addButtonDefinition('createCycloidalDriveCmd', 'Create Cycloidal Drive', 'Create a cycloidal drive with specified parameters')
createPanel.controls.addCommand(cmdDef)
# Add an event handler for the command created event
onCommandCreated = CommandCreatedEventHandler()
cmdDef.commandCreated.add(onCommandCreated)
handlers.append(onCommandCreated) # Keep a reference to prevent garbage collection
cmdDef.execute()
adsk.autoTerminate(False)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class CommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler):
def notify(self, args):
eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
cmd = eventArgs.command
inputs = cmd.commandInputs
# Add inputs for parameters
# inputs.addValueInput('numTeeth', 'Number of Teeth', 'cm', adsk.core.ValueInput.createByReal(10))
inputs.addIntegerSpinnerCommandInput('numTeeth', 'Number of Teeth', 1, 100, 1, 10)
inputs.addValueInput('baseCircleRadius', 'Base Circle Radius', 'cm', adsk.core.ValueInput.createByReal(10.0))
inputs.addValueInput('eccentricity', 'Eccentricity', 'cm', adsk.core.ValueInput.createByReal(5.0))
# Add selection input for the center point
selectionInput = inputs.addSelectionInput('centerPoint', 'Center Point', 'Select the center point')
selectionInput.setSelectionLimits(1, 1) # Limit to a single selection
selectionInput.addSelectionFilter('SketchPoints') # Limit selection to sketch points
# Add an event handler for when the command is executed
onExecute = CommandExecuteHandler()
cmd.execute.add(onExecute)
handlers.append(onExecute) # Keep a reference to prevent garbage collection
class CommandExecuteHandler(adsk.core.CommandEventHandler):
def notify(self, args):
eventArgs = adsk.core.CommandEventArgs.cast(args)
inputs = eventArgs.command.commandInputs
numTeeth = inputs.itemById('numTeeth').value
baseCircleRadius = inputs.itemById('baseCircleRadius').value
eccentricity = inputs.itemById('eccentricity').value
centerPoint = inputs.itemById('centerPoint').selection(0).entity
createCycloidalDrive(centerPoint, numTeeth, baseCircleRadius, eccentricity)
handlers = [] # Global list to keep handlers alive