The ShapeDiver API

You can remote-control our viewer from within the page where it is embedded. Here's how.


Introduction

The professional version of the ShapeDiver viewer comes with it's own integrated API which can be accessed from scripts on the website where it is embedded. It works by using web messaging to send commands to the viewer iframe and receive responses from it. This allows you to integrate a parametric 3d viewer into your own applications and control things like camera movements, parameter updates, screenshot creation and much much more. A simple example in which the API is used to read the parameter definitions from a model and set up external sliders to control them can be found here. We will go through this example in detail below.


Register for use

Since the API is currently under heavy development, we would like to have a good overview of the people who use it and their applications. On one hand, this enables us to contact you in case of major changes in functionality, updates or news. On the other hand, knowing what the API is used for should help us target our development resources (which are quite limited at the moment) to those features that are actually needed.

To register for API use, please contact us and let us know a little bit about you and your project. We will then upgrade your ShapeDiver user account so that

  • API access is enabled for all your models
  • you can use extended embedding features like disabling the internal controls in the viewer


Hello world

Let's take a closer look at the example mentioned above. It uses the ShapeDiver demo cube, a very simple model with three number sliders.

See the Pen WRZQRo by ShapeDiver (@ShapeDiver) on CodePen.


The HTML part consists mainly of a ShapeDiver iframe embed code with a single option, showControls, set to false. This is turning off the internal viewer controls and it is done because we will use the API to set up external controls outside the viewer. A separate div is added to hold these external controls.

The main functionality is implemented in Javascript, so let's look at the different parts of it step by step.

Getting parameter info

//once the iframe is loaded, we initialize our external controls
$('#sd-iframe').on('load', function() {
	// request parameter definitions
	payload = {
		command: "getParameterDefinitions"
	};
	this.contentWindow.postMessage(payload, "https://www.shapediver.com");
 });

Here, we simply wait for the iframe to load an then request information about all the parameters set up for this model. The this within this function refers to the iframe DOM element and as you can see, we send it a simple command without any arguments. Please note that the ShapeDiver.com domain is added as a second argument to the postMessage function. This is important for security reasons and makes sure that messages are restricted to the intended recipient, in this case our viewer page.

