Introduction: Parametric Modeling With Fusion 360 API

About: artist and technologist http://www.sterlingcrispin.com

Who This Guide Is For:

This guide assumes you have some programming experience, if you don't yet and want to write code for the Fusion 360 API (Application Programming Interface) I suggest taking an introduction to Python class through Google, Microsoft & EdX or check this Python for Non-Programmers list of resources.


Who Wrote This And Why:

I'm an artist who writes code to create new tools for self expression. You can see my work here sterlingcrispin.com or here instagram.com/sterlingcrispin.

What You'll Need:

Get yourself a free copy of Fusion360, also all of the code I reference is available free here github.com/sterlingcrispin/Fusion360API

Why Fusion360:

I've used a lot of other 3D modeling programs and I think Fusion 360 has exciting potential. For software focused on CAM (computer aided manufacturing) I think its the easiest and most powerful tool available. I'm writing this because I want to learn the Fusion 360 API and share my process to help other artists and designers do creative things with it.

Fusion 360 and its API as a topic is huge, and I learn best through directly making things. So this Instructable is as much a diary of my process as it is a guide for other people, hopefully you find it useful.

Intro:

Python VS C++:

Currently Fusion 360 API supports C++ and Python (Autodesk just stopped supporting JavaScript which personally I would have much rather use). I have more experience with C++ than Python but the code examples provided by Autodesk make it clear that Python is the least painful of the two choices.

A Word of Advice:

If you're like me and you're used to how things work in 3D graphics programming the Fusion360 API can be pretty counter intuitive. I suggest getting at least somewhat familiar with Fusion360 as a tool itself before getting into the API. For example, you might expect to be able to do something like this:

	cube = autodesk.createCube(10,10,10)
	cube.position += autodesk.Vector3D(0,10,0)

However the Fusion360 API behaves a lot like Fusion360 itself does:

First you need to create a collection of entities as if you were selecting them

        bodies = adsk.core.ObjectCollection.create()
        bodies.add(extrudeFeature.bodies.item(0))

then you need to create a 3D vector, a 3D matrix, and tell the matrix to use the vector as a translation

        vector = adsk.core.Vector3D.create(0.0, 10.0, 0.0)
        transform = adsk.core.Matrix3D.create()
        transform.translation = vector

then create a moveFeature, and use the ObjectCollection and Matrix3D as arguments for a MoveFeatureInput which is itself an object that gets added to the moveFeature finally moving the object.

        moveFeats = features.moveFeatures
        moveFeatureInput = moveFeats.createInput(bodies, transform)
        moveFeats.add(moveFeatureInput)

This might seem cumbersome at first but once you get used to the pattern it becomes more intuitive.

Recommended reading:

All code shown in this Instructable has been made available here https://github.com/sterlingcrispin/Fusion360API

First read Welcome to the Fusion 360 API (Application Programming Interface) and I strongly recommend looking over the first 3-5 pages of the Fusion 360 API User's Manual.

The API Reference Manual's list of objects is a must

These Sample Programs are a good starting point

The Fusion 360 API Object Model can be helpful if a hierarchy relationship in the Reference Manual is confusing

Additional resources

Autodesk videos about Fusion 360 API

Autodesk Fusion 360 API GitHub Site

Python 3.5 documentation // Python Math Functions

Step 1: Spiraling Splines

Scripts used in this step are SpiralSpline and SpiralSweepSolids can be found here https://github.com/sterlingcrispin/Fusion360API/

SpiralSpline.py

This first sketch was adapted from Sketch spline through points creation API Sample the idea was to start from a simple element like a spline and begin to build some complexity.

line 6:

Importing the math library to get trigonometry functions

import math

As a first deviation away from the provided API sample I nested the points.add function in a for loop that creates points along a circle on the XY plane using the trigonometric functions and simply steps forward in the Z direction making a spiral spline.

for i in range(10):
  # from 0 to TWOPI radians as i increases 
  p = (i/9) * math.pi * 2
  points.add(adsk.core.Point3D.create( math.cos(p), math.sin(p) , i ))
                
  # Create a spline along those points
  spline = sketch.sketchCurves.sketchFittedSplines.add(points)

