Autodesk Creative Platform Core Version 1.19.0
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 Declaration

Shape Generators can declare parameters using one of two appraoches:
  1. Synchronous
  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. There are several different types of parameters that are supported, each has a number of configurable characteristics. To learn more about the configurable options, please refer to the documentation for each of the parameter types:
  1. Angle

    Refer to AngleParameterJSON for additional fields.

  2. Boolean

    Refer to BooleanParameterJSON for additional fields.

  3. Real Value

    Refer to FloatParameterJSON for additional fields.

  4. Integer Value

    Refer to IntegerParameterJSON for additional fields.

  5. Length

    Refer to LengthParameterJSON for additional fields.

  6. List

    Refer to ListParameterJSON for additional fields.

  7. 2D Sketch

    Refer to SketchParameterJSON for additional fields.

  8. String

    Refer to StringParameterJSON for additional fields.

  9. File

    Refer to FileParameterJSON for additional fields.

Below are examples of how the parameters for a Shape Generator would be defined using the different techniques available:
  • 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);
      });
    }

Parameter Processing

Shape Generators can choose to process parameters using one of two appraoches:
  1. Synchronous
  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));
    }
    

The Object-Oriented Approach

Aside from declaring some parameters and generating geometry, there are lots of other things a Shape Generator may do so it became necessary to encapsulate all of the responsibilities in a clean interface that caters to our object-oriented developers. To find out more about the additional capabilities when using this approach refer to IShapeGenerator. This technique can be used in lieu of the Asynchronous or Synchronous approaches discussed above, and all three approaches: 1) Synchronous, 2) Asynchronous and 3) Object-Oriented will be supported going forward to cater to the full spectrum of developers.
  • Object-Oriented

    var Mesh3D = Core.Mesh3D;
    var Solid = Core.Solid;
    
    // An object-oriented shape generator
    var Generator = {
    
      parameters: function(callback) {
        var params = [
          { 
            "id": "radius", 
            "displayName": "Radius", 
            "type": "length", 
            "rangeMin": 1, 
            "rangeMax": 50, 
            "default": 20 
          }
        ];
        callback(params);
      },
       
      evaluate: function(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));
       
      }
    
    };
    
    // Returns the object-oriented shape generator,
    function shapeGenerator() {
      return Generator;
    }