Receiving messages

 function receiveMessage(event) {
	var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
	var data = event.data || event.originalEvent.data;
	var source = event.source || event.originalEvent.source;

	// for security reasons we accept only messages from shapediver.com
	if (origin != "https://www.shapediver.com")
			return;

The function receiveMessage will be called whenever the current document receives a message from the iframe. As a first step, we retrieve the origin of the message and check if it is legitimate. Then, we get the actual message data and store its source, which in this case is our ShapeDiver iframe object.

// we expect a JSON object with two values: a command name and a result
if (!data.hasOwnProperty("command")) {
		console.warn("Message did not contain command name. Aborting.")
		return;
}

// at this point the result might be undefined for the command setParameterValue in many cases, this is being fixed asap
if (!data.hasOwnProperty("result")) {
	console.warn("Message did not contain command result. Aborting.")
		return;
}

var commandName = data.command;
var result = data.result;

The general structure of messages received from the viewer is very similar to that of messages sent to it. They always include a commandName which indicates the command to which this message is a response and a result which can be as simple as a boolean or as complex as parameter descriptions or an image data blob.

Now we get to the only step in this example that is a bit intricate. We retrieve the actual parameter information from a message and set up number inputs (sliders) using this info.

Reading parameter info and setting up sliders

If the message we received is an answer to getParameterDefinitions we assume that the result is an object containing the definitions of all parameters in the embedded model. For our example model, this object might look like this:

{
	"99719be3-6d27-4c72-b70d-458eca7a6a1b": {
		decimalPlaces: 1,
		default: 2.9,
		max: 4,
		min: 1,
		title: "Twist Height",
		type: "Real",
		visibleName: "Twist Height"
	},
	"ab780f74-f78e-4b6b-8944-fbf65fcacc78": {
		decimalPlaces: 1,
		default: 0,
		max: 1.5,
		min: 0,
		title: "Top Twist",
		type: "Real",
		visibleName: "Top Twist"
	},
	"eda79390-2c5e-4772-a833-19b9049aa42c": {
		decimalPlaces: 1,
		default: 0,
		max: 1,
		min: 0,
		title: "Middle Twist",
		type: "Real",
		visibleName: "Middle Twist"
	}
}

Using this information, the our function adds three range inputs to the prepared div. A little problem in this very simple setup is the fact that pure HTML range inputs are a bit limited when it comes to values with decimal places. We help ourselves by multiplying the values with 10 before applying them to the slider and vice versa.


if (commandName == "getParameterDefinitions") {
		if (!blnHaveParameterDefinitions) {
				
				// create one slider for each parameter
				for (var param in result) {
						
						// create sliders - since standard html range inputs allow only integer steps,
						// we multiply the min and max values with 10^decimalPlaces so we can accomodate values with smaller steps
						$("#sd-ext-controls").append("<div>" + result[param].visibleName + "<p><input id=\"" + param + "\"  type=\"range\" name=\"" + param + "\" min=\"" + result[param].min * Math.pow(10, result[param].decimalPlaces) + "\" max=\"" + result[param].max * Math.pow(10, result[param].decimalPlaces) + "\"></div></p>");
						
						// event watcher for slider value changes - if the user changes a value,
						// send the info to the viewer 
						$("#" + param).change(function() {
								
								// here we divide the new value by 10^decimalplaces to get the correct value for the update
								var payload = {
										command: "setParameterValue",
										arguments: [this.id, $("#" + this.id).val() / Math.pow(10, result[param].decimalPlaces)]
								};
								source.postMessage(payload, "https://www.shapediver.com");
						});
				}
				
				// make sure to get initial values from viewer to set sliders correctly
				var payload = {
						command: "getParameterValues"
				};
				source.postMessage(payload, origin);
				blnHaveParameterDefinitions = true;
		}
}

In the second part of the function above, we set up event watchers for each of the sliders. On each change of the slider value, we send a message to the viewer which triggers an update. The setParameterValue command has two arguments: the parameter id and the new value.

As a last step, the function calls to retrieve the current, initial parameter values. Normally these should be the default values shown in the parameter definitions but there are exceptions to this rule. The response to this call will be read (see below) and the initial slider values will be set accordingly.

	// if we get informed about current parameter values, we set our sliders accordingly
	if (commandName == "getParameterValues") {
			for (var param in result) {
				console.log("Setting parameter " + param + " to " + result[param]);
				$("#" + param).val(result[param] * Math.pow(10, decimalPlacesForParameters[param]));
			}
	}
 }

// event watcher for incoming messages from the viewer
$(window).on("message", receiveMessage);

Last but not least, we set an event watcher that catches every message sent to our window and relays it to the receiveMessage function we just created.

This is for sure not the most concise "Hello world" example you have ever seen, but we hope that it does provide a first look at the ShapeDiver API and its basic usage. If you have feedback, suggestions or questions regarding the API or this introduction, please feel free to write us in our forum.

You can find the complete and constantly growing command reference for the API on this page. When we'll come up with additional examples, we will post them here as well. If you have built an application or tool that you think should be featured here, please feel free to let us know!

activateTopView(topView)


Toggle the top view mode.


Arguments

Param
Type
Details
topView
Boolean
If true, top view mode is activated.

Returns

Boolean
True if setting was changed. False if setting was already set to the chosen value.

If set to true, the camera is restricted to a top view of the scene. Panning and zooming is still possible, but rotating the camera in any way is impossible.




cameraPath(positions,targets,duration)


Tells the viewer camera to follow a given path in a given duration.


Arguments

