Marshal,
I fixed the issue you mentioned, it still does not fix my issue. I have not tried the rectangular method yet, which confuses me still, even after looking at the rectangular pattern API sample.
Here is the fixed code and you will notice it still produces the same tool body creation error:
import adsk.core, adsk.fusion, adsk.cam, traceback
# Global list to keep all event handlers in scope.
# This is only needed with Python.
handlers = []
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
# Get the CommandDefinitions collection.
cmdDefs = ui.commandDefinitions
# Create a button command definition.
buttonSample = cmdDefs.addButtonDefinition('MainButton','Plate Generator', 'An Add-in which generates a solid rectangle and applies holes or slots equidistant from part center.','./Resources/Main Icons')
# Connect to the command created event.
MainButtonEvent = SampleCommandCreatedEventHandler()
buttonSample.commandCreated.add(MainButtonEvent)
handlers.append(MainButtonEvent)
# Get the ADD-INS panel in the model workspace.
addInsPanel = ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel')
# Add the button to the bottom of the panel.
buttonControl = addInsPanel.controls.addCommand(buttonSample)
buttonControl.isPromoted = True
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler for the commandCreated event.
class SampleCommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
app = adsk.core.Application.get()
# Get the command
cmd = eventArgs.command
cmd.okButtonText = ("Generate") #text in "OK" button
# Get the CommandInputs collection to create new command inputs.
inputs = cmd.commandInputs
#Add image input
imageinput1 = inputs.addImageCommandInput('imageinput1','Diagram:','./Resources/Image Input/Diagram/diagram.png')
# Create the value inputs
length_in = inputs.addValueInput('length_in', 'Length','', adsk.core.ValueInput.createByReal(3))
width_in = inputs.addValueInput('width_in','Width','',adsk.core.ValueInput.createByReal(2))
thick_in = inputs.addValueInput('thick_in','Thickness','',adsk.core.ValueInput.createByReal(1))
fillet_cb = inputs.addBoolValueInput('fillet_cb','Add Corner Fillets', False,'./Resources/Image Input/Fillets', False)
fillet_in = inputs.addValueInput('fillet_in','Fillet Radius','',adsk.core.ValueInput.createByReal(0))
hole_cb = inputs.addBoolValueInput('hole_cb','Add Hole Pattern', True,'', True)
hole_dia = inputs.addValueInput('hole_dia','Hole Diameter','',adsk.core.ValueInput.createByReal(0))
hole_spcX = inputs.addValueInput('hole_spcX','Hole Spacing in X','',adsk.core.ValueInput.createByReal(0))
hole_spcY = inputs.addValueInput('hole_spcY','Hole Spacing in Y','',adsk.core.ValueInput.createByReal(0))
inputChanged = inputChangedEvent()
cmd.inputChanged.add(inputChanged)
handlers.append(inputChanged)
onExecute = SampleCommandExecuteHandler()
cmd.execute.add(onExecute)
handlers.append(onExecute)
# onExecutePreview = MyExecutePreviewHandler()
# cmd.executePreview.add(onExecutePreview)
# handlers.append(onExecutePreview)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler for the execute event.
class SampleCommandExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
eventArgs = adsk.core.CommandEventArgs.cast(args)
# Code to react to the event.
app = adsk.core.Application.get()
ui = app.userInterface
ui.messageBox('In command execute event handler.')
eventArgs = adsk.core.CommandEventArgs.cast(args)
# Get the values from the command inputs.
inputs = eventArgs.command.commandInputs
length = inputs.itemById('length_in').value
width = inputs.itemById('width_in').value
thickness = inputs.itemById('thick_in').value
fillet = inputs.itemById('fillet_in').value
filletcb = inputs.itemById('fillet_cb').value
hole_dia = inputs.itemById('hole_dia').value
hole_spcX = inputs.itemById('hole_spcX').value
hole_spcY = inputs.itemById('hole_spcY').value
holecb = inputs.itemById('hole_cb').value
#call drawBox function and add input values
drawBox(length, width, thickness, fillet, filletcb)
holePat(hole_dia, hole_spcX, hole_spcY, holecb, length, width, thickness)
#call addFillets function and add input value
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):
try:
eventArgs = adsk.core.CommandEventArgs.cast(args)
# Get the values from the command inputs.
inputs = eventArgs.command.commandInputs
length = inputs.itemById('length_in').value
width = inputs.itemById('width_in').value
thickness = inputs.itemById('thick_in').value
fillet = inputs.itemById('fillet_in').value
filletcb = inputs.itemById('fillet_cb').value
hole_dia = inputs.itemById('hole_dia').value
hole_spcX = inputs.itemById('hole_spcX').value
hole_spcY = inputs.itemById('hole_spcY').value
holecb = inputs.itemById('hole_cb').value
#call drawBox function and add input values
drawBox(length, width, thickness, fillet, filletcb)
holePat(hole_dia, hole_spcX, hole_spcY, holecb, length, width, thickness)
#call addFillets function and add input value
eventArgs.isValidResult
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def drawBox(length_in, width_in, thick_in, fillet_in, fillet_cb): #these values are item IDs - not variables (see above)
try:
# Get the active sketch.
app = adsk.core.Application.get()
sketch = adsk.fusion.Sketch.cast(app.activeEditObject)
ui = app.userInterface
doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
act = app.activeProduct
# Get the root component of the active design.
rootComp = act.rootComponent
# Create a new sketch on the xy plane.
sketches = rootComp.sketches
xyPlane = rootComp.xYConstructionPlane
sketch1 = sketches.add(xyPlane)
# Load the lines collection and draw geometry for BOX sketch (division for center around origin)
Load_lines = sketch1.sketchCurves.sketchLines #load the line API
L1 = Load_lines.addByTwoPoints(adsk.core.Point3D.create((length_in/-2), (width_in/-2), 0), adsk.core.Point3D.create((length_in/2),(width_in/-2), 0))
L2 = Load_lines.addByTwoPoints(adsk.core.Point3D.create((length_in/2),(width_in/-2),0), adsk.core.Point3D.create((length_in/2),(width_in/2),0))
L3 = Load_lines.addByTwoPoints(adsk.core.Point3D.create((length_in/2),(width_in/2),0), adsk.core.Point3D.create((length_in/-2),(width_in/2),0)) #draw lines (start, end)
L4 = Load_lines.addByTwoPoints(adsk.core.Point3D.create((length_in/-2),(width_in/2),0), adsk.core.Point3D.create((length_in/-2),(width_in/-2),0))
#get sketch profile
prof1 = sketch1.profiles.item(0)
#Extrude thickness
extrude1 = rootComp.features.extrudeFeatures
extrude1_prof = extrude1.createInput(prof1,adsk.fusion.FeatureOperations.NewComponentFeatureOperation)
distance = adsk.core.ValueInput.createByReal(thick_in)
extrude1_prof.setDistanceExtent(False, distance)
finish_extrude1 = extrude1.add(extrude1_prof) #executes the extrusion
if fillet_cb == True and fillet_in > 0:
#fillets----------------------
#find each Brep Edge
extrude1_face0 = finish_extrude1.sideFaces.item(0) #endFace, sideFaces, startFaces etc
get_loops0 = extrude1_face0.loops
loop_0 = get_loops0.item(0) # 0 = closed loop, 1 = open
load_edges = loop_0.edges
brep_edge_0 = load_edges.item(3) #which edge on the face and loop
#
extrude1_face1 = finish_extrude1.sideFaces.item(1)
get_loops1 = extrude1_face1.loops
loop_1 = get_loops1.item(0)
load_edges = loop_1.edges
brep_edge_1 = load_edges.item(3)
extrude1_face2 = finish_extrude1.sideFaces.item(2)
get_loops2 = extrude1_face2.loops
loop_2 = get_loops2.item(0) #
load_edges = loop_2.edges
brep_edge_2 = load_edges.item(3)
extrude1_face3 = finish_extrude1.sideFaces.item(3)
get_loops3 = extrude1_face3.loops
loop_3 = get_loops3.item(0)
load_edges = loop_3.edges
brep_edge_3 = load_edges.item(3)
load_fillets = rootComp.features.filletFeatures
# Create an edge collection, then add each found brep_edge
edgeCollection0 = adsk.core.ObjectCollection.create()
edgeCollection0.add(brep_edge_0)
edgeCollection1 = adsk.core.ObjectCollection.create()
edgeCollection1.add(brep_edge_1)
edgeCollection2 = adsk.core.ObjectCollection.create()
edgeCollection2.add(brep_edge_2)
edgeCollection3 = adsk.core.ObjectCollection.create()
edgeCollection3.add(brep_edge_3)
#bring in the valueInput
radius1 = adsk.core.ValueInput.createByReal(fillet_in)
input1 = load_fillets.createInput()
input1.addConstantRadiusEdgeSet(edgeCollection0, radius1, True)
input1.isG2 = False
input2 = load_fillets.createInput()
input2.addConstantRadiusEdgeSet(edgeCollection1, radius1, True)
input2.isG2 = False
input3 = load_fillets.createInput()
input3.addConstantRadiusEdgeSet(edgeCollection2, radius1, True)
input3.isG2 = False
input4 = load_fillets.createInput()
input4.addConstantRadiusEdgeSet(edgeCollection3, radius1, True)
input4.isG2 = False
#execute the fillets
fillet1 = load_fillets.add(input1)
fillet2 = load_fillets.add(input2)
fillet3 = load_fillets.add(input3)
fillet4 = load_fillets.add(input4)
length_in.inputs
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def holePat(hole_dia, hole_spcX, hole_spcY, hole_cb, length_in, width_in, thick_in): #these values are item IDs - not variables (see above)
try:
app = adsk.core.Application.get()
act = app.activeProduct
rootComp = act.rootComponent
ui = app.userInterface
#total_length = inputs.itemById('length_in').value
# Create a new sketch on the xy plane.
sketches = rootComp.sketches
xyPlane = rootComp.xYConstructionPlane
sketch2 = sketches.add(xyPlane)
sketch3 = sketches.add(xyPlane)
spcX_plus_holerad = (hole_spcX + (hole_dia))
spcY_plus_holerad = (hole_spcY + (hole_dia))
if hole_cb == True and hole_dia > 0:
if spcX_plus_holerad >= length_in:
ui.messageBox('Oops! User Specified Hole Spacing Greater Than or Equal To Part Length')
else:
sketch2 = sketches.add(xyPlane)
Load_circles = sketch2.sketchCurves.sketchCircles
circle1 = Load_circles.addByCenterRadius(adsk.core.Point3D.create((hole_spcX/2), 0, (thick_in)), (hole_dia/2))
circle2 = Load_circles.addByCenterRadius(adsk.core.Point3D.create((hole_spcX/-2),0, (thick_in)), (hole_dia/2))
cuts = rootComp.features.extrudeFeatures
extInput1 = cuts.createInput(sketch2.profiles.item(0), adsk.fusion.FeatureOperations.CutFeatureOperation)
extInput2 = cuts.createInput(sketch2.profiles.item(1), adsk.fusion.FeatureOperations.CutFeatureOperation)
extent_all_ne = adsk.fusion.ThroughAllExtentDefinition.create()
extInput1.setOneSideExtent(extent_all_ne, adsk.fusion.ExtentDirections.NegativeExtentDirection)
extInput2.setOneSideExtent(extent_all_ne, adsk.fusion.ExtentDirections.NegativeExtentDirection)
ext1 = cuts.add(extInput1)
ext2 = cuts.add(extInput2)
if spcY_plus_holerad >= width_in and hole_dia > 0:
ui.messageBox('Oops! User Specified Hole Spacing Outside Part Extents')
else:
sketch3 = sketches.add(xyPlane)
Load_circles = sketch3.sketchCurves.sketchCircles
circle3 = Load_circles.addByCenterRadius(adsk.core.Point3D.create(0, (hole_spcY/2), (thick_in)), (hole_dia/2))
circle4 = Load_circles.addByCenterRadius(adsk.core.Point3D.create(0,(hole_spcY/-2), (thick_in)), (hole_dia/2))
cuts = rootComp.features.extrudeFeatures
extInput3 = cuts.createInput(sketch2.profiles.item(0), adsk.fusion.FeatureOperations.CutFeatureOperation)
extInput4 = cuts.createInput(sketch2.profiles.item(1), adsk.fusion.FeatureOperations.CutFeatureOperation)
extent_all_ne = adsk.fusion.ThroughAllExtentDefinition.create()
extInput3.setOneSideExtent(extent_all_ne, adsk.fusion.ExtentDirections.NegativeExtentDirection)
extInput4.setOneSideExtent(extent_all_ne, adsk.fusion.ExtentDirections.NegativeExtentDirection)
ext3 = cuts.add(extInput3)
ext4 = cuts.add(extInput4)
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
class inputChangedEvent(adsk.core.InputChangedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
eventArgs = adsk.core.InputChangedEventArgs.cast(args)
changedInput = eventArgs.input
fillet_in = None
if changedInput.id == 'fillet_cb':
inputs = eventArgs.firingEvent.sender.commandInputs
fillet_in = inputs.itemById('fillet_in')
# Change the visibility of the scale value input.
if fillet_in:
if changedInput.value == True:
fillet_in.isVisible = True
else:
fillet_in.isVisible = False
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def stop(context):
try:
app = adsk.core.Application.get()
ui = app.userInterface
#Delete Button Def
buttonSample = ui.commandDefinitions.itemById('MainButton')
if buttonSample:
buttonSample.deleteMe()
#Delete Button Control
addinsPanel = ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel')
cntrl = addinsPanel.controls.itemById('MainButton')
if cntrl:
cntrl.deleteMe()
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))