feat(shelf): python exporter

This commit is contained in:
kellervater
2025-04-26 12:20:41 +02:00
parent bbb742f271
commit a5bad40082
6 changed files with 2766 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.3mf
*.stl
.vscode

2
scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.env
.vscode

View File

@@ -0,0 +1,12 @@
{
"autodeskProduct": "Fusion",
"type": "script",
"author": "kellervater (Patrick Pötz)",
"description": {
"": "Exports all common dimensions of the shelf."
},
"version": "",
"supportedOS": "windows|mac",
"editEnabled": true,
"iconFilename": "ScriptIcon.svg"
}

View File

@@ -0,0 +1,176 @@
#Fusion360API Python Script
#Description: Exports STEP files. Exports "Support" once per depth,
# and "Shelf" for each width/depth combination.
import adsk.core, adsk.fusion, adsk.cam, traceback, os
def run(context):
ui = None
try:
# --- Basic Fusion 360 setup ---
app = adsk.core.Application.get()
ui = app.userInterface
design = app.activeProduct
if not design:
ui.messageBox('No active Fusion 360 design', 'Export Script Error')
return
# --- Get Document Version ---
doc = app.activeDocument
version_str = "v_unknown" # Default in case of error
try:
if doc.dataFile:
version_number = doc.dataFile.versionNumber
version_str = f"v{version_number}"
else:
version_str = "v_unsaved"
ui.messageBox('The current document has not been saved to the cloud yet.\n'
'Filenames will use "v_unsaved" instead of a version number.',
'Unsaved Document Warning')
except Exception as e:
ui.messageBox(f'Could not retrieve document version:\n{e}\n'
f'Filenames will use "{version_str}".', 'Version Error')
# --- End Get Document Version ---
# --- Configuration
widthParamName = "shelf_width_units"
depthParamName = "shelf_depth_units"
minWidth = 4
maxWidth = 15
minDepth = 7
maxDepth = 15
baseFileName = "homeracker_shelf"
shelfBodyName = "Shelf"
supportBodyName = "Support"
# --- End Configuration ---
# Get the root component
rootComp = design.rootComponent
# Get User Parameters collection
userParams = design.userParameters
if not userParams:
ui.messageBox('Could not access user parameters.', 'Export Script Error')
return
# Find the specific parameters
widthParam = userParams.itemByName(widthParamName)
depthParam = userParams.itemByName(depthParamName)
if not widthParam or not depthParam:
ui.messageBox(f'Could not find parameters: "{widthParamName}" or "{depthParamName}". Check names.', 'Param Error')
return
# --- Find the bodies to control visibility (once before loops) ---
shelfBody = None
supportBody = None
try:
shelfBody = rootComp.bRepBodies.itemByName(shelfBodyName)
supportBody = rootComp.bRepBodies.itemByName(supportBodyName)
if not shelfBody:
ui.messageBox(f'Body "{shelfBodyName}" not found. Aborting...', 'Body Not Found Warning')
return
if not supportBody:
ui.messageBox(f'Body "{supportBodyName}" not found. Aborting...', 'Body Not Found Warning')
return
except Exception as e:
ui.messageBox(f'Error finding bodies:\n{traceback.format_exc()}', 'Error Finding Bodies')
return
# --- Get Export Directory from User ---
folderDialog = ui.createFolderDialog()
folderDialog.title = "Select Folder to Save STEP Files"
dialogResult = folderDialog.showDialog()
if dialogResult == adsk.core.DialogResults.DialogOK:
exportFolder = folderDialog.folder
else:
ui.messageBox('Export cancelled by user.')
return
# --- Get Export Manager ---
exportMgr = design.exportManager
# --- Progress Bar Setup ---
num_depths = (maxDepth - minDepth + 1)
num_widths = (maxWidth - minWidth + 1)
# Total exports = one support per depth + one shelf per width*depth
total_exports = num_depths + (num_depths * num_widths)
progressDialog = ui.createProgressDialog()
progressDialog.isCancelEnabled = False
progressDialog.show(f'Exporting {baseFileName}', 'Initializing...', 0, total_exports)
exported_count = 0
# --- Loop through parameter combinations ---
for d in range(minDepth, maxDepth + 1):
try:
# --- Set Depth Parameter ---
depthParam.value = float(d)
adsk.doEvents() # Allow update
progressDialog.progressValue = exported_count
progressDialog.message = f'Exporting Support: D={d} ({exported_count + 1}/{total_exports})'
adsk.doEvents()
# Set visibility: Support ONLY
supportBody.isLightBulbOn = True
shelfBody.isLightBulbOn = False # Hide shelf if it exists
adsk.doEvents() # Allow visibility change
# Construct filename & path for Support
supportFileName = f"{baseFileName}_Support_D{d}_{version_str}"
supportFullPath = os.path.join(exportFolder, supportFileName + ".step")
# Export Support
supportStepOptions = exportMgr.createSTEPExportOptions(supportFullPath, rootComp)
exportMgr.execute(supportStepOptions)
exported_count += 1
# --- End Support Export ---
except Exception:
progressDialog.hide() # Hide progress on error
ui.messageBox(f'Failed during processing or Support export for Depth={d}:\n{traceback.format_exc()}', 'Outer Loop Error')
return
# --- INNER LOOP: Width (for Shelf Export) ---
for w in range(minWidth, maxWidth + 1):
try:
progressDialog.progressValue = exported_count
progressDialog.message = f'Exporting Shelf: W={w}, D={d} ({exported_count + 1}/{total_exports})'
adsk.doEvents()
# --- Set Width Parameter ---
widthParam.value = float(w)
adsk.doEvents() # Allow update
# --- Set Visibility for Shelf Export: Shelf ONLY ---
shelfBody.isLightBulbOn = True
supportBody.isLightBulbOn = False # Hide support if it exists
adsk.doEvents() # Allow visibility change
# --- Construct Filename & Path for Shelf ---
shelfFileName = f"{baseFileName}_Shelf_W{w}_D{d}_{version_str}"
shelfFullPath = os.path.join(exportFolder, shelfFileName + ".step")
# --- Export Shelf ---
shelfStepOptions = exportMgr.createSTEPExportOptions(shelfFullPath, rootComp)
exportMgr.execute(shelfStepOptions)
exported_count += 1
except Exception as e_inner:
# Log error for this specific shelf, but continue loop
ui.messageBox(f'Failed exporting Shelf W={w}, D={d}:\n{traceback.format_exc()}\nSkipping this combination.', 'Inner Loop Error')
# Optionally add logging here instead of message box spam
continue # Continue to next width value
# --- Clean up ---
progressDialog.hide()
if exported_count > 0:
ui.messageBox(f'Successfully exported {exported_count} STEP files to:\n{exportFolder}', 'Export Complete')
else:
ui.messageBox('No files were exported. Check script configuration or logs for errors.', 'Export Result')
except Exception as e:
if ui:
ui.messageBox('Script Failed Unexpectedly:\n{}'.format(traceback.format_exc()))
if 'progressDialog' in locals() and progressDialog.isShowing:
progressDialog.hide()

View File

@@ -0,0 +1,6 @@
This script is intended to be used with the Fusion360 file `HomeRacker - Shelf`.
It exports all sane dimensions of the shelf to avoid tedious manual work.
It is ready to go and just needs to be run from within Fusion360 (`Shift + S`).
> [!NOTE]
> Since I bootstrapped the script from within Fusion, idk how to import it. Maybe you need to create a new one and just import the contents. Just try it and let me know how it works.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 85 KiB