Param
Type
Details
positions
Array{Object}
An array of 3d vectors defining camera positions along the path. The format is [{x: 0.0, y: 0.0, z: 0.0}, {x: 1.0, y: 1.0, z: 1.0}, {x: 0.0, y: 3.0, z: 1.0}].
targets
Array{Object}
An array of 3d vectors defining camera target along the path.
duration
Number
Length of the path in milliseconds.

Returns

Boolean
True if the path definition is valid.

This command will prompt the viewer to move its camera on a smooth path interpolating a given set of 3d locations. The camera rotation values and targets are interpolated as well. The most straightforward way to come up with proper input values for predefined paths is to manually move the camera to a desired location and read the values from the viewer using the getCamera command.


See also:




getCamera()


Returns the current camera position and orientation.


Returns

Object
The current camera position and orientation in the following format:
{position: {x: 0.0, y: 0.0, z: 0.0}, target: {x: 0.0, y: 0.0, z: 0.0}}

This information can be used to return the camera to a specific position using the setCamera command or create camera paths using cameraPath.


See also:




getExportDefinitions()


Returns a list of available geometry exports.


Returns

Array
All export definitions for the current model. The format is as follows:
[    
	{
		"id":	"d2514fd5caaf8d6cd563c616b09",
		"name":	"Download cut path as DWG",
		"type":	"download"
	},    
	{	"id":	"3fccf6f6-9eac4ffd-90dd940c7",
		"name":	"Order this origami from the designer",
		"type":	"email"
	}
]

Using the ShapeDiver plugin, designers can define several types of geometry exports in their Grasshopper definitions. Currently, geometry can be downloaded in the browser or sent to an email address specified by the designer. This command returns a list of available exports with their types and names. They can then be triggered by using the requestExport command.


See also:




getModelData()


Retrieves model specific data created by data output components.


Returns

Object
The object members are named as the unique ids of the individual data members. Their properties include the value and name of the data object.

Retrieves any model data created by ShapeDiver data output Grasshopper components. Values are updated whenever the parameters are changed.




getParameterDefinitions()


Requests the parameter definition information for the loaded model.


Returns

Object
An object describing all available parameter for the current model. See below for details.

Sending this command will prompt the viewer to return an object containing the complete parameter information for the loaded model. The 'result' object will contain one object for each parameter, named with a unique parameter id. The content of these parameter objects will vary depending on the type of the parameter.


Common elements

The following elements are included for all parameter types:

Element
Type
Definition
type
String
The parameter type description.
title
String
The title of the parameter as defined in the GH model.
default
varies
The default value for this parameter. This can be changed on shapediver.com via the model edit pane.
visibleName
String
The name of the parameter as set in shapediver.com's edit mode. After uploading a mode, this will be identical to 'title'.

Numerical parameters

The following additional elements are featured in numeric parameter types:

Element
Type
Definition
min
Number
The maximum admissible parameter value.
max
Number
The minimum admissible parameter value.
decimalPlaces
Integer
Number of decimal places allowed for values of this parameter. If more are provided, the viewer will truncate them before updating.

List parameters

The parameter types Checklist, Cycle, Sequence and DropDown are special in that their values consist of integers describing a selection of values from a list.
For Checklist, the format of the value is a comma separated list of integer indices as any number of choices can be selected. For the others, a single integer defines the active choice.
Choices are described in an array aptly named 'choices'.

Element
Type
Definition
choices
Array{String}
Describes the choices from which one (or several) can be selected.


The following code snippet is an example for the information returned by the viewer to a parameter definition request:


