Autodesk Creative Platform Core Version 1.0.3
A broad and deep collection of 2D and 3D capabilities.

Shape Generator Overview

Shape Generators are JavaScript programs that generate 3D geometry based on a set of visual inputs provided to the user. A shape can be generated from 2D curves that are extruded, or by directly building a mesh. The end result is a water-tight shape that can interact with other shapes in boolean operations. Developers are free to use functionality provided by the Autodesk Core Library, or libraries developed by other members of the community.

Curating Consistency

To ensure a consistent user experience, the default size of shapes produced by Shape Generators should be 20 × 20 × 20 millimeters, placed above the ground. Because each shape is different and it's not always possible to be 20 × 20 × 20 millimeters, at least one or two dimensions of the shape should be 20 millimeters.

For example, the shape's bounding box should not exceed (-10,-10,0) to (10,10,20).

Structural Prerequisites

There are 2 things developers need to provide in a Shape Generator:

  • Parameter Declaration | Optional

    A declaration of parameters that users can modify to affect the shape geometry.

  • Parameter Processing | Required

    A function that generates the shape geometry from a user-supplied set of parameter values.

Parameter Attributes

A Shape Generator declares the set of user-required parameters by defining an array of Parameter Definitions similar this:
params = [ 
	<parameter definition 1>, 
	<parameter definition 2>,
	...
	<parameter definition N>
];
Each Parameter Definition has the following required attributes regardless of Parameter Type:
  • id | Required

    A unique identifier for the parameter that is used to access its value when Processing Parameters.

  • type | Required

    The type of data this parameter represents. See Parameter Types for the set of supported types.

  • displayName | Required

    A user-visible name for the parameter.

  • default | Required

    The default value of this parameter which must be specified so that the default shape can exist.

Parameter Types

The currently supported parameter types are:
  • angle

    Indicates an angle. A degree symbol will be displayed next to the input. The value returned to the processing function will be in radians, but the default, rangeMin and rangeMax are expressed in degrees.

    Additional Parameter Attributes
    rangeMin
    Optional
    The minimum value for the parameter slider expressed in degrees (inclusive). Users can still enter smaller values however, so the processing code needs to safeguard against that scenario. | Default: 0
    rangeMax
    Optional
    The maximum value for the parameter slider expressed in degrees (inclusive). Users can still enter larger values however, so the processing code needs to safeguard against that scenario. | Default: 1
    params = [
      { 
        "id": "sweep", 
        "displayName": "Sweep Angle", 
        "type": "angle", 
        "rangeMin": 0, 
        "rangeMax": 360, 
        "default": 270 
      }
    ];
  • bool

    Indicates a boolean value (true or false).

    params = [
      { 
        "id": "pointed", 
        "displayName": "Pointed", 
        "type": "bool", 
        "default": true 
      }
    ];
  • float

    Indicates a unitless real value. Developers should use length or angle instead when applicable.

    Additional Parameter Attributes
    rangeMin
    Optional
    The minimum value for the parameter slider (inclusive). Users can still enter smaller values however, so the processing code needs to safeguard against that scenario. | Default: 0
    rangeMax
    Optional
    The maximum value for the parameter slider (inclusive). Users can still enter larger values however, so the processing code needs to safeguard against that scenario. | Default: 1
    params = [
      { 
        "id": "symmetry", 
        "displayName": "Symmetry", 
        "type": "float", 
        "rangeMin": -0.5, 
        "rangeMax": 1.0, 
        "default": 0.1 
      }
    ];
  • int

    Indicates a unitless integer value. Developers should use length or angle instead when applicable.

    Additional Parameter Attributes
    rangeMin
    Optional
    The minimum value for the parameter slider (inclusive). Users can still enter smaller values however, so the processing code needs to safeguard against that scenario. | Default: 0
    rangeMax
    Optional
    The maximum value for the parameter slider (inclusive). Users can still enter larger values however, so the processing code needs to safeguard against that scenario. | Default: 1
    params = [
      { 
        "id": "sides", 
        "displayName": "# Of Sides", 
        "type": "int", 
        "rangeMin": 3, 
        "rangeMax": 30, 
        "default": 5 
      }
    ];
  • length

    Indicates a length. Based on user preferences, it will be displayed as inches or millimeters. The value returned to processing function will always be in millimeters.

    Additional Parameter Attributes
    rangeMin
    Optional
    The minimum value for the parameter slider expressed in millimeters (inclusive). Users can still enter smaller values however, so the processing code needs to safeguard against that scenario. | Default: 0
    rangeMax
    Optional
    The maximum value for the parameter slider expressed in millimeters (inclusive). Users can still enter larger values however, so the processing code needs to safeguard against that scenario. | Default: 1
    params = [
      { 
        "id": "radius", 
        "displayName": "Radius",
        "type": "length", 
        "rangeMin": 1, 
        "rangeMax": 50, 
        "default": 20
      };
    ];
  • list

    A list of labels presented to the user in a combobox and values that accompany them. Additional attributes supported are as follows:

    Additional Parameter Attributes
    listLabels
    Required
    An array of user-visible strings that appear in a drop down box for a set of listValues that is supplied. Refer to Parameter Types for which types support this characteristic.
    listValues
    Required
    An array of values cooresponding to the listLabel entries. Must contain the same number of elements that are in listLabels. Refer to Parameter Types for which types support this characteristic.
    params = [
      { 
        "id": "technique", 
        "displayName": "Size Specifies", 
        "type": "list", 
        "listLabels": ["Radius", "Length of Apothem", "Length of Side"], 
        "listValues": ["c", "a", "s"], 
        "default": "c"
      }
    ];
  • sketch

    A 2D sketch. Developers are encouraged to add SVG resources to their project and load them asynchronously to populate the defaults. The actual value is the JSON serialization of the Sketch2D object obtained from Sketch2D.toJSON

    function shapeGeneratorDefaults(callback) {
      Library.resourceText('Circle.svg', function(resourceData) {
        var sketch2D = Conversions.toSketch2DFromSVG(resourceData);
        var params = [
          { 
            "id": "sketch", 
            "displayName": "Profile", 
            "type": "sketch", 
            "default": sketch2D.toJSON()
          }
        ];
        callback(params);
      });
    }
    
  • string

    Allows the user to input text.

    Additional Parameter Attributes
    singleLine
    Optional
    A single-line text entry input is provided, rather than the default multi-line text area input. | Default: false
    params = [
      { 
        "id": "equation", 
        "displayName": "Z = f(x,y)",
        "type": "string",
        "default": "Math.cos(Math.sqrt(x * x + y * y))"
      }
    ];

