diff --git a/README.md b/README.md
index 9306dfa..176b553 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,18 @@
# Online 3D Viewer
-This repository contains the source code of the https://3dviewer.net website. The website can open several 3D file formats and visualize the model in your browser.
+Online 3D Viewer (https://3dviewer.net) is a free and open source web solution to visualize and explore 3D models right in your browser. This repository contains the source code of the website and the library behind it.
[](https://ci.appveyor.com/project/kovacsv/online3dviewer)
[](https://travis-ci.com/kovacsv/Online3DViewer)
[](https://lgtm.com/projects/g/kovacsv/Online3DViewer/context:javascript)
+[](https://codecov.io/gh/kovacsv/Online3DViewer)
## Documentation
-- [User Documentation](https://3dviewer.net/info)
-- [Developer Documentation](https://github.com/kovacsv/Online3DViewer/wiki)
+The repository is separated into two parts. See more information in the [Developer Documentation](https://github.com/kovacsv/Online3DViewer/wiki).
+
+* **Online 3D Viewer Website**: Source code of the web solution with all of the pages and functions.
+* **Online 3D Viewer Engine**: Source code of the library to visualize models easily.
## Supported file formats
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..c31f84a
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,4 @@
+coverage:
+ range: 50..80
+ round: down
+ precision: 0
diff --git a/package.json b/package.json
index 6eef821..0269686 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "online-3d-viewer",
"description": "Online 3D Viewer",
- "version": "0.7.4",
+ "version": "0.7.5",
"repository": "github:kovacsv/Online3DViewer",
"license": "MIT",
"devDependencies": {
diff --git a/source/external/three.model.loader.js b/source/external/three.model.loader.js
index 236ded1..6e7a0d2 100644
--- a/source/external/three.model.loader.js
+++ b/source/external/three.model.loader.js
@@ -12,6 +12,11 @@ OV.ThreeModelLoader = class
this.callbacks = callbacks;
}
+ SetDefaultColor (defaultColor)
+ {
+ this.importer.SetDefaultColor (defaultColor);
+ }
+
LoadFromUrlList (urls)
{
if (this.inProgress) {
@@ -39,11 +44,22 @@ OV.ThreeModelLoader = class
obj.OnFilesLoaded ();
});
}
+
+ ReloadFiles ()
+ {
+ if (this.inProgress) {
+ return;
+ }
+
+ this.inProgress = true;
+ this.callbacks.onLoadStart ();
+ this.OnFilesLoaded ();
+ }
OnFilesLoaded ()
{
let obj = this;
- this.callbacks.onFilesLoaded ();
+ this.callbacks.onImportStart ();
OV.RunTaskAsync (function () {
obj.importer.Import ({
success : function (importResult) {
@@ -60,7 +76,7 @@ OV.ThreeModelLoader = class
OnModelImported (importResult)
{
let obj = this;
- this.callbacks.onModelImported ();
+ this.callbacks.onVisualizationStart ();
OV.ConvertModelToThreeMeshes (importResult.model, {
onTextureLoaded : function () {
obj.callbacks.onTextureLoaded ();
diff --git a/source/import/importer.js b/source/import/importer.js
index 3bd5825..4575172 100644
--- a/source/import/importer.js
+++ b/source/import/importer.js
@@ -260,6 +260,7 @@ OV.Importer = class
new OV.ImporterGltf ()
];
this.fileList = new OV.FileList (this.importers);
+ this.defaultColor = new OV.Color (200, 200, 200);
this.model = null;
this.usedFiles = [];
this.missingFiles = [];
@@ -275,6 +276,11 @@ OV.Importer = class
this.LoadFiles (fileList, OV.FileSource.File, onReady);
}
+ SetDefaultColor (defaultColor)
+ {
+ this.defaultColor = defaultColor;
+ }
+
Import (callbacks)
{
let mainFile = this.fileList.GetMainFile ();
@@ -310,7 +316,7 @@ OV.Importer = class
importer.Import (mainFile.file.content, mainFile.file.extension, {
getDefaultMaterial : function () {
let material = new OV.Material ();
- material.diffuse = new OV.Color (200, 200, 200);
+ material.diffuse = obj.defaultColor;
return material;
},
getFileBuffer : function (filePath) {
diff --git a/source/viewer/urlutils.js b/source/parameters/parameterlist.js
similarity index 52%
rename from source/viewer/urlutils.js
rename to source/parameters/parameterlist.js
index 98c2587..285feaf 100644
--- a/source/viewer/urlutils.js
+++ b/source/parameters/parameterlist.js
@@ -1,20 +1,30 @@
-OV.UrlParamConverter =
+OV.ParameterConverter =
{
- CameraToUrlParameter : function (camera)
+ NumberToString (number)
+ {
+ let precision = 5;
+ return number.toPrecision (precision);
+ },
+
+ StringToNumber (str)
+ {
+ return parseFloat (str);
+ },
+
+ CameraToString : function (camera)
{
if (camera === null) {
return null;
}
- let precision = 5;
let cameraParameters = [
- camera.eye.x.toPrecision (precision), camera.eye.y.toPrecision (precision), camera.eye.z.toPrecision (precision),
- camera.center.x.toPrecision (precision), camera.center.y.toPrecision (precision), camera.center.z.toPrecision (precision),
- camera.up.x.toPrecision (precision), camera.up.y.toPrecision (precision), camera.up.z.toPrecision (precision)
+ this.NumberToString (camera.eye.x), this.NumberToString (camera.eye.y), this.NumberToString (camera.eye.z),
+ this.NumberToString (camera.center.x), this.NumberToString (camera.center.y), this.NumberToString (camera.center.z),
+ this.NumberToString (camera.up.x), this.NumberToString (camera.up.y), this.NumberToString (camera.up.z)
].join (',');
return cameraParameters;
},
- UrlParameterToCamera : function (urlParam)
+ StringToCamera : function (urlParam)
{
if (urlParam === null || urlParam.length === 0) {
return null;
@@ -24,14 +34,14 @@ OV.UrlParamConverter =
return null;
}
let camera = new OV.Camera (
- new OV.Coord3D (parseFloat (paramParts[0]), parseFloat (paramParts[1]), parseFloat (paramParts[2])),
- new OV.Coord3D (parseFloat (paramParts[3]), parseFloat (paramParts[4]), parseFloat (paramParts[5])),
- new OV.Coord3D (parseFloat (paramParts[6]), parseFloat (paramParts[7]), parseFloat (paramParts[8]))
+ new OV.Coord3D (this.StringToNumber (paramParts[0]), this.StringToNumber (paramParts[1]), this.StringToNumber (paramParts[2])),
+ new OV.Coord3D (this.StringToNumber (paramParts[3]), this.StringToNumber (paramParts[4]), this.StringToNumber (paramParts[5])),
+ new OV.Coord3D (this.StringToNumber (paramParts[6]), this.StringToNumber (paramParts[7]), this.StringToNumber (paramParts[8]))
);
return camera;
},
- ModelUrlsToUrlParameter : function (urls)
+ ModelUrlsToString : function (urls)
{
if (urls === null) {
return null;
@@ -39,7 +49,7 @@ OV.UrlParamConverter =
return urls.join (',');
},
- UrlParameterToModelUrls : function (urlParam)
+ StringToModelUrls : function (urlParam)
{
if (urlParam === null || urlParam.length === 0) {
return null;
@@ -48,22 +58,23 @@ OV.UrlParamConverter =
}
};
-OV.UrlParamBuilder = class
+OV.ParameterListBuilder = class
{
- constructor ()
+ constructor (separator)
{
+ this.separator = separator;
this.urlParams = '';
}
AddModelUrls (urls)
{
- this.AddUrlPart ('model', OV.UrlParamConverter.ModelUrlsToUrlParameter (urls));
+ this.AddUrlPart ('model', OV.ParameterConverter.ModelUrlsToString (urls));
return this;
}
AddCamera (camera)
{
- this.AddUrlPart ('camera', OV.UrlParamConverter.CameraToUrlParameter (camera));
+ this.AddUrlPart ('camera', OV.ParameterConverter.CameraToString (camera));
return this;
}
@@ -73,7 +84,7 @@ OV.UrlParamBuilder = class
return;
}
if (this.urlParams.length > 0) {
- this.urlParams += '$';
+ this.urlParams += this.separator;
}
this.urlParams += keyword + '=' + urlPart;
}
@@ -84,10 +95,11 @@ OV.UrlParamBuilder = class
}
};
-OV.UrlParamParser = class
+OV.ParameterListParser = class
{
- constructor (urlParams)
+ constructor (urlParams, separator)
{
+ this.separator = separator;
this.urlParams = urlParams;
}
@@ -99,13 +111,13 @@ OV.UrlParamParser = class
}
let keywordParams = this.GetKeywordParams ('model');
- return OV.UrlParamConverter.UrlParameterToModelUrls (keywordParams);
+ return OV.ParameterConverter.StringToModelUrls (keywordParams);
}
GetCamera ()
{
let keywordParams = this.GetKeywordParams ('camera');
- return OV.UrlParamConverter.UrlParameterToCamera (keywordParams);
+ return OV.ParameterConverter.StringToCamera (keywordParams);
}
GetKeywordParams (keyword)
@@ -114,7 +126,7 @@ OV.UrlParamParser = class
return null;
}
let keywordToken = keyword + '=';
- let urlParts = this.urlParams.split ('$');
+ let urlParts = this.urlParams.split (this.separator);
for (let i = 0; i < urlParts.length; i++) {
let urlPart = urlParts[i];
if (urlPart.startsWith (keywordToken)) {
@@ -125,9 +137,19 @@ OV.UrlParamParser = class
}
};
+OV.CreateUrlBuilder = function ()
+{
+ return new OV.ParameterListBuilder ('$');
+};
+
+OV.CreateUrlParser = function (urlParams)
+{
+ return new OV.ParameterListParser (urlParams, '$');
+};
+
OV.CreateUrlParameters = function (urls, camera)
{
- let builder = new OV.UrlParamBuilder ();
+ let builder = OV.CreateUrlBuilder ();
builder.AddModelUrls (urls);
builder.AddCamera (camera);
return builder.GetUrlParams ();
diff --git a/source/viewer/domviewer.js b/source/viewer/domviewer.js
index 45f9c90..32c60ee 100644
--- a/source/viewer/domviewer.js
+++ b/source/viewer/domviewer.js
@@ -1,5 +1,19 @@
OV.Init3DViewerElements = function ()
{
+ function SetCamera (element, viewer, importResult)
+ {
+ let camera = null;
+ let cameraParams = element.getAttribute ('camera');
+ if (cameraParams) {
+ camera = OV.ParameterConverter.StringToCamera (cameraParams);
+ }
+ if (camera !== null) {
+ viewer.SetCamera (camera);
+ } else {
+ viewer.SetUpVector (importResult.upVector, false);
+ }
+ }
+
function LoadElement (element)
{
let canvas = document.createElement ('canvas');
@@ -8,10 +22,9 @@ OV.Init3DViewerElements = function ()
let viewer = new OV.Viewer ();
viewer.Init (canvas);
- let width = parseInt (element.getAttribute ('width'));
- let height = parseInt (element.getAttribute ('height'));
- element.style.width = width + 'px';
- element.style.height = height + 'px';
+ let width = element.clientWidth;
+ let height = element.clientHeight;
+ console.log (element.clientHeight);
viewer.Resize (width, height);
let loader = new OV.ThreeModelLoader ();
@@ -23,20 +36,21 @@ OV.Init3DViewerElements = function ()
element.appendChild (progressDiv);
progressDiv.innerHTML = 'Loading model...';
},
- onFilesLoaded : function () {
+ onImportStart : function () {
progressDiv.innerHTML = 'Importing model...';
},
- onModelImported : function () {
+ onVisualizationStart : function () {
progressDiv.innerHTML = 'Visualizing model...';
},
onModelFinished : function (importResult, threeMeshes) {
element.removeChild (progressDiv);
- canvas.style.display = 'initial';
+ canvas.style.display = 'inherit';
viewer.AddMeshes (threeMeshes);
let boundingSphere = viewer.GetBoundingSphere (function (meshUserData) {
return true;
});
viewer.AdjustClippingPlanes (boundingSphere);
+ SetCamera (element, viewer, importResult);
viewer.FitToWindow (boundingSphere, false);
},
onTextureLoaded : function () {
@@ -52,27 +66,34 @@ OV.Init3DViewerElements = function ()
return;
}
- let modelUrls = OV.UrlParamConverter.UrlParameterToModelUrls (modelParams);
+ let modelUrls = OV.ParameterConverter.StringToModelUrls (modelParams);
if (modelUrls === null || modelUrls.length === 0) {
return;
}
- let cameraParams = element.getAttribute ('camera');
- if (cameraParams) {
- let camera = OV.UrlParamConverter.UrlParameterToCamera (cameraParams);
- if (camera !== null) {
- viewer.SetCamera (camera);
- }
- }
-
loader.LoadFromUrlList (modelUrls);
+ return {
+ element: element,
+ viewer: viewer
+ };
}
+ let viewerElements = [];
window.addEventListener ('load', function () {
let elements = document.getElementsByClassName ('online_3d_viewer');
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
- LoadElement (element);
+ let viewerElement = LoadElement (element);
+ viewerElements.push (viewerElement);
+ }
+ });
+
+ window.addEventListener ('resize', function () {
+ for (let i = 0; i < viewerElements.length; i++) {
+ let viewerElement = viewerElements[i];
+ let width = viewerElement.element.clientWidth;
+ let height = viewerElement.element.clientHeight;
+ viewerElement.viewer.Resize (width, height);
}
});
};
diff --git a/test/tests/importer_test.js b/test/tests/importer_test.js
index 0e375b4..2e5b7f8 100644
--- a/test/tests/importer_test.js
+++ b/test/tests/importer_test.js
@@ -233,4 +233,24 @@ describe ('Importer Test', function () {
}
});
});
+
+ it ('Default color', function () {
+ let files = [
+ new FileObject ('stl', 'single_triangle.stl')
+ ];
+ let theImporter = new OV.Importer ();
+ theImporter.SetDefaultColor (new OV.Color (200, 0, 0));
+ ImportFilesWithImporter (theImporter, files, {
+ success : function (importer, importResult) {
+ assert (!OV.IsModelEmpty (importResult.model));
+ assert.deepStrictEqual (importResult.usedFiles, ['single_triangle.stl']);
+ assert.deepStrictEqual (importResult.missingFiles, []);
+ let material = importResult.model.GetMaterial (0);
+ assert.deepStrictEqual (material.diffuse, new OV.Color (200, 0, 0));
+ },
+ error : function (importer, importError) {
+ assert.fail ();
+ }
+ });
+ });
});
diff --git a/test/tests/urlutils_test.js b/test/tests/parameterlist_test.js
similarity index 71%
rename from test/tests/urlutils_test.js
rename to test/tests/parameterlist_test.js
index 6ed14e0..62fa89c 100644
--- a/test/tests/urlutils_test.js
+++ b/test/tests/parameterlist_test.js
@@ -1,22 +1,22 @@
var assert = require ('assert');
-describe ('Url Utils', function () {
- it ('Url builder', function () {
+describe ('Parameter List', function () {
+ it ('Parameter list builder', function () {
let modelUrls = ['a.txt', 'b.txt'];
let camera = new OV.Camera (
new OV.Coord3D (1.0, 1.0, 1.0),
new OV.Coord3D (0.0, 0.0, 0.0),
new OV.Coord3D (0.0, 0.0, 1.0)
);
- let urlParams1 = new OV.UrlParamBuilder ().AddModelUrls (modelUrls).GetUrlParams ();
- let urlParams2 = new OV.UrlParamBuilder ().AddCamera (camera).GetUrlParams ();
- let urlParams3 = new OV.UrlParamBuilder ().AddModelUrls (modelUrls).AddCamera (camera).GetUrlParams ();
+ let urlParams1 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).GetUrlParams ();
+ let urlParams2 = OV.CreateUrlBuilder ().AddCamera (camera).GetUrlParams ();
+ let urlParams3 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).AddCamera (camera).GetUrlParams ();
assert.strictEqual (urlParams1, 'model=a.txt,b.txt');
assert.strictEqual (urlParams2, 'camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000');
assert.strictEqual (urlParams3, 'model=a.txt,b.txt$camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000');
});
- it ('Url parser', function () {
+ it ('Parameter list parser', function () {
let modelUrls = ['a.txt', 'b.txt'];
let camera = new OV.Camera (
new OV.Coord3D (1.0, 1.0, 1.0),
@@ -27,16 +27,16 @@ describe ('Url Utils', function () {
let urlParams1 = 'model=a.txt,b.txt';
let urlParams2 = 'camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000';
let urlParams3 = 'model=a.txt,b.txt$camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000';
- let parserLegacy = new OV.UrlParamParser (urlParamsLegacy);
+ let parserLegacy = OV.CreateUrlParser (urlParamsLegacy);
assert.deepStrictEqual (parserLegacy.GetModelUrls (), modelUrls);
assert.deepStrictEqual (parserLegacy.GetCamera (), null);
- let parser1 = new OV.UrlParamParser (urlParams1);
+ let parser1 = OV.CreateUrlParser (urlParams1);
assert.deepStrictEqual (parser1.GetModelUrls (), modelUrls);
assert.deepStrictEqual (parser1.GetCamera (), null);
- let parser2 = new OV.UrlParamParser (urlParams2);
+ let parser2 = OV.CreateUrlParser (urlParams2);
assert.deepStrictEqual (parser2.GetModelUrls (), null);
assert.deepStrictEqual (parser2.GetCamera (), camera);
- let parser3 = new OV.UrlParamParser (urlParams3);
+ let parser3 = OV.CreateUrlParser (urlParams3);
assert.deepStrictEqual (parser3.GetModelUrls (), modelUrls);
assert.deepStrictEqual (parser3.GetCamera (), camera);
});
diff --git a/tools/config.json b/tools/config.json
index 722cd6b..51eac2c 100644
--- a/tools/config.json
+++ b/tools/config.json
@@ -42,11 +42,11 @@
"source/export/exporter.js",
"source/external/three.converter.js",
"source/external/three.model.loader.js",
+ "source/parameters/parameterlist.js",
"source/viewer/domutils.js",
"source/viewer/navigation.js",
"source/viewer/viewer.js",
- "source/viewer/domviewer.js",
- "source/viewer/urlutils.js"
+ "source/viewer/domviewer.js"
],
"website_files" : [
"website/o3dv/utils.js",
diff --git a/tools/create_package.py b/tools/create_package.py
index 28678f1..fc7e663 100644
--- a/tools/create_package.py
+++ b/tools/create_package.py
@@ -60,7 +60,13 @@ def CreateDestinationDir (config, rootDir, websiteDir, version, testBuild):
'o3dv/o3dv.website.min.js'
]
- for htmlFileName in ['index.html', 'embed.html', os.path.join ('info', 'index.html')]:
+ htmlFileNames = [
+ 'index.html',
+ 'embed.html',
+ os.path.join ('info', 'index.html'),
+ os.path.join ('info', 'cookies.html')
+ ]
+ for htmlFileName in htmlFileNames:
htmlFilePath = os.path.join (websiteDir, htmlFileName)
replacer = Tools.TokenReplacer (htmlFilePath, False)
replacer.ReplaceTokenFileLinks ('', '', libFiles, None)
diff --git a/tools/sandbox/embed_iframe.html b/tools/sandbox/embed_iframe.html
index 7841e2c..33ee9bf 100644
--- a/tools/sandbox/embed_iframe.html
+++ b/tools/sandbox/embed_iframe.html
@@ -2,34 +2,39 @@
-
-
-
-
- Online 3D Viewer
+
+
+
+
+ Online 3D Viewer
-
-
-
-
+
+
+
+
+
diff --git a/tools/sandbox/embed_selfhost.html b/tools/sandbox/embed_selfhost.html
deleted file mode 100644
index 5c435f0..0000000
--- a/tools/sandbox/embed_selfhost.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
- Online 3D Viewer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tools/sandbox/embed_selfhost_fullscreen.html b/tools/sandbox/embed_selfhost_fullscreen.html
new file mode 100644
index 0000000..a0c9465
--- /dev/null
+++ b/tools/sandbox/embed_selfhost_fullscreen.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+ Online 3D Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/sandbox/embed_selfhost_multiple.html b/tools/sandbox/embed_selfhost_multiple.html
new file mode 100644
index 0000000..447fa32
--- /dev/null
+++ b/tools/sandbox/embed_selfhost_multiple.html
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+ Online 3D Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/sandbox/embed_selfhost_single.html b/tools/sandbox/embed_selfhost_single.html
new file mode 100644
index 0000000..19ad383
--- /dev/null
+++ b/tools/sandbox/embed_selfhost_single.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+ Online 3D Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/update_includes.py b/tools/update_includes.py
index 3288d41..166c793 100644
--- a/tools/update_includes.py
+++ b/tools/update_includes.py
@@ -19,8 +19,12 @@ def Main (argv):
config = json.load (configJson)
rootDir = os.path.abspath ('..')
- for htmlFileName in ['index.html', 'embed.html']:
- htmlFilePath = os.path.join (rootDir, 'website', htmlFileName)
+ websiteFiles = [
+ os.path.join ('website', 'index.html'),
+ os.path.join ('website', 'embed.html')
+ ]
+ for htmlFileName in websiteFiles:
+ htmlFilePath = os.path.join (rootDir, htmlFileName)
replacer = Tools.TokenReplacer (htmlFilePath, True)
libFiles = Tools.CreateFileList (config['lib_files'], 'libs/', '../libs/')
importerFiles = Tools.CreateFileList (config['importer_files'], 'source/', '../source/')
@@ -29,6 +33,18 @@ def Main (argv):
replacer.ReplaceTokenFileLinks ('', '', importerFiles, None)
replacer.ReplaceTokenFileLinks ('', '', websiteFiles, None)
replacer.WriteToFile (htmlFilePath)
+
+ sandboxFiles = [
+ os.path.join ('tools', 'sandbox', 'embed_selfhost_single.html'),
+ os.path.join ('tools', 'sandbox', 'embed_selfhost_multiple.html'),
+ os.path.join ('tools', 'sandbox', 'embed_selfhost_fullscreen.html')
+ ]
+ for htmlFileName in sandboxFiles:
+ htmlFilePath = os.path.join (rootDir, htmlFileName)
+ replacer = Tools.TokenReplacer (htmlFilePath, True)
+ importerFiles = Tools.CreateFileList (config['importer_files'], 'source/', '../../source/')
+ replacer.ReplaceTokenFileLinks ('', '', importerFiles, None)
+ replacer.WriteToFile (htmlFilePath)
return 0
diff --git a/website/embed.html b/website/embed.html
index 1a3c815..8b6ef56 100644
--- a/website/embed.html
+++ b/website/embed.html
@@ -55,11 +55,11 @@
+
-
@@ -82,21 +82,13 @@
diff --git a/website/index.html b/website/index.html
index 064aa4d..2808d18 100644
--- a/website/index.html
+++ b/website/index.html
@@ -55,11 +55,11 @@
+
-
@@ -79,10 +79,8 @@
diff --git a/website/info/cookies.html b/website/info/cookies.html
new file mode 100644
index 0000000..a1ef165
--- /dev/null
+++ b/website/info/cookies.html
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+ Online 3D Viewer Cookies Policy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Like most similar websites, Online 3D Viewer (the "Website") uses cookies.
+ On this page we explain more about cookies and how we use them.
+
+
What are cookies?
+
+ Cookies are small text files that are stored in your web browser that allows Online 3D Viewer or a third party to recognize you.
+ Cookies can be used to collect, store and share bits of information about your activities across websites, including on
+ Online 3D Viewer Website.
+
+
+ Cookies might be used for the following purposes:
+
+
+ To provide analytics
+ To store your preferences
+
+
+ Online 3D Viewer uses both session cookies and persistent cookies.
+
+
+ A session cookie is used to identify a particular visit to our Website. These cookies expire after a short time,
+ or when you close your web browser after using our Website. We use these cookies to identify you during a single browsing session,
+ such as when you visit our Website.
+
+
+ A persistent cookie will remain on your devices for a set period of time specified in the cookie.
+ We use these cookies where we need to identify you over a longer period of time. For example,
+ we would use a persistent cookie to store your preferences on the Website.
+
+
How do third parties use cookies on the Website?
+
+ Third party companies like analytics companies use cookies to collect user information on an anonymous basis.
+ They may use that information to build a profile of your activities on the Online 3D Viewer Website and
+ other websites that you've visited.
+
+
What are your cookies options?
+
+ If you don't like the idea of cookies or certain types of cookies, you can change your browser's settings to
+ delete cookies that have already been set and to not accept new cookies. To learn more about how to do this,
+ visit the help pages of your browser.
+
+
+ Please note, however, that if you delete cookies or do not accept them, you might not be able to use all of
+ the features we offer, you may not be able to store your preferences, and some of our pages might not display properly.
+
+
+
+
+
diff --git a/website/info/index.html b/website/info/index.html
index d8f97bc..5a994b3 100644
--- a/website/info/index.html
+++ b/website/info/index.html
@@ -42,6 +42,7 @@
Self-hosted viewer
Exporting models
+ Cookies policy
@@ -225,6 +226,10 @@
After that select the format you would like to export to, and download the resulting files one by one.
+ Cookies policy
+
+ You can check the policy at the Cookies Policy page.
+