Next wrap that loop in another to create a series of spiral splines that vary with intensity,

  for j in range(10):
    for i in range(10):
      # from 0 to TWOPI radians as i increases 
      p = (i/9) * math.pi * 2
      # scaled in intensity by each spline
      p = p * (j/9) 
      # so the splines aren't on top of one another
      xstep = j * 2
      points.add(adsk.core.Point3D.create( math.cos(p) + xstep , math.sin(p) , i ))
                
      # Create a spline along those points
      spline = sketch.sketchCurves.sketchFittedSplines.add(points)
            
      #delete any old points so the splines don't become connected
      points = adsk.core.ObjectCollection.create()

Step 2: Sweeping the Splines Into Solids

SpiralSweepSolids.py

Building on this collection of spiraling splines this sketch creates a circle at the beginning of every spline and sweeps the circle down the spline to create a new solid

    # Create a circle at the beginning of the spline
    circles = sketch.sketchCurves.sketchCircles
    circle1 = circles.addByCenterRadius(points[0], j/(tubeCount-2) + 0.1)
            
    # Create a sweep input
    prof = sketch.profiles.item(j)
    path = rootComp.features.createPath(spline)
    sweeps = rootComp.features.sweepFeatures
    sweepInput = sweeps.createInput(prof,path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

Step 3: Refactor and Play Around

SpiralSweepSolidsAlt.py

At this point I stopped to clean up a few variables like xstep, length and radius so they could each be adjusted and explore the parameter space of the code as it currently is. There's also a new variable called taper that's causing the spirals to lean downward as the tube count increases. Rather than continuing to place code in-line in this instructable I'm switching to a screenshot from diffchecker.com that will just show what has changed. As before all of this code is available on my github.

Some of these images also used operations done manually after the code ran, like Create>Mirror for the symmetrical form.

Step 4: Chamfers and Sketch Planes

SpiralSweepXY.py

As before the code for this is available at https://github.com/sterlingcrispin/Fusion360API.

Problem:

I wanted to run a second set of splines across the first set creating a kind of woven grid, which was easy enough by creating a second sketch on the zX plane, but the intersections of these shapes looked crude. Chamfering the edges seemed like a good solution but the Sweep feature was causing the shapes to distort heavily and making the chamfering fail.

Solution:

I borrowed code from the Pipe.py example included in Fusion360's API, and created sketch planes that were normal (facing in the direction of) the splines. I really like the output of this function it looks a lot more like the Create>Pipe function in Fusion360.

SweepNormalToSpline is the first function, which given a spline, radius, and the root component of the document the function creates a new construction plane facing in the direction of the spline, draws a circle of the radius you specify, sweeps the circle down the spline, and returns a sweep object for you to use. Again this code was borrowed heavily from Pipe.py but I found it really helpful to create it into a function.

ChamferSweep is the second function and is pretty straightforward, it loops through every face of the sweep, then every edge, creating a group of edges which it then chamfers. It helps to have the Fusion360 API reference open when writing this kind of thing to find out exactly what a chamfer command needs as an argument (an object collection of edges), and how to get those edges from a sweep (the nested loop)

Another helpful tip I found was to set the design to "Direct Design Type" which stops recording every action in the timeline, this speeds up the script compute time a lot and I haven't found the loss of that information a problem yet.


Step 5: Refactor and Play Around

At this point I felt like the code was really starting to get somewhere interesting so I changed the variables controlling the underlying form like length, tube count, spline segments and radius to see what kinds of forms would come out of the parameter space so far. If you're reading this and following along I suggest doing the same to see what you can find and what stands out as interesting to you.

I started noticing this arcing cupping shape and it made me think of a bowl or a vase.

Step 6: Find a Form

SpiralSweepBowl.py

After experimenting with the code I had I thought a bowl could be formed and edited the original spline code to form a cavity, but I think its clear this script is a great starting point to explore other possible forms.

Step 7: 3D Print or Render It!

I made these renderings locally using Fusion360 and the Nylon-6-6 material setting. If you wanted to 3D print this form I would scale it up from 93mm to 150mm or whatever size you prefer. You can use the Modify>Combine tool in the modeling mode to combine all of the tubes into one solid body for 3D printing and then export it as an STL