Usage
Distribution
The ShapeDiver 3D viewer v2 is available via the following storage locations:
- direct access: https://shapediverviewer.s3.amazonaws.com/v2/2.MINOR.PATCH/FILE, or
- CDN: https://viewer.shapediver.com/v2/2.MINOR.PATCH/FILE
Version numbers (2.MINOR.PATCH) follow the rules of SemVer.
The following files are available:
sdv.min.js
: minified viewersdv.concat.min.js
: minified viewer concatenated with external dependencies (Three.js, axios, verb-nurbs)sdv_reflector.min.js
: helper script which allows to reflect the API v2 between different browser windows, typically from an iframe to its parent window
JavaScript Namespace
Including the viewer JavaScript file defines the namespace SDVApp.
<script defer src="https://viewer.shapediver.com/v2/2.17.0/sdv.concat.min.js"></script>
Basic usage
Please refer to SDVApp.ParametricViewer for a documentation of available settings of the SDVApp.ParametricViewer
constructor.
Direct embedding - including UI
Give it a try: Direct embedding example
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>ShapeDiver Viewer v2</title>
<!-- ShapeDiver Viewer -->
<script defer src="https://viewer.shapediver.com/v2/2.17.0/sdv.concat.min.js"></script>
<link rel='stylesheet' type='text/css' href='https://viewer.shapediver.com/v2/2.17.0/sdv.css'>
<!-- ShapeDiver Viewer Controls and Export Modal Dialog Dependencies -->
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/css/uikit.min.css" integrity="sha256-sO/kKFCHPL4rhYHDyHC2dwGlaIBttifOfQ0ZaGLAheo=" crossorigin="anonymous" />
<!-- UIkit JS -->
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit.min.js" integrity="sha256-jN++RwBoYassp9qTuZDfQuptszFdL1Pm4dKZWS5KjjY=" crossorigin="anonymous"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit-icons.min.js" integrity="sha256-6pktS+jePPdXx9oCn8r4hS5jR1eq0Ry7vbifYtG0LDU=" crossorigin="anonymous"></script>
</head>
<body>
<!-- ShapeDiver Viewer Main Container -->
<div id='sdv-container' class='shapediver-container-flex shapediver-container-fullsize' sdv-fullscreen='true'>
<!-- ShapeDiver Viewer Settings Controls Container -->
<div id='sdv-container-settings' class='shapediver-settings-flex' style='display: none;'></div>
<!-- ShapeDiver Viewer Viewport Container -->
<div class='shapediver-viewport-flex'>
<div id='sdv-container-viewport' class='shapediver-container-fullsize' style='opacity: 0;'
logginglevel=0
messagelogginglevel=2
>
</div>
<!-- The loading icon will be created here -->
</div>
<!-- ShapeDiver Viewer Parameter Controls Container -->
<div id='sdv-container-controls' class='shapediver-controls-flex' style='display: none;'></div>
</div>
<script>
// ShapeDiver Viewer Initialisation
var initSdvApp = function(/*event*/) {
// settings can be defined here or as attributes of the viewport container
// settings defined here take precedence
let settings = {
ticket: 'TICKET_FOR_YOUR_MODEL',
modelViewUrl: 'eu-central-1', // or 'us-east-1' or address of your own ShapeDiver model view server
};
// provide global access to the ShapeDiver Viewer API returned by the constructor
window.api = new SDVApp.ParametricViewer(settings);
};
// there is a slight chance that loading has been completed already
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSdvApp, false);
} else {
initSdvApp();
}
</script>
</body>
</html>
iframe embedding
Give it a try: iframe embedding example
We provide a script for reflecting the API v2 to the iframe's parent window. This is done by translating all API calls to and from messages between the browser Window objects, see Window.postMessage.
After loading the example shown below, try to type api=SDVReflector.get('api')
in your browser console to see the magic
and get access to an API v2 object without the need to think about
Window.postMessage.
Please note that all synchronous functions of the API v2 become asynchronous due to the messaging which is happening
in the background, e.g. api.parameters.get()
becomes api.parameters.getAsync()
.
In case of iframe embedding you can pass settings to the constructor of SDVApp.ParametricViewer by means of query string parameters.
The example below shows settings modelViewUrl
and ticket
being passed in this way.
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="google" value="notranslate">
<title>ShapeDiver Viewer v2 - iframe test</title>
<!-- ShapeDiver Viewer API reflector, sets the global variable SDVReflector -->
<script src="https://viewer.shapediver.com/v2/2.17.0/sdv_reflector.min.js"></script>
</head>
<body>
<!-- Uncomment this script if you want to see messages received from the iframe in the browser console -->
<!--
<script>
window.addEventListener('message', console.log, false);
</script>
-->
<!-- Uncomment this script if you want to trigger some actions once the ShapeDiver Viewer has been loaded -->
<!--
<script>
window.addEventListener('message', function(event) {
if ( event.data && typeof event.data === 'object' ) {
if ( event.data.type === 'sdv-ViewerLoaded' ) {
console.log('ShapeDiver Viewer initialisation finished', event.data);
sdapi = SDVReflector.get('api');
} else if ( event.data.type === 'sdv-CommPluginLoaded' ) {
console.log('ShapeDiver CommPlugin successfully loaded', event.data);
sdapi.parameters.getAsync().then( function(result) {
console.log('Available model parameters', result.data);
});
}
}
}, false);
</script>
-->
<!-- Refer to the settings of the SDVApp.ParametricViewer constructor to find out which query string parameters can be used -->
<iframe id='sdv-iframe'
width="640" height="480"
src="https://viewer.shapediver.com/v2/2.17.0/iframe/remote.html?modelViewUrl=eu-central-1&ticket=TICKET_FOR_YOUR_MODEL"
referrerpolicy="origin"
allowfullscreen
scrolling="no"
style="overflow-x: hidden; overflow-y: hidden; border-width: 0;"
>
<p>Your browser does not support iframes.</p>
</iframe>
</body>
</html>
As the iframe loads and the viewer initializes, the following messages will be sent to notify you about the progress:
{type: 'sdv-DOMContentLoaded'}
: The DOM content of the iframe has been completely loaded, initialisation of the viewer has begun.{type: 'sdv-ViewerLoaded'}
: The initialisation of the viewer has finished, it's safe to callapi=SDVReflector.get('api')
to retrieve the reflected API v2 object.
Will only be sent if a ticket is specified when calling SDVApp.ParametricViewer
:
{type: 'sdv-CommPluginLoaded'}
: The CommPlugin which was created bySDVApp.ParametricViewer
was successfully loaded.{type: 'sdv-CommPluginFailed'}
: The CommPlugin which was created bySDVApp.ParametricViewer
failed to loaded.
Advanced usage
Direct embedding - minimal
In case you do not need the parameter and settings controls provided by ShapeDiver, direct embedding of the ShapeDiver Viewer can be simplified as shown in this example:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>ShapeDiver Viewer v2</title>
<!-- ShapeDiver Viewer -->
<script defer src="https://viewer.shapediver.com/v2/2.17.0/sdv.concat.min.js"></script>
<link rel='stylesheet' type='text/css' href='https://viewer.shapediver.com/v2/2.17.0/sdv.css'>
</head>
<body>
<!-- ShapeDiver Viewer Container -->
<div id='sdv-container' style='position: absolute; width: 100%; height: 100%; left:0%; top:0%' >
</div>
<script>
// ShapeDiver Viewer Initialisation
var initSdvApp = function(/*event*/) {
// settings can be defined here or as attributes of the viewport container
// settings defined here take precedence
let settings = {
ticket: 'TICKET_FOR_YOUR_MODEL',
modelViewUrl: 'eu-central-1', // or 'us-east-1' or address of your own ShapeDiver model view server
container: document.getElementById('sdv-container'),
};
// provide global access to the ShapeDiver Viewer API returned by the constructor
window.api = new SDVApp.ParametricViewer(settings);
};
// there is a slight chance that loading has been completed already
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSdvApp, false);
} else {
initSdvApp();
}
</script>
</body>
</html>
Deferred loading of geometry - Direct embedding
When loading the viewer you might want to initially load your model for parameter values different from its
currently stored default parameter values. To achieve this, tell the viewer to defer loading of geometry until the first parameter update,
by setting deferGeometryLoading
to true
as shown in the following example. Afterwards wait until parameters have been registered
before doing the first parameter update, which will in turn load initial geometry.
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>ShapeDiver Viewer v2</title>
<!-- ShapeDiver Viewer -->
<script defer src="https://viewer.shapediver.com/v2/2.17.0/sdv.concat.min.js"></script>
<link rel='stylesheet' type='text/css' href='https://viewer.shapediver.com/v2/2.17.0/sdv.css'>
<!-- ShapeDiver Viewer Controls and Export Modal Dialog Dependencies -->
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/css/uikit.min.css" integrity="sha256-sO/kKFCHPL4rhYHDyHC2dwGlaIBttifOfQ0ZaGLAheo=" crossorigin="anonymous" />
<!-- UIkit JS -->
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit.min.js" integrity="sha256-jN++RwBoYassp9qTuZDfQuptszFdL1Pm4dKZWS5KjjY=" crossorigin="anonymous"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit-icons.min.js" integrity="sha256-6pktS+jePPdXx9oCn8r4hS5jR1eq0Ry7vbifYtG0LDU=" crossorigin="anonymous"></script>
</head>
<body>
<!-- ShapeDiver Viewer Main Container -->
<div id='sdv-container' class='shapediver-container-flex shapediver-container-fullsize' sdv-fullscreen='true'>
<!-- ShapeDiver Viewer Settings Controls Container -->
<div id='sdv-container-settings' class='shapediver-settings-flex' style='display: none;'></div>
<!-- ShapeDiver Viewer Viewport Container -->
<div class='shapediver-viewport-flex'>
<div id='sdv-container-viewport' class='shapediver-container-fullsize' style='opacity: 0;'
logginglevel=0
messagelogginglevel=2
>
</div>
<!-- The loading icon will be created here -->
</div>
<!-- ShapeDiver Viewer Parameter Controls Container -->
<div id='sdv-container-controls' class='shapediver-controls-flex' style='display: none;'></div>
</div>
<script>
// ShapeDiver Viewer Initialisation
var initSdvApp = function(/*event*/) {
// settings can be defined here or as attributes of the viewport container
// settings defined here take precedence
let settings = {
ticket: 'TICKET_FOR_YOUR_MODEL',
modelViewUrl: 'eu-central-1', // or 'us-east-1' or address of your own ShapeDiver model view server
deferGeometryLoading: true, // tells the CommPlugin to not load default geometry, but wait for the first parameter update
};
// provide global access to the ShapeDiver Viewer API returned by the constructor
window.api = new SDVApp.ParametricViewer(settings);
// Register an event listener to get notified about the first parameter registration
var token = api.parameters.addEventListener(api.parameters.EVENTTYPE.REGISTERED, function() {
// be sure to deregister the event listener
api.parameters.removeEventListener(token.data);
// further parameter registrations might be pending in the event queue, therefore we append our first parameter update to the queue as well
setTimeout(function() {
api.parameters.updateAsync(/* HERE GOES YOUR PARAMETER UPDATE */);
}, 0);
});
};
// there is a slight chance that loading has been completed already
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSdvApp, false);
} else {
initSdvApp();
}
</script>
</body>
</html>
Deferred loading of geometry - iframe embedding
When loading the viewer you might want to initially load your model for parameter values different from its
currently stored default parameter values. To achieve this, tell the viewer to defer loading of geometry until the first parameter update,
by setting deferGeometryLoading
to true
as shown in the following example. Afterwards wait until parameters have been registered
before doing the first parameter update, which will in turn load initial geometry.
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="google" value="notranslate">
<title>ShapeDiver Viewer v2 - iframe test</title>
<!-- ShapeDiver Viewer API reflector, sets the global variable SDVReflector -->
<script src="https://viewer.shapediver.com/v2/2.17.0/sdv_reflector.min.js"></script>
</head>
<body>
<!-- Uncomment this script if you want to see messages received from the iframe in the browser console -->
<!--
<script>
window.addEventListener('message', console.log, false);
</script>
-->
<script>
window.addEventListener('message', async function(event) {
if ( event.data && typeof event.data === 'object' ) {
if ( event.data.type === 'sdv-ViewerLoaded' ) {
console.log('ShapeDiver Viewer initialisation finished', event.data);
// get a ShapeDiver Viewer API object
window.api = SDVReflector.get('api');
// register a ShapeDiver CommPlugin for a ShapeDiver model
await api.plugins.registerCommPluginAsync({
ticket: 'TICKET_FOR_YOUR_MODEL',
modelViewUrl: 'eu-central-1',
runtimeId: 'CommPlugin_1',
deferGeometryLoading: true
});
console.log('ShapeDiver CommPlugin successfully loaded', event.data);
// get parameters of the model
const result = await api.parameters.getAsync();
const parameters = result.data;
console.log('Available model parameters', parameters);
// send initial parameter update, this will also show the scene
await api.parameters.updateAsync([
{name: 'Param 1', value: 100},
{name: 'Param 2', value: 'some string'},
]);
// refresh, the initial parameter update might not have changed any values
await api.plugins.refreshPluginAsync('CommPlugin_1');
// show the scene
await api.updateSettingAsync('scene.show', true);
}
}
}, false);
</script>
<!-- Refer to the settings of the SDVApp.ParametricViewer constructor to find out which query string parameters can be used -->
<iframe id='sdv-iframe'
width="640" height="480"
src="https://viewer.shapediver.com/v2/2.17.0/iframe/remote.html"
referrerpolicy="origin"
allowfullscreen
scrolling="no"
style="overflow-x: hidden; overflow-y: hidden; border-width: 0;"
>
<p>Your browser does not support iframes.</p>
</iframe>
</body>
</html>
Loading of additional CommPlugins
To be documented