Automate Scaling and Exporting Step files

jedidavidalan
Participant

Automate Scaling and Exporting Step files

jedidavidalan
Participant
Participant

Hi there,

 

I'm a graphic designer whose experience is mostly with Adobe Photoshop and Illustrator for print, but I've dabbled with CAD before to design jewelry for 3D printing and using sites like Shapeways to sell my design.  Well, after a little over a decade of neglecting my shop, I'm rebuilding all my buggy vrml files from scratch in Fusion360.  The design part has been fun, but the tedious part is the way I build ring sizes.  

 

I'm sure there's a better way with parametric design, but I'm still relatively new, and most of my design process uses Illustrator to build my sketches, and then bring them into Fusion 360 to bring them to 3D.  So I usually design my rings as a US size 10, and then I did the math to scale the whole ring down to size 5 and up to size 12.5 and everything in between.  So what I've been doing is placing my final design of a ring at the origin, duplicating the body 15 times, and then just making one size visible, and scaling the whole ring up or down from the origin.  Once I've got all 16 sizes scaled, I make one ring visible at a time, and export that model as a .step file, and name it with the size.  

 

So I watched the whole video of Automating Fusion 360 with the API by Patrick Rainsberry, but the problem I've encountered is that I don't have any coding experience.  I'm used to automating with Photoshop or Illustrator where you can record your actions and then tell the app to repeat those steps on a batch of files.  Is there anyone that can/would be willing to help me set something up?  I've got over fifty designs currently, and I'm planning on really making a push with this particular side hustle in the future, so it would be really helpful if I could devote more of my time to design and less to tedium and file management.  

0 Likes
Reply
Accepted solutions (2)
1,992 Views
10 Replies
Replies (10)

BrianEkins
Mentor
Mentor
Accepted solution

The Scale feature is parametric so you can set up a model to be scale and then use a small script to change the scale and export as STEP.

 

Below is the contents of a script that does this.  It expects a design to be open that contains a body in the root component named "Ring".  It also expects there is a parameter in the design called "Scale".  I've attached the f3d that I used to test it.  When you run the script, it prompts for a folder, where it will write the new STEP files.  The valid sizes and the scale factor associated with each one is hard-coded in the script and will be easy to change to the real values.  The script iterates through these pre-defined sizes, sets the parameters controlling the scale, and exports the body as a STEP file.  It used the name defined in the list for the file and exports it to the specified folder.

 

import adsk.core, adsk.fusion, traceback
import os

def run(context):
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui: adsk.core.UserInterface  = app.userInterface
        des: adsk.fusion.Design = app.activeProduct

        # Get the parameter named "Scale".
        scaleParam = des.allParameters.itemByName('Scale')

        # Get the body named "Ring". This looks for it in the root component,
        # this code will need to be modified if it's in a sub component.
        root = des.rootComponent
        body = root.bRepBodies.itemByName("Ring")

        # List of name sizes and the associated scale factors.
        sizeList = []
        sizeList.append(('8', 0.8))
        sizeList.append(('9', 0.9))
        sizeList.append(('10', 1.0))
        sizeList.append(('11', 1.1))
        sizeList.append(('12', 1.2))

        # Get the folder to export to from the user.
        folderDialog = ui.createFolderDialog()
        folderDialog.title = 'Specify Export Folder'
        results = folderDialog.showDialog()
        if results != adsk.core.DialogResults.DialogOK:
            return

        folder = folderDialog.folder

        # Iterate through the sizes, scaling the model and exporting for each size.
        for size in sizeList:
            name = size[0]
            scale = size[1]

            # Modify the parameter to get the correct scale.
            scaleParam.value = scale

            # Give control back to Fusion so the view can refresh.
            adsk.doEvents()

            # Export the file as STEP.
            exportMgr = des.exportManager
            filename = os.path.join(folder, name + '.step')
            stepOptions = exportMgr.createSTEPExportOptions(filename, root)
            if exportMgr.execute(stepOptions):
                WriteToTextWindow('Successfully exported ' + filename)
            else:
                WriteToTextWindow('Failed to export ' + filename)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def WriteToTextWindow(text):
    app = adsk.core.Application.get()
    ui = app.userInterface

    # Get the palette that represents the TEXT COMMANDS window. 
    textPalette = ui.palettes.itemById('TextCommands')

    # Make sure the palette is visible. 
    if not textPalette.isVisible: 
        textPalette.isVisible = True

    # Write the text. 
    textPalette.writeText(text) 
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
1 Like

jedidavidalan
Participant
Participant

That is awesome!  I think this is exactly what I was looking for.  Thank you so much, and thanks for your amazing speed!

0 Likes

jedidavidalan
Participant
Participant

So, I went through and added the correct list of sizes and the scale per each size in the code, but I kept getting the error: 

Screen Shot 2021-06-12 at 5.37.05 PM.png

Here's how I modified the code:

#Author-Brian Ekins
#Description-Script will take a size 10 ring and iterate Size 5-12.5 with half-sizes in-between.

import adsk.core, adsk.fusion, traceback
import os