Declaring Parameters

Shape Generators can declare parameters using one of two appraoches: 1) Synchronous or 2) Asynchronous. It's up to the developer to choose the approach based on the functionality that's required. The Asynchronous model is typically only used when the parameters are more complicated and require the use of some asynchronous functionality to prepare. Users are encouraged to use the synchronous model when possible.
  • Synchronous

    // SVG Data For Default Extrusion Profile
    // Wrapped in a function so Conversions.toSketch2DFromSVG(...) is 
    // only executed when needed and not on each shape generation.
    function defaultValue() {
        var svg = '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
                   <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
                   <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
                   <circle cx="0" cy="0" r="10" stroke="black" stroke-width="2" fill="red" />
                   </svg>';
        var svgSketch = Conversions.toSketch2DFromSVG(svg);
        return svgSketch.toJSON();
    }
    params = [
      {
        "id": "sketch",
        "displayName": "Profile",
        "type": "sketch", 
        "default": defaultValue() 
      }
    ];
  • Asynchronous

    function shapeGeneratorDefaults(callback) {
      Library.resourceText('Circle.svg', function(resourceData) {
        var sketch2D = Conversions.toSketch2DFromSVG(resourceData);
        var params = [
          { 
            "id": "sketch", 
            "displayName": "Profile", 
            "type": "sketch", 
            "default": sketch2D.toJSON()
          }
        ];
        callback(params);
      });
    }

Processing Parameters

Shape Generators can choose to process parameters using one of two appraoches: 1) Synchronous or 2) Asynchronous. It's up to the developer to choose the approach based on the functionality that's required.
  • Synchronous

    function process(params) {
    
      var l = params['length'];
      var w = params['width'];
      var h = params['height'];
    
      var result = computeResult(l, w, h);
      return result;
    
    }
  • Asynchronous

    function shapeGeneratorEvaluate(params, callback) {
    
      var l = params['length'];
      var w = params['width'];
      var h = params['height'];
    
      var result = computeResult(l, w, h);
      callback(result)
    
    }

The process() or shapeGeneratorEvaluate() functions are mandatory for shape generators. For a script to be valid, these functions must produce a Solid3D object. Failure to produce a Solid3D will leave the script-generated shape in an error state.

The first argument is a key-value dictionary Object [ String , Object ] where the keys are a parameter id, and the values are the types defined by the parameter definitions. If the asynchronous approach is used, the second argument is a callback Function ( Object ) that must be called with the results.

Putting It All Together

There's no functionality in the examples below that require the use of the asynchronous model, but both approaches are shown below to illustate the key differences in the techniques:
  • Synchronous

    params = [
      { 
        "id": "radius", 
        "displayName": "Radius", 
        "type": "length", 
        "rangeMin": 1, 
        "rangeMax": 50, 
        "default": 20 
      }
    ];
    
    function process(params) {
    
      var r = params['radius'];
      var angle = 2*Math.PI / 3;
      var h = Math.sqrt(2) * r;
    
      var sides = [];
      for (var i = 0; i < 3; i++) {
      	var x = r * Math.cos(i * angle);
      	var y = r * Math.sin(i * angle);
      	sides.push([x, y, 0]);
      }
      var peak = [0, 0, h];
    
      var mesh = new Mesh3D();
      mesh.triangle(sides[0], sides[2], sides[1]);
      mesh.triangle(sides[0], sides[1], peak);
      mesh.triangle(sides[1], sides[2], peak);
      mesh.triangle(sides[2], sides[0], peak);
    
      return Solid.make(mesh);
    }
    
  • Asynchronous

    function shapeGeneratorDefaults(callback) {
      var params = [
        { 
          "id": "radius", 
          "displayName": "Radius", 
          "type": "length", 
          "rangeMin": 1, 
          "rangeMax": 50, 
          "default": 20 
        }
      ];
      callback(params);
    }
    
    function shapeGeneratorEvaluate(params, callback) {
    
      var r = params['radius'];
      var angle = 2*Math.PI / 3;
      var h = Math.sqrt(2) * r;
    
      var sides = [];
      for (var i = 0; i < 3; i++) {
        var x = r * Math.cos(i * angle);
        var y = r * Math.sin(i * angle);
        sides.push([x, y, 0]);
      }
      var peak = [0, 0, h];
    
      var mesh = new Mesh3D();
      mesh.triangle(sides[0], sides[2], sides[1]);
      mesh.triangle(sides[0], sides[1], peak);
      mesh.triangle(sides[1], sides[2], peak);
      mesh.triangle(sides[2], sides[0], peak);
    
      callback(Solid.make(mesh));
    }