Merge branch 'dev'
This commit is contained in:
commit
040faf8ccc
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://www.paypal.com/donate?hosted_button_id=N8V9R8JFH2SE2']
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "online-3d-viewer",
|
||||
"description": "Online 3D Viewer",
|
||||
"version": "0.7.6",
|
||||
"version": "0.7.7",
|
||||
"repository": "github:kovacsv/Online3DViewer",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
||||
@ -3,7 +3,6 @@ OV.ExportedFile = class
|
||||
constructor (name)
|
||||
{
|
||||
this.name = name;
|
||||
this.url = null;
|
||||
this.content = null;
|
||||
}
|
||||
|
||||
@ -17,16 +16,6 @@ OV.ExportedFile = class
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
GetUrl ()
|
||||
{
|
||||
return this.url;
|
||||
}
|
||||
|
||||
SetUrl (url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
GetContent ()
|
||||
{
|
||||
return this.content;
|
||||
|
||||
@ -50,7 +50,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
|
||||
let textureIndex = fileNameToIndex[fileName];
|
||||
if (textureIndex === undefined) {
|
||||
let textureFile = new OV.ExportedFile (fileName);
|
||||
textureFile.SetUrl (texture.url);
|
||||
textureFile.SetContent (texture.buffer);
|
||||
files.push (textureFile);
|
||||
|
||||
textureIndex = mainJson.textures.length;
|
||||
@ -244,19 +244,10 @@ OV.ExporterGltf = class extends OV.ExporterBase
|
||||
}
|
||||
}
|
||||
|
||||
function AddBufferView (mainJson, offset, length)
|
||||
{
|
||||
mainJson.bufferViews.push ({
|
||||
buffer : 0,
|
||||
byteOffset : offset,
|
||||
byteLength : length,
|
||||
});
|
||||
return offset + length;
|
||||
}
|
||||
|
||||
let mainJson = {
|
||||
asset : {
|
||||
version : '2.0'
|
||||
version : '2.0',
|
||||
generator : 'https://3dviewer.net'
|
||||
},
|
||||
scene : 0,
|
||||
scenes : [
|
||||
|
||||
@ -25,7 +25,7 @@ OV.ExporterObj = class extends OV.ExporterBase
|
||||
});
|
||||
if (fileIndex === -1) {
|
||||
let textureFile = new OV.ExportedFile (fileName);
|
||||
textureFile.SetUrl (texture.url);
|
||||
textureFile.SetContent (texture.buffer);
|
||||
files.push (textureFile);
|
||||
}
|
||||
}
|
||||
@ -37,6 +37,7 @@ OV.ExporterObj = class extends OV.ExporterBase
|
||||
files.push (objFile);
|
||||
|
||||
let mtlWriter = new OV.TextWriter ();
|
||||
mtlWriter.WriteLine (this.GetHeaderText ());
|
||||
for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) {
|
||||
let material = model.GetMaterial (materialIndex);
|
||||
mtlWriter.WriteArrayLine (['newmtl', this.GetExportedMaterialName (material.name)]);
|
||||
@ -52,6 +53,7 @@ OV.ExporterObj = class extends OV.ExporterBase
|
||||
mtlFile.SetContent (mtlWriter.GetText ());
|
||||
|
||||
let objWriter = new OV.TextWriter ();
|
||||
objWriter.WriteLine (this.GetHeaderText ());
|
||||
objWriter.WriteArrayLine (['mtllib', mtlFile.GetName ()]);
|
||||
let vertexOffset = 0;
|
||||
let normalOffset = 0;
|
||||
@ -105,4 +107,9 @@ OV.ExporterObj = class extends OV.ExporterBase
|
||||
|
||||
objFile.SetContent (objWriter.GetText ());
|
||||
}
|
||||
|
||||
GetHeaderText ()
|
||||
{
|
||||
return '# exported by https://3dviewer.net';
|
||||
}
|
||||
};
|
||||
|
||||
21
source/external/three.model.loader.js
vendored
21
source/external/three.model.loader.js
vendored
@ -12,12 +12,7 @@ OV.ThreeModelLoader = class
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
SetDefaultColor (defaultColor)
|
||||
{
|
||||
this.importer.SetDefaultColor (defaultColor);
|
||||
}
|
||||
|
||||
LoadFromUrlList (urls)
|
||||
LoadFromUrlList (urls, settings)
|
||||
{
|
||||
if (this.inProgress) {
|
||||
return;
|
||||
@ -27,11 +22,11 @@ OV.ThreeModelLoader = class
|
||||
this.inProgress = true;
|
||||
this.callbacks.onLoadStart ();
|
||||
this.importer.LoadFilesFromUrls (urls, function () {
|
||||
obj.OnFilesLoaded ();
|
||||
obj.OnFilesLoaded (settings);
|
||||
});
|
||||
}
|
||||
|
||||
LoadFromFileList (files)
|
||||
LoadFromFileList (files, settings)
|
||||
{
|
||||
if (this.inProgress) {
|
||||
return;
|
||||
@ -41,11 +36,11 @@ OV.ThreeModelLoader = class
|
||||
this.inProgress = true;
|
||||
this.callbacks.onLoadStart ();
|
||||
this.importer.LoadFilesFromFileObjects (files, function () {
|
||||
obj.OnFilesLoaded ();
|
||||
obj.OnFilesLoaded (settings);
|
||||
});
|
||||
}
|
||||
|
||||
ReloadFiles ()
|
||||
ReloadFiles (settings)
|
||||
{
|
||||
if (this.inProgress) {
|
||||
return;
|
||||
@ -53,15 +48,15 @@ OV.ThreeModelLoader = class
|
||||
|
||||
this.inProgress = true;
|
||||
this.callbacks.onLoadStart ();
|
||||
this.OnFilesLoaded ();
|
||||
this.OnFilesLoaded (settings);
|
||||
}
|
||||
|
||||
OnFilesLoaded ()
|
||||
OnFilesLoaded (settings)
|
||||
{
|
||||
let obj = this;
|
||||
this.callbacks.onImportStart ();
|
||||
OV.RunTaskAsync (function () {
|
||||
obj.importer.Import ({
|
||||
obj.importer.Import (settings, {
|
||||
success : function (importResult) {
|
||||
obj.OnModelImported (importResult);
|
||||
},
|
||||
|
||||
@ -179,6 +179,14 @@ OV.FileList = class
|
||||
}
|
||||
};
|
||||
|
||||
OV.ImportSettings = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.defaultColor = new OV.Color (200, 200, 200);
|
||||
}
|
||||
};
|
||||
|
||||
OV.ImportErrorCode =
|
||||
{
|
||||
NoImportableFile : 1,
|
||||
@ -207,7 +215,7 @@ OV.ImportResult = class
|
||||
}
|
||||
};
|
||||
|
||||
OV.ImporterBuffers = class
|
||||
OV.ImportBuffers = class
|
||||
{
|
||||
constructor (getBufferCallback)
|
||||
{
|
||||
@ -260,7 +268,6 @@ 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 = [];
|
||||
@ -276,12 +283,7 @@ OV.Importer = class
|
||||
this.LoadFiles (fileList, OV.FileSource.File, onReady);
|
||||
}
|
||||
|
||||
SetDefaultColor (defaultColor)
|
||||
{
|
||||
this.defaultColor = defaultColor;
|
||||
}
|
||||
|
||||
Import (callbacks)
|
||||
Import (settings, callbacks)
|
||||
{
|
||||
let mainFile = this.fileList.GetMainFile ();
|
||||
if (mainFile === null || mainFile.file === null || mainFile.file.content === null) {
|
||||
@ -300,7 +302,7 @@ OV.Importer = class
|
||||
|
||||
let obj = this;
|
||||
let importer = mainFile.importer;
|
||||
let buffers = new OV.ImporterBuffers (function (fileName) {
|
||||
let buffers = new OV.ImportBuffers (function (fileName) {
|
||||
let fileBuffer = null;
|
||||
let file = obj.fileList.FindFileByPath (fileName);
|
||||
if (file === null || file.content === null) {
|
||||
@ -316,7 +318,7 @@ OV.Importer = class
|
||||
importer.Import (mainFile.file.content, mainFile.file.extension, {
|
||||
getDefaultMaterial : function () {
|
||||
let material = new OV.Material ();
|
||||
material.diffuse = obj.defaultColor;
|
||||
material.diffuse = settings.defaultColor;
|
||||
return material;
|
||||
},
|
||||
getFileBuffer : function (filePath) {
|
||||
|
||||
@ -25,23 +25,6 @@ OV.Color = class
|
||||
this.b = b; // 0 .. 255
|
||||
}
|
||||
|
||||
ToHexString ()
|
||||
{
|
||||
function IntegerToHex (intVal)
|
||||
{
|
||||
let result = parseInt (intVal, 10).toString (16);
|
||||
while (result.length < 2) {
|
||||
result = '0' + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let r = IntegerToHex (this.r);
|
||||
let g = IntegerToHex (this.g);
|
||||
let b = IntegerToHex (this.b);
|
||||
return r + g + b;
|
||||
}
|
||||
|
||||
Clone ()
|
||||
{
|
||||
return new OV.Color (this.r, this.g, this.b);
|
||||
@ -253,3 +236,37 @@ OV.Triangle = class
|
||||
return cloned;
|
||||
}
|
||||
};
|
||||
|
||||
OV.ColorToHexString = function (color)
|
||||
{
|
||||
function IntegerToHex (intVal)
|
||||
{
|
||||
let result = parseInt (intVal, 10).toString (16);
|
||||
while (result.length < 2) {
|
||||
result = '0' + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let r = IntegerToHex (color.r);
|
||||
let g = IntegerToHex (color.g);
|
||||
let b = IntegerToHex (color.b);
|
||||
return r + g + b;
|
||||
};
|
||||
|
||||
OV.HexStringToColor = function (hexString)
|
||||
{
|
||||
if (hexString.length !== 6) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let r = parseInt (hexString.substr (0, 2), 16);
|
||||
let g = parseInt (hexString.substr (2, 2), 16);
|
||||
let b = parseInt (hexString.substr (4, 2), 16);
|
||||
return new OV.Color (r, g, b);
|
||||
};
|
||||
|
||||
OV.ColorIsEqual = function (a, b)
|
||||
{
|
||||
return a.r === b.r && a.g === b.g && a.b === b.b;
|
||||
};
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
OV.ParameterConverter =
|
||||
{
|
||||
IntegerToString (integer)
|
||||
{
|
||||
return integer.toString ();
|
||||
},
|
||||
|
||||
StringToInteger (str)
|
||||
{
|
||||
return parseInt (str, 10);
|
||||
},
|
||||
|
||||
NumberToString (number)
|
||||
{
|
||||
let precision = 5;
|
||||
@ -11,6 +21,22 @@ OV.ParameterConverter =
|
||||
return parseFloat (str);
|
||||
},
|
||||
|
||||
ModelUrlsToString : function (urls)
|
||||
{
|
||||
if (urls === null) {
|
||||
return null;
|
||||
}
|
||||
return urls.join (',');
|
||||
},
|
||||
|
||||
StringToModelUrls : function (str)
|
||||
{
|
||||
if (str === null || str.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return str.split (',');
|
||||
},
|
||||
|
||||
CameraToString : function (camera)
|
||||
{
|
||||
if (camera === null) {
|
||||
@ -24,12 +50,12 @@ OV.ParameterConverter =
|
||||
return cameraParameters;
|
||||
},
|
||||
|
||||
StringToCamera : function (urlParam)
|
||||
StringToCamera : function (str)
|
||||
{
|
||||
if (urlParam === null || urlParam.length === 0) {
|
||||
if (str === null || str.length === 0) {
|
||||
return null;
|
||||
}
|
||||
let paramParts = urlParam.split (',');
|
||||
let paramParts = str.split (',');
|
||||
if (paramParts.length !== 9) {
|
||||
return null;
|
||||
}
|
||||
@ -41,20 +67,34 @@ OV.ParameterConverter =
|
||||
return camera;
|
||||
},
|
||||
|
||||
ModelUrlsToString : function (urls)
|
||||
ColorToString : function (color)
|
||||
{
|
||||
if (urls === null) {
|
||||
if (color === null) {
|
||||
return null;
|
||||
}
|
||||
return urls.join (',');
|
||||
let colorParameters = [
|
||||
this.IntegerToString (color.r),
|
||||
this.IntegerToString (color.g),
|
||||
this.IntegerToString (color.b)
|
||||
].join (',');
|
||||
return colorParameters;
|
||||
},
|
||||
|
||||
StringToModelUrls : function (urlParam)
|
||||
StringToColor : function (str)
|
||||
{
|
||||
if (urlParam === null || urlParam.length === 0) {
|
||||
if (str === null || str.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return urlParam.split (',');
|
||||
let paramParts = str.split (',');
|
||||
if (paramParts.length !== 3) {
|
||||
return null;
|
||||
}
|
||||
let color = new OV.Color (
|
||||
this.StringToInteger (paramParts[0]),
|
||||
this.StringToInteger (paramParts[1]),
|
||||
this.StringToInteger (paramParts[2])
|
||||
);
|
||||
return color;
|
||||
}
|
||||
};
|
||||
|
||||
@ -63,7 +103,7 @@ OV.ParameterListBuilder = class
|
||||
constructor (separator)
|
||||
{
|
||||
this.separator = separator;
|
||||
this.urlParams = '';
|
||||
this.paramList = '';
|
||||
}
|
||||
|
||||
AddModelUrls (urls)
|
||||
@ -78,36 +118,42 @@ OV.ParameterListBuilder = class
|
||||
return this;
|
||||
}
|
||||
|
||||
AddColor (color)
|
||||
{
|
||||
this.AddUrlPart ('color', OV.ParameterConverter.ColorToString (color));
|
||||
return this;
|
||||
}
|
||||
|
||||
AddUrlPart (keyword, urlPart)
|
||||
{
|
||||
if (keyword === null || urlPart === null) {
|
||||
return;
|
||||
}
|
||||
if (this.urlParams.length > 0) {
|
||||
this.urlParams += this.separator;
|
||||
if (this.paramList.length > 0) {
|
||||
this.paramList += this.separator;
|
||||
}
|
||||
this.urlParams += keyword + '=' + urlPart;
|
||||
this.paramList += keyword + '=' + urlPart;
|
||||
}
|
||||
|
||||
GetUrlParams ()
|
||||
GetParameterList ()
|
||||
{
|
||||
return this.urlParams;
|
||||
return this.paramList;
|
||||
}
|
||||
};
|
||||
|
||||
OV.ParameterListParser = class
|
||||
{
|
||||
constructor (urlParams, separator)
|
||||
constructor (paramList, separator)
|
||||
{
|
||||
this.separator = separator;
|
||||
this.urlParams = urlParams;
|
||||
this.paramList = paramList;
|
||||
}
|
||||
|
||||
GetModelUrls ()
|
||||
{
|
||||
// detect legacy links
|
||||
if (this.urlParams.indexOf ('=') === -1) {
|
||||
return this.urlParams.split (',');
|
||||
if (this.paramList.indexOf ('=') === -1) {
|
||||
return this.paramList.split (',');
|
||||
}
|
||||
|
||||
let keywordParams = this.GetKeywordParams ('model');
|
||||
@ -119,14 +165,20 @@ OV.ParameterListParser = class
|
||||
let keywordParams = this.GetKeywordParams ('camera');
|
||||
return OV.ParameterConverter.StringToCamera (keywordParams);
|
||||
}
|
||||
|
||||
GetColor ()
|
||||
{
|
||||
let colorParams = this.GetKeywordParams ('color');
|
||||
return OV.ParameterConverter.StringToColor (colorParams);
|
||||
}
|
||||
|
||||
GetKeywordParams (keyword)
|
||||
{
|
||||
if (this.urlParams === null || this.urlParams.length === 0) {
|
||||
if (this.paramList === null || this.paramList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
let keywordToken = keyword + '=';
|
||||
let urlParts = this.urlParams.split (this.separator);
|
||||
let urlParts = this.paramList.split (this.separator);
|
||||
for (let i = 0; i < urlParts.length; i++) {
|
||||
let urlPart = urlParts[i];
|
||||
if (urlPart.startsWith (keywordToken)) {
|
||||
@ -147,10 +199,9 @@ OV.CreateUrlParser = function (urlParams)
|
||||
return new OV.ParameterListParser (urlParams, '$');
|
||||
};
|
||||
|
||||
OV.CreateUrlParameters = function (urls, camera)
|
||||
OV.CreateModelUrlParameters = function (urls)
|
||||
{
|
||||
let builder = OV.CreateUrlBuilder ();
|
||||
builder.AddModelUrls (urls);
|
||||
builder.AddCamera (camera);
|
||||
return builder.GetUrlParams ();
|
||||
return builder.GetParameterList ();
|
||||
};
|
||||
|
||||
@ -1,19 +1,5 @@
|
||||
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');
|
||||
@ -50,7 +36,16 @@ OV.Init3DViewerElements = function ()
|
||||
return true;
|
||||
});
|
||||
viewer.AdjustClippingPlanes (boundingSphere);
|
||||
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);
|
||||
}
|
||||
viewer.FitToWindow (boundingSphere, false);
|
||||
},
|
||||
onTextureLoaded : function () {
|
||||
@ -71,7 +66,16 @@ OV.Init3DViewerElements = function ()
|
||||
return;
|
||||
}
|
||||
|
||||
loader.LoadFromUrlList (modelUrls);
|
||||
let settings = new OV.ImportSettings ();
|
||||
let colorParams = element.getAttribute ('color');
|
||||
if (colorParams) {
|
||||
let color = OV.ParameterConverter.StringToColor (colorParams);
|
||||
if (color !== null) {
|
||||
settings.defaultColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
loader.LoadFromUrlList (modelUrls, settings);
|
||||
return {
|
||||
element: element,
|
||||
viewer: viewer
|
||||
|
||||
@ -387,7 +387,7 @@ OV.Viewer = class
|
||||
this.ResizeRenderer (width, height);
|
||||
}
|
||||
this.Render ();
|
||||
let url = this.renderer.domElement.toDataURL();
|
||||
let url = this.renderer.domElement.toDataURL ();
|
||||
if (originalSize !== null) {
|
||||
this.ResizeRenderer (
|
||||
parseInt (originalSize.x, 10),
|
||||
|
||||
@ -12,15 +12,15 @@ function CreateTestModel ()
|
||||
material1.diffuseMap = new OV.TextureMap ();
|
||||
material1.diffuseMap.name = 'textures/texture1.png';
|
||||
material1.diffuseMap.url = 'texture1_url';
|
||||
material1.diffuseMap.buffer = new ArrayBuffer (4);
|
||||
material1.diffuseMap.buffer = new ArrayBuffer (1);
|
||||
material1.specularMap = new OV.TextureMap ();
|
||||
material1.specularMap.name = 'textures/texture2.png';
|
||||
material1.specularMap.url = 'texture2_url';
|
||||
material1.specularMap.buffer = new ArrayBuffer (4);
|
||||
material1.specularMap.buffer = new ArrayBuffer (2);
|
||||
material1.bumpMap = new OV.TextureMap ();
|
||||
material1.bumpMap.name = 'textures/texture3.png';
|
||||
material1.bumpMap.url = 'texture3_url';
|
||||
material1.bumpMap.buffer = new ArrayBuffer (4);
|
||||
material1.bumpMap.buffer = new ArrayBuffer (3);
|
||||
model.AddMaterial (material1);
|
||||
|
||||
let material2 = new OV.Material ();
|
||||
@ -74,6 +74,7 @@ describe ('Exporter', function () {
|
||||
assert.strictEqual (mtlFile.GetName (), 'model.mtl');
|
||||
assert.strictEqual (mtlFile.GetContent (),
|
||||
[
|
||||
'# exported by https://3dviewer.net',
|
||||
'newmtl TestMaterial1',
|
||||
'Ka 0 0 0',
|
||||
'Kd 1 0 0',
|
||||
@ -95,6 +96,7 @@ describe ('Exporter', function () {
|
||||
assert.strictEqual (objFile.GetName (), 'model.obj');
|
||||
assert.strictEqual (objFile.GetContent (),
|
||||
[
|
||||
'# exported by https://3dviewer.net',
|
||||
'mtllib model.mtl',
|
||||
'g TestMesh1',
|
||||
'v 0 0 1',
|
||||
@ -121,18 +123,15 @@ describe ('Exporter', function () {
|
||||
|
||||
let textureFile1 = result[2];
|
||||
assert.strictEqual (textureFile1.GetName (), 'texture1.png');
|
||||
assert.strictEqual (textureFile1.GetUrl (), 'texture1_url');
|
||||
assert.strictEqual (textureFile1.GetContent (), null);
|
||||
assert.strictEqual (textureFile1.GetContent ().byteLength, 1);
|
||||
|
||||
let textureFile2 = result[3];
|
||||
assert.strictEqual (textureFile2.GetName (), 'texture2.png');
|
||||
assert.strictEqual (textureFile2.GetUrl (), 'texture2_url');
|
||||
assert.strictEqual (textureFile2.GetContent (), null);
|
||||
assert.strictEqual (textureFile2.GetContent ().byteLength, 2);
|
||||
|
||||
let textureFile3 = result[4];
|
||||
assert.strictEqual (textureFile3.GetName (), 'texture3.png');
|
||||
assert.strictEqual (textureFile3.GetUrl (), 'texture3_url');
|
||||
assert.strictEqual (textureFile3.GetContent (), null);
|
||||
assert.strictEqual (textureFile3.GetContent ().byteLength, 3);
|
||||
});
|
||||
|
||||
it ('Stl Export', function () {
|
||||
@ -305,8 +304,7 @@ describe ('Exporter', function () {
|
||||
assert.strictEqual (binFile.GetName (), 'model.bin');
|
||||
|
||||
assert.strictEqual (textureFile.GetName (), 'texture1.png');
|
||||
assert.strictEqual (textureFile.GetUrl (), 'texture1_url');
|
||||
assert.strictEqual (textureFile.GetContent (), null);
|
||||
assert.strictEqual (textureFile.GetContent ().byteLength, 1);
|
||||
|
||||
let contentBuffer = gltfFile.GetContent ();
|
||||
let importer = new OV.ImporterGltf ();
|
||||
|
||||
@ -4,7 +4,8 @@ var path = require ('path');
|
||||
function ImportFilesWithImporter (importer, files, callbacks)
|
||||
{
|
||||
importer.LoadFilesFromFileObjects (files, function () {
|
||||
importer.Import ({
|
||||
let settings = new OV.ImportSettings ();
|
||||
importer.Import (settings, {
|
||||
success : function (importResult) {
|
||||
callbacks.success (importer, importResult);
|
||||
},
|
||||
@ -239,18 +240,21 @@ describe ('Importer Test', function () {
|
||||
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 ();
|
||||
}
|
||||
theImporter.LoadFilesFromFileObjects (files, function () {
|
||||
let settings = new OV.ImportSettings ();
|
||||
settings.defaultColor = new OV.Color (200, 0, 0);
|
||||
theImporter.Import (settings, {
|
||||
success : function (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 (importError) {
|
||||
assert.fail ();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -150,3 +150,19 @@ describe ('Model Finalization', function() {
|
||||
assert.strictEqual (normal.z, 0.7071067811865475);
|
||||
});
|
||||
});
|
||||
|
||||
describe ('Color Conversion', function() {
|
||||
it ('Color equality check', function () {
|
||||
assert (OV.ColorIsEqual (new OV.Color (10, 20, 30), new OV.Color (10, 20, 30)));
|
||||
assert (!OV.ColorIsEqual (new OV.Color (10, 20, 30), new OV.Color (11, 20, 30)));
|
||||
assert (!OV.ColorIsEqual (new OV.Color (10, 20, 30), new OV.Color (10, 21, 30)));
|
||||
assert (!OV.ColorIsEqual (new OV.Color (10, 20, 30), new OV.Color (10, 20, 31)));
|
||||
});
|
||||
|
||||
it ('Color hex string conversion', function () {
|
||||
let color = new OV.Color (10, 20, 30);
|
||||
let hexString = '0a141e';
|
||||
assert.strictEqual (OV.ColorToHexString (color), hexString);
|
||||
assert.deepStrictEqual (OV.HexStringToColor (hexString), color);
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,12 +8,15 @@ describe ('Parameter List', function () {
|
||||
new OV.Coord3D (0.0, 0.0, 0.0),
|
||||
new OV.Coord3D (0.0, 0.0, 1.0)
|
||||
);
|
||||
let urlParams1 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).GetUrlParams ();
|
||||
let urlParams2 = OV.CreateUrlBuilder ().AddCamera (camera).GetUrlParams ();
|
||||
let urlParams3 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).AddCamera (camera).GetUrlParams ();
|
||||
let color = new OV.Color (1, 2, 3);
|
||||
let urlParams1 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).GetParameterList ();
|
||||
let urlParams2 = OV.CreateUrlBuilder ().AddCamera (camera).GetParameterList ();
|
||||
let urlParams3 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).AddCamera (camera).GetParameterList ();
|
||||
let urlParams4 = OV.CreateUrlBuilder ().AddModelUrls (modelUrls).AddCamera (camera).AddColor (color).GetParameterList ();
|
||||
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');
|
||||
assert.strictEqual (urlParams4, 'model=a.txt,b.txt$camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000$color=1,2,3');
|
||||
});
|
||||
|
||||
it ('Parameter list parser', function () {
|
||||
@ -22,22 +25,31 @@ describe ('Parameter List', function () {
|
||||
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 color = new OV.Color (1, 2, 3);
|
||||
let urlParamsLegacy = 'a.txt,b.txt';
|
||||
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 urlParams4 = 'model=a.txt,b.txt$camera=1.0000,1.0000,1.0000,0.0000,0.0000,0.0000,0.0000,0.0000,1.0000$color=1,2,3';
|
||||
let parserLegacy = OV.CreateUrlParser (urlParamsLegacy);
|
||||
assert.deepStrictEqual (parserLegacy.GetModelUrls (), modelUrls);
|
||||
assert.deepStrictEqual (parserLegacy.GetCamera (), null);
|
||||
let parser1 = OV.CreateUrlParser (urlParams1);
|
||||
assert.deepStrictEqual (parser1.GetModelUrls (), modelUrls);
|
||||
assert.deepStrictEqual (parser1.GetCamera (), null);
|
||||
assert.deepStrictEqual (parser1.GetColor (), null);
|
||||
let parser2 = OV.CreateUrlParser (urlParams2);
|
||||
assert.deepStrictEqual (parser2.GetModelUrls (), null);
|
||||
assert.deepStrictEqual (parser2.GetCamera (), camera);
|
||||
assert.deepStrictEqual (parser2.GetColor (), null);
|
||||
let parser3 = OV.CreateUrlParser (urlParams3);
|
||||
assert.deepStrictEqual (parser3.GetModelUrls (), modelUrls);
|
||||
assert.deepStrictEqual (parser3.GetCamera (), camera);
|
||||
assert.deepStrictEqual (parser3.GetColor (), null);
|
||||
let parser4 = OV.CreateUrlParser (urlParams4);
|
||||
assert.deepStrictEqual (parser4.GetModelUrls (), modelUrls);
|
||||
assert.deepStrictEqual (parser4.GetCamera (), camera);
|
||||
assert.deepStrictEqual (parser4.GetColor (), color);
|
||||
});
|
||||
});
|
||||
|
||||
@ -52,7 +52,7 @@ module.exports =
|
||||
content = testUtils.GetArrayBufferFileContent (folder, fileName);
|
||||
}
|
||||
var extension = OV.GetFileExtension (fileName);
|
||||
let buffers = new OV.ImporterBuffers (function (filePath) {
|
||||
let buffers = new OV.ImportBuffers (function (filePath) {
|
||||
let extension = OV.GetFileExtension (filePath);
|
||||
let knownFormats = importer.GetKnownFileFormats ();
|
||||
let format = OV.FileFormat.Binary;
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
"website/o3dv/treeview.js",
|
||||
"website/o3dv/modal.js",
|
||||
"website/o3dv/dialogs.js",
|
||||
"website/o3dv/exportdialog.js",
|
||||
"website/o3dv/modeldata.js",
|
||||
"website/o3dv/info.js",
|
||||
"website/o3dv/menu.js",
|
||||
|
||||
@ -30,6 +30,16 @@
|
||||
width=360 height=240
|
||||
style="border:1px solid #eeeeee;">
|
||||
</iframe>
|
||||
<iframe
|
||||
src="../../website/embed.html#model=../test/testfiles/obj/hundred_cubes.obj"
|
||||
width=360 height=240
|
||||
style="border:1px solid #eeeeee;">
|
||||
</iframe>
|
||||
<iframe
|
||||
src="../../website/embed.html#model=../test/testfiles/obj/hundred_cubes.obj$color=200,0,0"
|
||||
width=360 height=240
|
||||
style="border:1px solid #eeeeee;">
|
||||
</iframe>
|
||||
<iframe
|
||||
src="../../website/embed.html#model=wrong.3ds"
|
||||
width=360 height=240
|
||||
|
||||
@ -89,6 +89,15 @@
|
||||
model="../../test/testfiles/obj/hundred_cubes.obj,../../test/testfiles/obj/hundred_cubes.mtl"
|
||||
camera="1,1,1,0,0,0,0,0,1">
|
||||
</div>
|
||||
<div class="online_3d_viewer"
|
||||
style="width: 360px; height: 240px;"
|
||||
model="../../test/testfiles/obj/hundred_cubes.obj">
|
||||
</div>
|
||||
<div class="online_3d_viewer"
|
||||
style="width: 360px; height: 240px;"
|
||||
model="../../test/testfiles/obj/hundred_cubes.obj"
|
||||
color="200,0,0">
|
||||
</div>
|
||||
<div class="online_3d_viewer"
|
||||
style="width: 360px; height: 240px;"
|
||||
model="wrong.3ds">
|
||||
|
||||
1
website/assets/images/toolbar/settings.svg
Normal file
1
website/assets/images/toolbar/settings.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" xml:space="preserve"><path d="m14.5 17.5 3-3m-3-3 3 3m-5.5 3-3-3m3-3-3 3M1.5 3.4v5.7l5 3 5-3V3.4L6.5.5zm5 8.7V6.2m-5-2.8 5 2.8m0 0 5-2.8" fill="none" stroke="#263238" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></svg>
|
||||
|
After Width: | Height: | Size: 304 B |
@ -68,6 +68,7 @@
|
||||
<script type="text/javascript" src="o3dv/treeview.js"></script>
|
||||
<script type="text/javascript" src="o3dv/modal.js"></script>
|
||||
<script type="text/javascript" src="o3dv/dialogs.js"></script>
|
||||
<script type="text/javascript" src="o3dv/exportdialog.js"></script>
|
||||
<script type="text/javascript" src="o3dv/modeldata.js"></script>
|
||||
<script type="text/javascript" src="o3dv/info.js"></script>
|
||||
<script type="text/javascript" src="o3dv/menu.js"></script>
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
<script type="text/javascript" src="o3dv/treeview.js"></script>
|
||||
<script type="text/javascript" src="o3dv/modal.js"></script>
|
||||
<script type="text/javascript" src="o3dv/dialogs.js"></script>
|
||||
<script type="text/javascript" src="o3dv/exportdialog.js"></script>
|
||||
<script type="text/javascript" src="o3dv/modeldata.js"></script>
|
||||
<script type="text/javascript" src="o3dv/info.js"></script>
|
||||
<script type="text/javascript" src="o3dv/menu.js"></script>
|
||||
|
||||
@ -1,135 +1,6 @@
|
||||
OV.ProgressDialog = class
|
||||
OV.FeatureSet =
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
this.modal.SetCloseable (false);
|
||||
this.imageDiv = null;
|
||||
this.textDiv = null;
|
||||
}
|
||||
|
||||
SetText (text)
|
||||
{
|
||||
this.textDiv.html (text);
|
||||
}
|
||||
|
||||
Show (text)
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_progress');
|
||||
|
||||
this.imageDiv = $('<img>').addClass ('ov_progress_img').attr ('src', 'assets/images/3dviewer_net_logo.svg').appendTo (contentDiv);
|
||||
this.textDiv = $('<div>').addClass ('ov_progress_text').appendTo (contentDiv);
|
||||
|
||||
this.SetText (text);
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ButtonDialog = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
}
|
||||
|
||||
Init (title, buttons)
|
||||
{
|
||||
function AddButton (button, buttonsDiv)
|
||||
{
|
||||
let buttonDiv = $('<div>').addClass ('ov_dialog_button').html (button.name).appendTo (buttonsDiv);
|
||||
if (button.subClass) {
|
||||
buttonDiv.addClass (button.subClass);
|
||||
}
|
||||
buttonDiv.click (function () {
|
||||
button.onClick ();
|
||||
});
|
||||
}
|
||||
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_dialog');
|
||||
|
||||
$('<div>').addClass ('ov_dialog_title').html (title).appendTo (contentDiv);
|
||||
let dialogContentDiv = $('<div>').addClass ('ov_dialog_content').appendTo (contentDiv);
|
||||
let buttonsDiv = $('<div>').addClass ('ov_dialog_buttons').appendTo (contentDiv);
|
||||
let buttonsInnerDiv = $('<div>').addClass ('ov_dialog_buttons_inner').appendTo (buttonsDiv);
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
AddButton (buttons[i], buttonsInnerDiv);
|
||||
}
|
||||
|
||||
return dialogContentDiv;
|
||||
}
|
||||
|
||||
SetCloseHandler (closeHandler)
|
||||
{
|
||||
this.modal.SetCloseHandler (closeHandler);
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ListPopup = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
this.listDiv = null;
|
||||
}
|
||||
|
||||
Init ()
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_popup');
|
||||
this.listDiv = $('<div>').addClass ('ov_popup_list').addClass ('ov_thin_scrollbar').appendTo (contentDiv);
|
||||
}
|
||||
|
||||
SetCustomResizeHandler (customResizeHandler)
|
||||
{
|
||||
this.modal.SetCustomResizeHandler (customResizeHandler);
|
||||
}
|
||||
|
||||
AddListItem (item, callbacks)
|
||||
{
|
||||
let listItemDiv = $('<div>').addClass ('ov_popup_list_item').appendTo (this.listDiv);
|
||||
if (item.color) {
|
||||
$('<div>').addClass ('ov_popup_list_item_rgbbox').css ('background', '#' + item.color).appendTo (listItemDiv);
|
||||
}
|
||||
$('<div>').addClass ('ov_popup_list_item_name').html (item.name).appendTo (listItemDiv);
|
||||
listItemDiv.click (callbacks.onClick);
|
||||
if (OV.IsHoverEnabled () && callbacks.onHoverStart && callbacks.onHoverStop) {
|
||||
listItemDiv.hover (
|
||||
function () {
|
||||
callbacks.onHoverStart ();
|
||||
},
|
||||
function () {
|
||||
callbacks.onHoverStop ();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
SetDefaultColor : false
|
||||
};
|
||||
|
||||
OV.ShowMessageDialog = function (title, message, subMessage)
|
||||
@ -206,94 +77,30 @@ OV.ShowOpenUrlDialog = function (onOk)
|
||||
return dialog;
|
||||
};
|
||||
|
||||
OV.ShowExportDialog = function (model)
|
||||
OV.ShowEmbeddingDialog = function (importer, importSettings, camera)
|
||||
{
|
||||
if (model === null) {
|
||||
return OV.ShowMessageDialog ('Export Failed', 'Please load a model to export', null);
|
||||
}
|
||||
|
||||
let dialog = new OV.ButtonDialog ();
|
||||
let contentDiv = dialog.Init ('Export', [
|
||||
{
|
||||
name : 'Close',
|
||||
onClick () {
|
||||
dialog.Hide ();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'Select a format from the below list to export your model. Please note that the export can take several second.';
|
||||
$('<div>').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
|
||||
let formats = [
|
||||
{ name : 'obj (text)', format : OV.FileFormat.Text, extension : 'obj' },
|
||||
{ name : 'stl (text)', format : OV.FileFormat.Text, extension : 'stl' },
|
||||
{ name : 'stl (binary)', format : OV.FileFormat.Binary, extension : 'stl' },
|
||||
{ name : 'ply (text)', format : OV.FileFormat.Text, extension : 'ply' },
|
||||
{ name : 'ply (binary)', format : OV.FileFormat.Binary, extension : 'ply' },
|
||||
{ name : 'gltf (text)', format : OV.FileFormat.Text, extension : 'gltf' },
|
||||
{ name : 'gltf (binary)', format : OV.FileFormat.Binary, extension : 'glb' },
|
||||
{ name : 'off (text)', format : OV.FileFormat.Text, extension : 'off' }
|
||||
];
|
||||
|
||||
let formatSelect = $('<select>').addClass ('ov_dialog_select').appendTo (contentDiv);
|
||||
$('<option>').html ('Select format').appendTo (formatSelect);
|
||||
for (let i = 0; i < formats.length; i++) {
|
||||
let format = formats[i];
|
||||
$('<option>').html (format.name).appendTo (formatSelect);
|
||||
}
|
||||
|
||||
let fileListSection = $('<div>').addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
let fileList = $('<div>').addClass ('ov_dialog_file_list').addClass ('ov_thin_scrollbar').appendTo (fileListSection);
|
||||
|
||||
let createdUrls = [];
|
||||
formatSelect.change (function () {
|
||||
fileList.empty ();
|
||||
let selectedIndex = formatSelect.prop ('selectedIndex');
|
||||
if (selectedIndex < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
let selectedFormat = formats[selectedIndex - 1];
|
||||
fileList.html ('Please wait...');
|
||||
OV.RunTaskAsync (function () {
|
||||
let exporter = new OV.Exporter ();
|
||||
let files = exporter.Export (model, selectedFormat.format, selectedFormat.extension);
|
||||
fileList.empty ();
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i];
|
||||
let url = file.GetUrl ();
|
||||
if (url === null) {
|
||||
url = OV.CreateObjectUrl (file.GetContent ());
|
||||
createdUrls.push (url);
|
||||
}
|
||||
let fileLink = $('<a>').addClass ('ov_dialog_file_link').appendTo (fileList);
|
||||
fileLink.attr ('href', url);
|
||||
fileLink.attr ('download', file.GetName ());
|
||||
$('<img>').addClass ('ov_dialog_file_link_icon').attr ('src', 'assets/images/dialog/file_download.svg').appendTo (fileLink);
|
||||
$('<div>').addClass ('ov_dialog_file_link_text').html (file.GetName ()).appendTo (fileLink);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
dialog.SetCloseHandler (function () {
|
||||
for (let i = 0; i < createdUrls.length; i++) {
|
||||
OV.RevokeObjectUrl (createdUrls[i]);
|
||||
}
|
||||
});
|
||||
dialog.Show ();
|
||||
return dialog;
|
||||
};
|
||||
|
||||
OV.ShowEmbeddingDialog = function (importer, camera)
|
||||
{
|
||||
function GetEmbeddingCode (files, camera, useCameraCheck)
|
||||
function AddCheckboxLine (parentDiv, text, onChange)
|
||||
{
|
||||
let line = $('<div>').addClass ('ov_dialog_table_row').appendTo (parentDiv);
|
||||
let check = $('<input>').attr ('type', 'checkbox').attr ('checked', 'true').appendTo (line);
|
||||
$('<span>').html (text).appendTo (line);
|
||||
check.change (function () {
|
||||
onChange (check.prop ('checked'));
|
||||
});
|
||||
}
|
||||
|
||||
function GetEmbeddingCode (params)
|
||||
{
|
||||
let builder = OV.CreateUrlBuilder ();
|
||||
builder.AddModelUrls (params.files);
|
||||
builder.AddCamera (params.camera);
|
||||
builder.AddColor (params.color);
|
||||
let hashParameters = builder.GetParameterList ();
|
||||
|
||||
let embeddingCode = '';
|
||||
embeddingCode += '<iframe';
|
||||
embeddingCode += ' width="640" height="480"';
|
||||
embeddingCode += ' style="border:1px solid #eeeeee;"';
|
||||
let hashParameters = OV.CreateUrlParameters (files, useCameraCheck.get (0).checked ? camera : null);
|
||||
embeddingCode += ' src="https://3dviewer.net/embed.html#' + hashParameters + '">';
|
||||
embeddingCode += '</iframe>';
|
||||
return embeddingCode;
|
||||
@ -314,6 +121,12 @@ OV.ShowEmbeddingDialog = function (importer, camera)
|
||||
modelFiles.push (file.fileUrl);
|
||||
}
|
||||
|
||||
let embeddingParams = {
|
||||
files : modelFiles,
|
||||
camera : camera,
|
||||
color : null
|
||||
};
|
||||
|
||||
let dialog = new OV.ButtonDialog ();
|
||||
let urlsTextArea = $('<textarea>').attr ('readonly', 'true').addClass ('ov_dialog_textarea');
|
||||
let contentDiv = dialog.Init ('Embedding', [
|
||||
@ -324,19 +137,25 @@ OV.ShowEmbeddingDialog = function (importer, camera)
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'Embedding options:';
|
||||
$('<div>').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
let optionsSection = $('<div>').addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
let useCameraLine = $('<div>').appendTo (optionsSection);
|
||||
let useCamera = $('<input>').attr ('type', 'checkbox').attr ('checked', 'true').appendTo (useCameraLine);
|
||||
$('<span>').html ('Use current camera position').appendTo (useCameraLine);
|
||||
useCamera.change (function () {
|
||||
let newEmbeddingCode = GetEmbeddingCode (modelFiles, camera, useCamera);
|
||||
urlsTextArea.val (newEmbeddingCode);
|
||||
|
||||
AddCheckboxLine (optionsSection, 'Use current camera position', function (checked) {
|
||||
embeddingParams.camera = checked ? camera : null;
|
||||
urlsTextArea.val (GetEmbeddingCode (embeddingParams));
|
||||
});
|
||||
|
||||
let embeddingCode = GetEmbeddingCode (modelFiles, camera, useCamera);
|
||||
urlsTextArea.val (embeddingCode);
|
||||
if (OV.FeatureSet.SetDefaultColor) {
|
||||
AddCheckboxLine (optionsSection, 'Use overridden default color', function (checked) {
|
||||
embeddingParams.color = checked ? importSettings.defaultColor : null;
|
||||
urlsTextArea.val (GetEmbeddingCode (embeddingParams));
|
||||
});
|
||||
embeddingParams.color = importSettings.defaultColor;
|
||||
}
|
||||
|
||||
urlsTextArea.val (GetEmbeddingCode (embeddingParams));
|
||||
|
||||
urlsTextArea.appendTo (contentDiv);
|
||||
let copyToClipboardText = 'copy to clipboard';
|
||||
@ -359,6 +178,42 @@ OV.ShowEmbeddingDialog = function (importer, camera)
|
||||
return dialog;
|
||||
};
|
||||
|
||||
OV.ShowSettingsDialog = function (importSettings, onOk)
|
||||
{
|
||||
let dialogSettings = {
|
||||
defaultColor : importSettings.defaultColor
|
||||
};
|
||||
let dialog = new OV.ButtonDialog ();
|
||||
let contentDiv = dialog.Init ('Settings', [
|
||||
{
|
||||
name : 'Cancel',
|
||||
subClass : 'outline',
|
||||
onClick () {
|
||||
dialog.Hide ();
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'OK',
|
||||
onClick () {
|
||||
dialog.Hide ();
|
||||
onOk (dialogSettings);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let colorRow = $('<div>').addClass ('ov_dialog_table_row').appendTo (contentDiv);
|
||||
$('<div>').html ('Default Color').addClass ('ov_dialog_table_row_name').appendTo (colorRow);
|
||||
let valueColumn = $('<div>').addClass ('ov_dialog_table_row_value').appendTo (colorRow);
|
||||
let colorInput = $('<input>').attr ('type', 'color').addClass ('ov_dialog_color').appendTo (valueColumn);
|
||||
colorInput.val ('#' + OV.ColorToHexString (dialogSettings.defaultColor));
|
||||
colorInput.change (function () {
|
||||
let colorStr = colorInput.val ().substr (1);
|
||||
dialogSettings.defaultColor = OV.HexStringToColor (colorStr);
|
||||
});
|
||||
dialog.Show ();
|
||||
return dialog;
|
||||
};
|
||||
|
||||
OV.ShowListPopup = function (button, items, callbacks)
|
||||
{
|
||||
let popup = new OV.ListPopup ();
|
||||
|
||||
@ -20,8 +20,13 @@ OV.Embed = class
|
||||
if (urls === null) {
|
||||
return;
|
||||
}
|
||||
this.modelLoader.LoadFromUrlList (urls);
|
||||
let hashParameters = OV.CreateUrlParameters (urls, null);
|
||||
let settings = new OV.ImportSettings ();
|
||||
let color = this.hashHandler.GetColorFromHash ();
|
||||
if (color !== null) {
|
||||
settings.defaultColor = color;
|
||||
}
|
||||
this.modelLoader.LoadFromUrlList (urls, settings);
|
||||
let hashParameters = OV.CreateModelUrlParameters (urls);
|
||||
let websiteUrl = this.parameters.websiteLinkDiv.attr ('href') + '#' + hashParameters;
|
||||
this.parameters.websiteLinkDiv.attr ('href', websiteUrl);
|
||||
}
|
||||
|
||||
191
website/o3dv/exportdialog.js
Normal file
191
website/o3dv/exportdialog.js
Normal file
@ -0,0 +1,191 @@
|
||||
OV.ExportDialog = class
|
||||
{
|
||||
constructor (callbacks)
|
||||
{
|
||||
this.callbacks = callbacks;
|
||||
this.model = null;
|
||||
this.exportFormats = [
|
||||
{
|
||||
name : 'obj',
|
||||
formats : [
|
||||
{ name : 'text', format : OV.FileFormat.Text, extension : 'obj' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'stl',
|
||||
formats : [
|
||||
{ name : 'text', format : OV.FileFormat.Text, extension : 'stl' },
|
||||
{ name : 'binary', format : OV.FileFormat.Binary, extension : 'stl' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'ply',
|
||||
formats : [
|
||||
{ name : 'text', format : OV.FileFormat.Text, extension : 'ply' },
|
||||
{ name : 'binary', format : OV.FileFormat.Binary, extension : 'ply' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'gltf',
|
||||
formats : [
|
||||
{ name : 'text', format : OV.FileFormat.Text, extension : 'gltf' },
|
||||
{ name : 'binary', format : OV.FileFormat.Binary, extension : 'glb' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'off',
|
||||
formats : [
|
||||
{ name : 'text', format : OV.FileFormat.Text, extension : 'off' }
|
||||
]
|
||||
}
|
||||
];
|
||||
this.formatParameters = {
|
||||
exportFormatButtonDivs : [],
|
||||
formatSettingsDiv : null,
|
||||
selectedFormat : null
|
||||
};
|
||||
}
|
||||
|
||||
Show (model)
|
||||
{
|
||||
if (model === null) {
|
||||
let messageDialog = OV.ShowMessageDialog (
|
||||
'Export Failed',
|
||||
'Please load a model before exporting.',
|
||||
null
|
||||
);
|
||||
this.callbacks.onDialog (messageDialog);
|
||||
return;
|
||||
}
|
||||
|
||||
let obj = this;
|
||||
let mainDialog = new OV.ButtonDialog ();
|
||||
let contentDiv = mainDialog.Init ('Export', [
|
||||
{
|
||||
name : 'Close',
|
||||
subClass : 'outline',
|
||||
onClick () {
|
||||
mainDialog.Hide ();
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'Export',
|
||||
onClick () {
|
||||
let selectedFormat = obj.formatParameters.selectedFormat;
|
||||
if (selectedFormat === null) {
|
||||
return;
|
||||
}
|
||||
mainDialog.Hide ();
|
||||
obj.ExportFormat (model);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'Select a format from the below list to export your model. Please note that the export can take several second.';
|
||||
$('<div>').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
|
||||
let buttonWidth = 40;
|
||||
let optionsHeight = 50;
|
||||
let exportFormatSelect = $('<div>').addClass ('ov_dialog_select').appendTo (contentDiv);
|
||||
this.formatParameters.formatSettingsDiv = $('<div>').addClass ('ov_dialog_section').height (optionsHeight).appendTo (contentDiv);
|
||||
for (let i = 0; i < this.exportFormats.length; i++) {
|
||||
let exportFormat = this.exportFormats[i];
|
||||
let exportFormatButton = $('<div>').addClass ('ov_dialog_select_option').html (exportFormat.name).width (buttonWidth).appendTo (exportFormatSelect);
|
||||
this.formatParameters.exportFormatButtonDivs.push (exportFormatButton);
|
||||
exportFormatButton.click (function () {
|
||||
obj.OnExportFormatSelect (i);
|
||||
});
|
||||
}
|
||||
this.OnExportFormatSelect (0);
|
||||
|
||||
mainDialog.Show ();
|
||||
this.callbacks.onDialog (mainDialog);
|
||||
}
|
||||
|
||||
OnExportFormatSelect (exportFormatIndex)
|
||||
{
|
||||
this.formatParameters.formatSettingsDiv.empty ();
|
||||
for (let i = 0; i < this.formatParameters.exportFormatButtonDivs.length; i++) {
|
||||
let exportFormatButtonDiv = this.formatParameters.exportFormatButtonDivs[i];
|
||||
if (i === exportFormatIndex) {
|
||||
exportFormatButtonDiv.addClass ('selected');
|
||||
} else {
|
||||
exportFormatButtonDiv.removeClass ('selected');
|
||||
}
|
||||
}
|
||||
|
||||
let obj = this;
|
||||
let exportFormat = this.exportFormats[exportFormatIndex];
|
||||
for (let i = 0; i < exportFormat.formats.length; i++) {
|
||||
let format = exportFormat.formats[i];
|
||||
let formatDiv = $('<div>').addClass ('ov_dialog_table_row').appendTo (this.formatParameters.formatSettingsDiv);
|
||||
let formatInput = $('<input>').addClass ('ov_dialog_table_radio').attr ('type', 'radio').attr ('id', format.name).attr ('name', 'format').appendTo (formatDiv);
|
||||
$('<label>').attr ('for', format.name).html (format.name).appendTo (formatDiv);
|
||||
if (i === 0) {
|
||||
formatInput.prop ('checked', true);
|
||||
this.formatParameters.selectedFormat = format;
|
||||
}
|
||||
formatInput.change (function () {
|
||||
obj.formatParameters.selectedFormat = format;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ExportFormat (model)
|
||||
{
|
||||
let format = this.formatParameters.selectedFormat;
|
||||
if (format === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let obj = this;
|
||||
let progressDialog = new OV.ProgressDialog ();
|
||||
progressDialog.Show ('Exporting Model');
|
||||
OV.RunTaskAsync (function () {
|
||||
let exporter = new OV.Exporter ();
|
||||
let files = exporter.Export (model, format.format, format.extension);
|
||||
if (files.length === 0) {
|
||||
progressDialog.Hide ();
|
||||
} else if (files.length === 1) {
|
||||
progressDialog.Hide ();
|
||||
let file = files[0];
|
||||
OV.DownloadArrayBufferAsFile (file.GetContent (), file.GetName ());
|
||||
} else if (files.length > 1) {
|
||||
progressDialog.Hide ();
|
||||
obj.ShowExportedFiles (files);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ShowExportedFiles (files)
|
||||
{
|
||||
let dialog = new OV.ButtonDialog ();
|
||||
let contentDiv = dialog.Init ('Exported Files', [
|
||||
{
|
||||
name : 'Close',
|
||||
onClick () {
|
||||
dialog.Hide ();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'You can download your exported files here.';
|
||||
$('<div>').html (text).addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
|
||||
let fileListSection = $('<div>').addClass ('ov_dialog_section').appendTo (contentDiv);
|
||||
let fileList = $('<div>').addClass ('ov_dialog_file_list').addClass ('ov_thin_scrollbar').appendTo (fileListSection);
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i];
|
||||
let url = OV.CreateObjectUrl (file.GetContent ());
|
||||
let fileLink = $('<a>').addClass ('ov_dialog_file_link').appendTo (fileList);
|
||||
fileLink.attr ('href', url);
|
||||
fileLink.attr ('download', file.GetName ());
|
||||
$('<img>').addClass ('ov_dialog_file_link_icon').attr ('src', 'assets/images/dialog/file_download.svg').appendTo (fileLink);
|
||||
$('<div>').addClass ('ov_dialog_file_link_text').html (file.GetName ()).appendTo (fileLink);
|
||||
}
|
||||
|
||||
dialog.Show ();
|
||||
this.callbacks.onDialog (dialog);
|
||||
}
|
||||
};
|
||||
@ -28,12 +28,6 @@ OV.HashHandler = class
|
||||
this.SetHash ('');
|
||||
}
|
||||
|
||||
GetCameraFromHash ()
|
||||
{
|
||||
let parser = OV.CreateUrlParser (this.GetHash ());
|
||||
return parser.GetCamera ();
|
||||
}
|
||||
|
||||
GetModelFilesFromHash ()
|
||||
{
|
||||
let parser = OV.CreateUrlParser (this.GetHash ());
|
||||
@ -42,10 +36,22 @@ OV.HashHandler = class
|
||||
|
||||
SetModelFilesToHash (files)
|
||||
{
|
||||
let params = OV.CreateUrlParameters (files, null);
|
||||
let params = OV.CreateModelUrlParameters (files);
|
||||
this.SetHash (params);
|
||||
}
|
||||
|
||||
GetCameraFromHash ()
|
||||
{
|
||||
let parser = OV.CreateUrlParser (this.GetHash ());
|
||||
return parser.GetCamera ();
|
||||
}
|
||||
|
||||
GetColorFromHash ()
|
||||
{
|
||||
let parser = OV.CreateUrlParser (this.GetHash ());
|
||||
return parser.GetColor ();
|
||||
}
|
||||
|
||||
GetHash ()
|
||||
{
|
||||
return window.location.hash.substr (1);
|
||||
|
||||
@ -51,7 +51,7 @@ OV.InfoPanel = class
|
||||
|
||||
let infoContainer = $('<div>').addClass ('ov_info_box').appendTo (contentDiv);
|
||||
AddRow (infoContainer, 'Color', function (valueDiv) {
|
||||
let colorString = '#' + info.diffuse.ToHexString ();
|
||||
let colorString = '#' + OV.ColorToHexString (info.diffuse);
|
||||
$('<div>').addClass ('ov_info_box_rgbbox').css ('background', colorString).attr ('title', colorString).appendTo (valueDiv);
|
||||
$('<div>').addClass ('ov_info_box_rgbtext').html (colorString).attr ('title', colorString).appendTo (valueDiv);
|
||||
});
|
||||
@ -128,7 +128,7 @@ OV.InfoPanel = class
|
||||
let materialInfo = getMaterialInfo (info.usedMaterials[i]);
|
||||
materialItems.push ({
|
||||
name : OV.GetMaterialName (materialInfo.name),
|
||||
color : materialInfo.diffuse.ToHexString ()
|
||||
color : OV.ColorToHexString (materialInfo.diffuse)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -97,3 +97,137 @@ OV.Modal = class
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OV.ProgressDialog = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
this.modal.SetCloseable (false);
|
||||
this.imageDiv = null;
|
||||
this.textDiv = null;
|
||||
}
|
||||
|
||||
SetText (text)
|
||||
{
|
||||
this.textDiv.html (text);
|
||||
}
|
||||
|
||||
Show (text)
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_progress');
|
||||
|
||||
this.imageDiv = $('<img>').addClass ('ov_progress_img').attr ('src', 'assets/images/3dviewer_net_logo.svg').appendTo (contentDiv);
|
||||
this.textDiv = $('<div>').addClass ('ov_progress_text').appendTo (contentDiv);
|
||||
|
||||
this.SetText (text);
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ButtonDialog = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
}
|
||||
|
||||
Init (title, buttons)
|
||||
{
|
||||
function AddButton (button, buttonsDiv)
|
||||
{
|
||||
let buttonDiv = $('<div>').addClass ('ov_dialog_button').html (button.name).appendTo (buttonsDiv);
|
||||
if (button.subClass) {
|
||||
buttonDiv.addClass (button.subClass);
|
||||
}
|
||||
buttonDiv.click (function () {
|
||||
button.onClick ();
|
||||
});
|
||||
}
|
||||
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_dialog');
|
||||
|
||||
$('<div>').addClass ('ov_dialog_title').html (title).appendTo (contentDiv);
|
||||
let dialogContentDiv = $('<div>').addClass ('ov_dialog_content').appendTo (contentDiv);
|
||||
let buttonsDiv = $('<div>').addClass ('ov_dialog_buttons').appendTo (contentDiv);
|
||||
let buttonsInnerDiv = $('<div>').addClass ('ov_dialog_buttons_inner').appendTo (buttonsDiv);
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
AddButton (buttons[i], buttonsInnerDiv);
|
||||
}
|
||||
|
||||
return dialogContentDiv;
|
||||
}
|
||||
|
||||
SetCloseHandler (closeHandler)
|
||||
{
|
||||
this.modal.SetCloseHandler (closeHandler);
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ListPopup = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
this.listDiv = null;
|
||||
}
|
||||
|
||||
Init ()
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_popup');
|
||||
this.listDiv = $('<div>').addClass ('ov_popup_list').addClass ('ov_thin_scrollbar').appendTo (contentDiv);
|
||||
}
|
||||
|
||||
SetCustomResizeHandler (customResizeHandler)
|
||||
{
|
||||
this.modal.SetCustomResizeHandler (customResizeHandler);
|
||||
}
|
||||
|
||||
AddListItem (item, callbacks)
|
||||
{
|
||||
let listItemDiv = $('<div>').addClass ('ov_popup_list_item').appendTo (this.listDiv);
|
||||
if (item.color) {
|
||||
$('<div>').addClass ('ov_popup_list_item_rgbbox').css ('background', '#' + item.color).appendTo (listItemDiv);
|
||||
}
|
||||
$('<div>').addClass ('ov_popup_list_item_name').html (item.name).appendTo (listItemDiv);
|
||||
listItemDiv.click (callbacks.onClick);
|
||||
if (OV.IsHoverEnabled () && callbacks.onHoverStart && callbacks.onHoverStop) {
|
||||
listItemDiv.hover (
|
||||
function () {
|
||||
callbacks.onHoverStart ();
|
||||
},
|
||||
function () {
|
||||
callbacks.onHoverStop ();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,6 +100,16 @@ OV.CopyToClipboard = function (text)
|
||||
document.body.removeChild (input);
|
||||
};
|
||||
|
||||
OV.DownloadArrayBufferAsFile = function (arrayBuffer, fileName)
|
||||
{
|
||||
let link = document.createElement ('a');
|
||||
link.href = OV.CreateObjectUrl (arrayBuffer);
|
||||
link.download = fileName;
|
||||
document.body.appendChild (link);
|
||||
link.click ();
|
||||
document.body.removeChild (link);
|
||||
};
|
||||
|
||||
OV.CreateIconButton = function (iconName, hoverIconName, title, link)
|
||||
{
|
||||
let buttonLink = $('<a>');
|
||||
|
||||
@ -449,23 +449,34 @@ div.ov_dialog textarea.ov_dialog_textarea
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.ov_dialog select.ov_dialog_select
|
||||
div.ov_dialog div.ov_dialog_select
|
||||
{
|
||||
background-image: url('../assets/images/dialog/arrow_down.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
background-position: right 10px center;
|
||||
font-size: 14px;
|
||||
margin: 10px 0px;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid #cccccc;
|
||||
margin: 20px 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_select_option
|
||||
{
|
||||
color: #3393bd;
|
||||
text-align: center;
|
||||
padding: 3px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #3393bd;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_select_option.selected
|
||||
{
|
||||
color: #ffffff;
|
||||
background: #3393bd;
|
||||
}
|
||||
|
||||
div.ov_dialog input.ov_dialog_color
|
||||
{
|
||||
width: 36px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_file_list
|
||||
@ -508,6 +519,28 @@ div.ov_dialog div.ov_dialog_inner_button
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_table_row
|
||||
{
|
||||
padding: 2px 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_table_row_name
|
||||
{
|
||||
width: 120px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_table_row_value
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog input.ov_dialog_table_radio
|
||||
{
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
div.ov_popup
|
||||
{
|
||||
background: #ffffff;
|
||||
|
||||
@ -7,6 +7,7 @@ OV.Website = class
|
||||
this.hashHandler = new OV.HashHandler ();
|
||||
this.toolbar = new OV.Toolbar (this.parameters.toolbarDiv);
|
||||
this.menu = new OV.Menu (this.parameters.menuDiv);
|
||||
this.importSettings = new OV.ImportSettings ();
|
||||
this.modelLoader = new OV.ThreeModelLoader ();
|
||||
this.highlightMaterial = new THREE.MeshPhongMaterial ({
|
||||
color : 0x8ec9f0,
|
||||
@ -154,19 +155,24 @@ OV.Website = class
|
||||
});
|
||||
}
|
||||
|
||||
LoadModelFromUrlList (urls)
|
||||
LoadModelFromUrlList (urls, settings)
|
||||
{
|
||||
this.modelLoader.LoadFromUrlList (urls);
|
||||
this.modelLoader.LoadFromUrlList (urls, settings);
|
||||
this.ClearHashIfNotOnlyUrlList ();
|
||||
}
|
||||
|
||||
LoadModelFromFileList (files)
|
||||
{
|
||||
if (files.length === 0) {
|
||||
this.modelLoader.LoadFromFileList (files, this.importSettings);
|
||||
this.ClearHashIfNotOnlyUrlList ();
|
||||
}
|
||||
|
||||
ReloadFiles ()
|
||||
{
|
||||
if (this.model === null) {
|
||||
return;
|
||||
}
|
||||
this.modelLoader.LoadFromFileList (files);
|
||||
this.ClearHashIfNotOnlyUrlList ();
|
||||
this.modelLoader.ReloadFiles (this.importSettings);
|
||||
}
|
||||
|
||||
ClearHashIfNotOnlyUrlList ()
|
||||
@ -186,7 +192,13 @@ OV.Website = class
|
||||
if (urls === null) {
|
||||
return;
|
||||
}
|
||||
this.LoadModelFromUrlList (urls);
|
||||
let settings = new OV.ImportSettings ();
|
||||
settings.defaultColor = this.importSettings.defaultColor;
|
||||
let color = this.hashHandler.GetColorFromHash ();
|
||||
if (color !== null) {
|
||||
settings.defaultColor = color;
|
||||
}
|
||||
this.LoadModelFromUrlList (urls, settings);
|
||||
} else {
|
||||
this.ClearModel ();
|
||||
this.parameters.introDiv.show ();
|
||||
@ -233,6 +245,8 @@ OV.Website = class
|
||||
}
|
||||
|
||||
let obj = this;
|
||||
let importer = this.modelLoader.GetImporter ();
|
||||
|
||||
AddButton (this.toolbar, 'open', 'Open model from your device', false, function () {
|
||||
obj.OpenFileBrowserDialog ();
|
||||
});
|
||||
@ -266,14 +280,36 @@ OV.Website = class
|
||||
});
|
||||
AddSeparator (this.toolbar, true);
|
||||
AddButton (this.toolbar, 'export', 'Export model', true, function () {
|
||||
obj.dialog = OV.ShowExportDialog (obj.model);
|
||||
});
|
||||
AddButton (this.toolbar, 'embed', 'Get embedding code', true, function () {
|
||||
obj.dialog = OV.ShowEmbeddingDialog (obj.modelLoader.GetImporter (), obj.viewer.GetCamera ());
|
||||
let exportDialog = new OV.ExportDialog ({
|
||||
onDialog : function (dialog) {
|
||||
obj.dialog = dialog;
|
||||
}
|
||||
});
|
||||
exportDialog.Show (obj.model);
|
||||
});
|
||||
AddButton (this.toolbar, 'embed', 'Get embedding code', true, function () {
|
||||
obj.dialog = OV.ShowEmbeddingDialog (importer, obj.importSettings, obj.viewer.GetCamera ());
|
||||
});
|
||||
if (OV.FeatureSet.SetDefaultColor) {
|
||||
AddSeparator (this.toolbar, true);
|
||||
AddButton (this.toolbar, 'settings', 'Settings', true, function () {
|
||||
obj.dialog = OV.ShowSettingsDialog (obj.importSettings, function (dialogSettings) {
|
||||
let reload = false;
|
||||
if (!OV.ColorIsEqual (obj.importSettings.defaultColor, dialogSettings.defaultColor)) {
|
||||
obj.importSettings.defaultColor = dialogSettings.defaultColor;
|
||||
reload = true;
|
||||
}
|
||||
if (reload) {
|
||||
obj.ReloadFiles ();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.parameters.fileInput.on ('change', function (ev) {
|
||||
obj.LoadModelFromFileList (ev.target.files);
|
||||
if (ev.target.files.length > 0) {
|
||||
obj.LoadModelFromFileList (ev.target.files);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -293,7 +329,9 @@ OV.Website = class
|
||||
window.addEventListener ('drop', function (ev) {
|
||||
ev.stopPropagation ();
|
||||
ev.preventDefault ();
|
||||
obj.LoadModelFromFileList (ev.dataTransfer.files);
|
||||
if (ev.dataTransfer.files.length > 0) {
|
||||
obj.LoadModelFromFileList (ev.dataTransfer.files);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user