{
  "command": "getParameterDefinitions",
  "result": {
    "a017f07e-acb8-45fd-85e4-f530d0178775": {
      "type": "String",
      "title": "Message",
      "default": "Welcome to ShapeDiver",
      "maxLength": 30,
      "visibleName": "Message"
    },
    "fd810684-92ba-498b-af53-5b89d1a21307": {
      "type": "Date",
      "title": "Date",
      "default": "2016-07-04T00:00:00",
      "visibleName": "Date"
    },
    "6261f132-b694-4439-8930-e849f573e4f1": {
      "type": "Time",
      "title": "Time",
      "default": "0001-01-01T23:55:00",
      "visibleName": "Time"
    },
    "a23b0838-d8e2-4f69-b650-3320a2caa0d5": {
      "type": "Odd",
      "title": "SliderOdd",
      "min": 1,
      "max": 9,
      "default": 3,
      "decimalPlaces": 0,
      "visibleName": "SliderOdd"
    },
    "4f761185-6f77-431e-8c68-319427d96172": {
      "type": "Even",
      "title": "SliderEven",
      "min": 0,
      "max": 10,
      "default": 8,
      "decimalPlaces": 0,
      "visibleName": "SliderEven"
    },
    "02721960-af59-4b3d-a806-a8cb98929b58": {
      "type": "Real",
      "title": "Slider1Digit",
      "min": 0,
      "max": 10,
      "default": 7.5,
      "decimalPlaces": 1,
      "visibleName": "Slider1Digit"
    },
    "65f0f5da-7722-45bd-a123-a6f8b54d62c6": {
      "type": "Integer",
      "title": "SliderNatural",
      "min": 0,
      "max": 10,
      "default": 5,
      "decimalPlaces": 0,
      "visibleName": "SliderNatural"
    },
    "b9ec1460-0b3b-42a3-8c30-ce4d44f112bc": {
      "type": "Real",
      "title": "Slider2Digit",
      "min": 0,
      "max": 10,
      "default": 0.74,
      "decimalPlaces": 2,
      "visibleName": "Slider2Digit"
    },
    "3ea8934e-5442-438e-a3d6-38941118337d": {
      "type": "Color",
      "title": "Textcolor",
      "default": "0x1bb5ffff",
      "visibleName": "Textcolor"
    },
    "505a9a2a-4359-4a71-8120-dc763c95aab9": {
      "type": "Cycle",
      "title": "Type",
      "default": "1",
      "choices": [
        "Arrow2d",
        "Arrow3d",
        "Sphere"
      ],
      "visibleName": "Type"
    },
    "ddeb83ac-2064-4d42-8a8b-e1d0421c6713": {
      "type": "Checklist",
      "title": "Legend",
      "default": "0,1,2,3",
      "choices": [
        "Ticks",
        "Text2d",
        "Tag2d",
        "Tag3d"
      ],
      "visibleName": "Legend"
    },
    "60f97239-b66b-4d4f-bae4-fbd7bb5c3e8b": {
      "type": "Real",
      "title": "Textsize",
      "min": 0.5,
      "max": 2,
      "default": 0.7,
      "decimalPlaces": 1,
      "visibleName": "Textsize"
    },
    "bbe31535-75bd-412e-a3ae-a8e13c40ea90": {
      "type": "Integer",
      "title": "KnobAngle",
      "min": 0,
      "max": 360,
      "default": 0,
      "decimalPlaces": 0,
      "visibleName": "KnobAngle"
    },
    "8337f849-9987-4a3e-86b8-3aab917e356b": {
      "type": "Dropdown",
      "title": "Material",
      "default": "2",
      "choices": [
        "Basic",
        "Plastic",
        "Metal",
        "Glass"
      ],
      "visibleName": "Material"
    },
    "1d115a54-6fda-4d4e-b8ce-e89c4ad1e286": {
      "type": "Color",
      "title": "Colour",
      "default": "0x20c622ff",
      "visibleName": "Colour"
    }
  },
  "errorCode": 0,
  "errorMessage": ""
}

					


See also:




getParameterValues()


Retrieves current values for all parameters.


Returns

Object
An object with the following format:
{
	"command": "getParameterValues",
	"result": {     
		"a017f07e-acb8-45fd-85e4-f530d0178775": 30,
		"fd810684-92ba-498b-af53-5b89d1a21307": "2016-07-04T00:00:00",
		"6261f132-b694-4439-8930-e849f573e4f1": "0001-01-01T23:55:00",
		"a23b0838-d8e2-4f69-b650-3320a2caa0d5": "0x20c622ff"  
	} 
} 