def run(context):
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui: adsk.core.UserInterface  = app.userInterface
        des: adsk.fusion.Design = app.activeProduct

        # Get the parameter named "Scale".
        scaleParam = des.allParameters.itemByName('Scale')

        # Get the body named "Ring". This looks for it in the root component,
        # this code will need to be modified if it's in a sub component.
        root = des.rootComponent
        body = root.bRepBodies.itemByName("Ring")

        # List of name sizes and the associated scale factors.
        sizeList = []
        sizeList.append(('05.0', 0.79293))
        sizeList.append(('05.5', 0.81313))
        sizeList.append(('06.0', 0.83333))
        sizeList.append(('06.5', 0.85354))
        sizeList.append(('07.0', 0.87374))
        sizeList.append(('07.5', 0.89394))
        sizeList.append(('08.0', 0.91414))
        sizeList.append(('08.5', 0.93434))
        sizeList.append(('09.0', 0.95960))
        sizeList.append(('09.5', 0.97980))
        sizeList.append(('10.0', 1.00000))
        sizeList.append(('10.5', 1.02020))
        sizeList.append(('11.0', 1.04040))
        sizeList.append(('11.5', 1.06061))
        sizeList.append(('12.0', 1.08081))
        sizeList.append(('12.5', 1.10101))

        # Get the folder to export to from the user.
        folderDialog = ui.createFolderDialog()
        folderDialog.title = 'Specify Export Folder'
        results = folderDialog.showDialog()
        if results != adsk.core.DialogResults.DialogOK:
            return

        folder = folderDialog.folder

        # Iterate through the sizes, scaling the model and exporting for each size.
        for size in sizeList:
            name = size[0]
            scale = size[1]

            # Modify the parameter to get the correct scale.
            scaleParam.value = scale

            # Give control back to Fusion so the view can refresh.
            adsk.doEvents()

            # Export the file as STEP.
            exportMgr = des.exportManager
            filename = os.path.join(folder, name + '.step')
            stepOptions = exportMgr.createSTEPExportOptions(filename, root)
            if exportMgr.execute(stepOptions):
                WriteToTextWindow('Successfully exported ' + filename)
            else:
                WriteToTextWindow('Failed to export ' + filename)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def WriteToTextWindow(text):
    app = adsk.core.Application.get()
    ui = app.userInterface

    # Get the palette that represents the TEXT COMMANDS window. 
    textPalette = ui.palettes.itemById('TextCommands')

    # Make sure the palette is visible. 
    if not textPalette.isVisible: 
        textPalette.isVisible = True

    # Write the text. 
    textPalette.writeText(text) 

 

And here's the parameter I set up.  I set the unit as %, but for some reason it remains shows as blank in the list:Screen Shot 2021-06-12 at 5.55.18 PM.png

I'm not sure if this is an issue because I didn't initially build the rings using parameters, or if there's something more fundamental that I did wrong.  Can you tell if this is a simple fix or if this isn't going to work?

 

On the off chance this just isn't going to work, I'm wondering if I'm approaching this the wrong way.  Perhaps, instead of a script to build out the different sizes of each ring, maybe I can make one blank ring, and make fifteen copies of that blank ring that all reference the original, and resize them all to make sure they're the correct scale.  Then, if I make a change to that original model, by putting a symbol into the face of it, all the other rings match it, and it's just a matter of getting a script to export all 16 rings to step files.  

 

I know that when you start with a sketch and make a model, a change to the original sketch can trickle down to the model, but I can't remember how to ensure those changes come out in the end, and I can't remember if it's possible or how to do that with a finished model/body.  Of course, it's possible I'm overthinking all of this.  I tend to do that, come up with multiple solutions, and waste time trying to make them work instead of just working on my designs.

0 Likes

jedidavidalan
Participant
Participant
It took me about a day's worth of research and banging my head against the table, but I finally figured out what I was doing wrong and got it working. It works like a charm. This is going to save me hours! Thank you again so much for your amazing solution and quickness.
0 Likes

jedidavidalan
Participant
Participant

Hi there,

 

I recently got a new computer, and my scripts didn't make the automatic migration with everything else.  I thought i had it set up the same way it was before, but I've encountered a new error I've never seen before.  

Screen Shot 2022-01-27 at 6.05.51 PM.png

The filename was supposed to be based on the name of the model, and it always worked before, so i'm not quite sure what I'm missing.  I used the same "Modified Code" that I posted earlier.  Any help would be greatly appreciated.  

0 Likes

kandennti
Mentor
Mentor
Accepted solution
0 Likes

jedidavidalan
Participant
Participant

You were 100% right!  I kept looking at line 61 and couldn't figure out what to do, it hadn't occurred to me that i missed a line at the beginning when I copy/Pasted.  Thank you so much for your help.  

1 Like

joecamisa
Contributor
Contributor

Hi all, I am trying to do something very similar to automate scaling a single body with two small differences:

 

(1) I am exporting STL files instead of STEP.   Where would I find the command for exporting an STL file and how can I control the size of the STL file?

 

(2) For the exported file name I'd like to append the Size to the Name of the model being exported.

For example for a model with the name "RingTest":  the following STL files would be created:  RingTest S5.stl, RingTest S6.stl, RingTest S7.stl, ..., RingTest S12.stl.

 

Any suggestions on how to script this and which Fusion 360 documents and tutorials I should read would be greatly appreciated.

 

Thanks!

 

0 Likes

joecamisa
Contributor
Contributor

Thanks for the link.  This was what I am looking for.

I'm getting an error in my script but am debugging to figure it out why.

0 Likes

Type a product name