Returns an object with the ids and current values of all parameters of the loaded model. Please note that when a parameter is updated by the user or via the API, this command will immediately begin to return the new parameter value as 'current'. However, it might still take a while until the viewer actually displays the updated geometry. To get a full overview over the status of the viewer, combine this command with getStatus.


See also:




getScreenshot()


Get screenshot as data URI


Returns

String
Data URI of a screenshot of the viewer canvas. Will always begin with data:image/png;base64,...

This command will return a screenshot of the viewer canvas without any control elements as a data URI using the png image format.




getStatus()


Returns a status code and description.


Returns

Object
A status description in the following format:
{
	"statusCode": 3, 
	"statusText": "Error",
	"statusInfo": "Lost connection to ShapeDiver."
}

The viewer can be in one of the following states:

State
Code
Description
Busy
1
Updated geometry is currently being loaded from server. This may be because of a parameter update or because the initial geometry is still being loaded.
Initializing
2
Viewer or at least one plugin are still initializing.
Error
3
There has been an error, the viewer must be reloaded. Error information is included as a message string.


See also:




hideControls()


Hides the control panel and its toggle from the viewer window.


Returns

Boolean
True if the control panel was hidden.

This command deactivates the display of the control panel and the corresponding toggle from the viewer.


See also:




hideFullscreenToggle()


Hides the full-screen toggle in the viewer.


Returns

Boolean
True if the full-screen toggle was hidden.


See also:




requestExport(id)


Triggers different export actions based on the type of the export.


Arguments

Param
Type
Details
id
String
The id of the export to be triggered.

Returns

Boolean
True if the export was processed successfully.

Requests the execution of an export using the current parameter set. The triggered action depends on the type of the export. For exports of type download, the command triggers the user's browser to download the exported geometry in the file format specified by the designer. Exports of type email will prompt the ShapeDiver servers to send an email with a download link and the current parameter set to the email address specified by the designer. In this case, the user does not get direct access to the exported geometry.


See also:




restrictCamera(component,blnMax,value)


Restricts camera movement in x, y or z directions.


Arguments

Param
Type
Details
component
Integer
0 for restriction in the x-direction, 1 for y, 2 for z
blnMax
Boolean
If true, the value is set as an upper bound, otherwise as a lower bound.
value
Number
The coordinate used as an upper or lower bound on camera movement.

Returns

Boolean
True if the camera movement was successfully restricted.

Restricts the effective movement of the viewer's camera beyong a given axis-parallel plane. As an example, you could prohibit the camera from moving below the xy-plane by setting a lower bound on the z-coordinate.


See also:




restrictPan(component,blnMax,value)


Defines upper and lower bounds for camera panning.


Arguments

Param
Type
Details
component
Integer
0 for restriction in the x-direction, 1 for y, 2 for z
blnMax
Boolean
If true, the value is set as an upper bound, otherwise as a lower bound.
value
Number
The coordinate used as an upper or lower bound on panning.

Returns

Boolean
True if panning was successfully restricted.

Prohibits the panning of the camera target beyond a given axis parallel plane.


See also:




setAutoRotate(speed)


Starts or stops autorotation of the camera around the object.


Arguments

Param
Type
Details
speed
Number
Speed to be used for autoration of the camera. Typical values are not higher than 10. Setting the speed to 0 stops autoration.

Returns

Boolean
True if autorotation was updated.

This command allows to activate autoration of the camera. Pass speed 0 to deactivate autorotation.




setButtonColor(color)


Changes the color of buttons and toggles in the viewer.


Arguments

Param
Type
Details
color
Color
The new color for buttons and toggles.

Returns

Boolean
True if color was changed successfully.

Buttons and toggles in the parameter widget and the viewer will be changed to this color. The toggles will remain gray if unused, but will take the new color when hovered above or activated.




setCamera(position,target,tween,tweenLength)


Move the camera to a new position.


Arguments

Param
Type
Details
position
Object
A 3d vector describing the new position of the camera. The format is {x: 0.0, y: 0.0, z: 0.0}.
target
Object
A 3d vector describing the new target to which the camera will point after the update.
tween
Boolean
If true, the camera will smoothly move to the new position within a duration given by the next parameter. If false, the move will be instant.
tweenLength
Integer
Length of the movement in milliseconds.

Returns

Boolean
True if camera could was set.

This command will make the camera smoothly move to a new position.


See also:




setControlDamping(damping)


Sets the damping factor for camera rotation and panning.


Arguments

Param
Type
Details
damping
Number
Damping factor between 0 and 1.

Returns

Boolean
True if the command was successful.

Sets the damping factor for camera rotation and panning.


See also:




setEdgeColor(color)


Define color of visible edges


Arguments

Param
Type
Details
color
Color
The new color used to render visible edges.

Returns

Boolean
True if color was set.

Define color for all visible edges. This color is only used if setEdgeColorByObject is set to false and showEdges is set to true.


See also:




setEdgeColorByObject(byObject)


Define how visible edges are colored.


Arguments

Param
Type
Details
byObject
Boolean
True if edges should be colored according to their parent object.

Returns

Boolean
True if the setting was changed, false if it was already at the desired value.

Configure how the color of visible edges is defined. If you set this to true, edges will be colored according to the main color of the object they correspond to. Otherwise, all visible edges will have the color set using setEdgeColor.


See also:




setIgnoreMouse(bIgnoreMouse)


Ignore all mouse input to the viewer


Arguments

Param
Type
Details
bIgnoreMouse
Boolean
If true, all mouse input to the 3d viewer window will be ignored. This does not apply to the parameter widget, which will stil function normally.

Returns

Boolean
True if command could be processed.




setParameterValue(id,value)


Tells the viewer to update a given parameter to a new value.


Arguments

Param
Type
Details
id
String
The unique id of the parameter which should be updated.
value
(String/Number/Boolean)
The new value of the parameter. Subject to constraints set in parameter definition.

Returns

Boolean
True if parameter id and value are valid.

This is one of the most basic and important commands in the ShapeDiver API. Given the unique id of a parameter of the loaded model as well as a valid new value for this parameter, the viewer will update the model to reflect the new value.

The viewer will check if the parameter id and value provided are valid based on its stored parameter information and respond accordinglyy once this check has been finished. Please note that the viewer's response will typically be returned before the actual update has been received from the ShapeDiver servers and is being displayed. To get information about the loading status of the viewer please use the getStatus command.


See also:




setRotateSpeed(speed)


Sets the rotation speed of the camera.


Arguments

Param
Type
Details
speed
Number
Rotation speed between 0 and 1.

Returns

Boolean
True if the command was successful.

Sets the rotation speed of the camera when using the rotation control of the viewer. Not to be confused with setAutoRotate.


See also:




setZoomSpeed(speed)


Sets the zoom speed of the camera


Arguments

Param
Type
Details
speed
Number
Zoom speed between 0 and 1.

Returns

Boolean
True if the command was successful.

Sets the zoom speed of the camera when using the zoom control of the viewer.




showControls()


Shows the control panel and its toggle in the viewer.


Returns

Boolean
True if the control panel was shown.

This command activates the display of the control panel and the corresponding toggle from the viewer.


See also:




showEdges(show)


Choose whether to display feature edges for all objects.


Arguments

Param
Type
Details
show
Boolean
If true, edges will be shown.

Returns

Boolean
True if setting was changed. False if setting was already set to the chosen value.

If set to true, lines are displayed to emphasize objects' feature edges.


See also:




showFullscreenToggle()


Shows the full-screen toggle in the viewer.


Returns

Boolean
True if the full-screen toggle was shown.


See also:




showGrid(show)


Choose whether to display the ground plane grid.


Arguments

Param
Type
Details
show
Boolean
If true, the grid will be shown.

Returns

Boolean
True if setting was changed. False if setting was already set to the chosen value.