Introduce InputFile class that can specify the name and the url as well (#202).

This commit is contained in:
kovacsv 2022-06-05 14:44:05 +02:00
parent eca3d88982
commit 316c8e7293
16 changed files with 1766 additions and 82 deletions

View File

@ -63,7 +63,7 @@
});
// load a model providing model urls
viewer.LoadModelFromUrls ([
viewer.LoadModelFromUrlList ([
'../../test/testfiles/obj/hundred_cubes.obj',
'../../test/testfiles/obj/hundred_cubes.mtl'
]);

View File

@ -52,7 +52,7 @@
});
// load a model providing model urls
viewer.LoadModelFromUrls ([
viewer.LoadModelFromUrlList ([
'../../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb'
]);
});

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<title>Online 3D Viewer</title>
<script type="text/javascript" src="../build/o3dv.min-dev.js"></script>
<style>
div.online_3d_viewer
{
float: left;
border: 1px solid #eeeeee;
width: 640px;
height: 480px;
}
</style>
<script type='text/javascript'>
window.addEventListener ('load', () => {
// get the parent element of the viewer
let parentDiv = document.getElementById ('viewer');
// initialize the viewer with the parent element and some parameters
let viewer = new OV.EmbeddedViewer (parentDiv, {
camera : new OV.Camera (
new OV.Coord3D (-1.5, 2.0, 3.0),
new OV.Coord3D (0.0, 0.0, 0.0),
new OV.Coord3D (0.0, 1.0, 0.0)
)
});
// load a model providing model urls
let inputFiles = [
new OV.InputFile ('hundred_cubes.obj', OV.FileSource.Url, '../../test/testfiles/obj/hundred_cubes_noext_obj'),
new OV.InputFile ('hundred_cubes.mtl', OV.FileSource.Url, '../../test/testfiles/obj/hundred_cubes_noext_mtl')
];
viewer.LoadModelFromInputFiles (inputFiles);
});
</script>
</head>
<body>
<div class="online_3d_viewer" id="viewer"></div>
<div id="calculation_result"></div>
</body>
</html>

View File

@ -1,27 +1,44 @@
import { RunTasks } from '../core/taskrunner.js';
import { FileFormat, FileSource, GetFileExtension, GetFileName, ReadFile, RequestUrl } from '../io/fileutils.js';
export class File
export class InputFile
{
constructor (file, source)
constructor (name, source, data)
{
this.name = name;
this.source = source;
if (source === FileSource.Url) {
this.fileUrl = file;
this.fileObject = null;
this.name = GetFileName (file);
this.extension = GetFileExtension (file);
} else if (source === FileSource.File) {
this.fileUrl = null;
this.fileObject = file;
this.name = GetFileName (file.name);
this.extension = GetFileExtension (file.name);
} else if (source === FileSource.Decompressed) {
this.fileUrl = null;
this.fileObject = null;
this.name = GetFileName (file);
this.extension = GetFileExtension (file);
}
this.data = data;
}
}
export function InputFilesFromUrls (urls)
{
let inputFiles = [];
for (let url of urls) {
let fileName = GetFileName (url);
inputFiles.push (new InputFile (fileName, FileSource.Url, url));
}
return inputFiles;
}
export function InputFilesFromFileObjects (fileObjects)
{
let inputFiles = [];
for (let fileObject of fileObjects) {
let fileName = GetFileName (fileObject.name);
inputFiles.push (new InputFile (fileName, FileSource.File, fileObject));
}
return inputFiles;
}
export class ImporterFile
{
constructor (name, source, data)
{
this.name = GetFileName (name);
this.extension = GetFileExtension (name);
this.source = source;
this.data = data;
this.content = null;
}
@ -31,25 +48,25 @@ export class File
}
}
export class FileList
export class ImporterFileList
{
constructor ()
{
this.files = [];
}
FillFromFileUrls (fileList)
FillFromInputFiles (inputFiles)
{
this.Fill (fileList, FileSource.Url);
this.files = [];
for (let inputFile of inputFiles) {
let file = new ImporterFile (inputFile.name, inputFile.source, inputFile.data);
this.files.push (file);
}
}
FillFromFileObjects (fileList)
{
this.Fill (fileList, FileSource.File);
}
ExtendFromFileList (files)
ExtendFromFileList (fileList)
{
let files = fileList.GetFiles ();
for (let i = 0; i < files.length; i++) {
let file = files[i];
if (!this.ContainsFileByPath (file.name)) {
@ -104,16 +121,6 @@ export class FileList
return true;
}
Fill (fileList, fileSource)
{
this.files = [];
for (let fileIndex = 0; fileIndex < fileList.length; fileIndex++) {
let fileObject = fileList[fileIndex];
let file = new File (fileObject, fileSource);
this.AddFile (file);
}
}
AddFile (file)
{
this.files.push (file);
@ -127,9 +134,9 @@ export class FileList
}
let loaderPromise = null;
if (file.source === FileSource.Url) {
loaderPromise = RequestUrl (file.fileUrl, FileFormat.Binary);
loaderPromise = RequestUrl (file.data, FileFormat.Binary);
} else if (file.source === FileSource.File) {
loaderPromise = ReadFile (file.fileObject, FileFormat.Binary);
loaderPromise = ReadFile (file.data, FileFormat.Binary);
} else {
complete ();
return;

View File

@ -1,7 +1,7 @@
import { RunTaskAsync } from '../core/taskrunner.js';
import { FileSource, GetFileName } from '../io/fileutils.js';
import { Color } from '../model/color.js';
import { File, FileList } from './filelist.js';
import { ImporterFile, ImporterFileList } from './filelist.js';
import { Importer3dm } from './importer3dm.js';
import { Importer3ds } from './importer3ds.js';
import { ImporterGltf } from './importergltf.js';
@ -96,7 +96,7 @@ export class Importer
new ImporterThreeWrl (),
new ImporterThree3mf ()
];
this.fileList = new FileList ();
this.fileList = new ImporterFileList ();
this.model = null;
this.usedFiles = [];
this.missingFiles = [];
@ -107,9 +107,9 @@ export class Importer
this.importers.push (importer);
}
ImportFiles (fileList, fileSource, settings, callbacks)
ImportFiles (inputFiles, settings, callbacks)
{
this.LoadFiles (fileList, fileSource, () => {
this.LoadFiles (inputFiles, () => {
callbacks.onFilesLoaded ();
RunTaskAsync (() => {
this.ImportLoadedFiles (settings, callbacks);
@ -117,14 +117,11 @@ export class Importer
});
}
LoadFiles (fileList, fileSource, onReady)
LoadFiles (inputFiles, onReady)
{
let newFileList = new FileList ();
if (fileSource === FileSource.Url) {
newFileList.FillFromFileUrls (fileList);
} else if (fileSource === FileSource.File) {
newFileList.FillFromFileObjects (fileList);
}
let newFileList = new ImporterFileList ();
newFileList.FillFromInputFiles (inputFiles);
let reset = false;
if (this.HasImportableFile (newFileList)) {
reset = true;
@ -139,8 +136,7 @@ export class Importer
if (!foundMissingFile) {
reset = true;
} else {
let newFiles = newFileList.GetFiles ();
this.fileList.ExtendFromFileList (newFiles);
this.fileList.ExtendFromFileList (newFileList);
reset = false;
}
}
@ -258,7 +254,7 @@ export class Importer
const decompressed = fflate.unzipSync (archiveBuffer);
for (const fileName in decompressed) {
if (Object.prototype.hasOwnProperty.call (decompressed, fileName)) {
let file = new File (fileName, FileSource.Decompressed);
let file = new ImporterFile (fileName, FileSource.Decompressed, null);
file.SetContent (decompressed[fileName].buffer);
fileList.AddFile (file);
}

View File

@ -20,7 +20,7 @@ import { OctreeNode, Octree } from './geometry/octree.js';
import { Quaternion, QuaternionIsEqual, ArrayToQuaternion, QuaternionFromAxisAngle, QuaternionFromXYZ } from './geometry/quaternion.js';
import { Transformation, TransformationIsEqual } from './geometry/transformation.js';
import { BezierTweenFunction, LinearTweenFunction, ParabolicTweenFunction, TweenCoord3D } from './geometry/tween.js';
import { File, FileList } from './import/filelist.js';
import { InputFile, ImporterFile, ImporterFileList, InputFilesFromUrls, InputFilesFromFileObjects } from './import/filelist.js';
import { ImportSettings, ImportError, ImportResult, ImporterFileAccessor, Importer, ImportErrorCode } from './import/importer.js';
import { Importer3dm } from './import/importer3dm.js';
import { Importer3ds } from './import/importer3ds.js';
@ -140,8 +140,11 @@ export {
LinearTweenFunction,
ParabolicTweenFunction,
TweenCoord3D,
File,
FileList,
InputFile,
ImporterFile,
ImporterFileList,
InputFilesFromUrls,
InputFilesFromFileObjects,
ImportSettings,
ImportError,
ImportResult,

View File

@ -22,7 +22,7 @@ export class ThreeModelLoader
return this.inProgress;
}
LoadModel (files, fileSource, settings, callbacks)
LoadModel (inputFiles, settings, callbacks)
{
if (this.inProgress) {
return;
@ -31,7 +31,7 @@ export class ThreeModelLoader
this.inProgress = true;
callbacks.onLoadStart ();
this.RevokeObjectUrls ();
this.importer.ImportFiles (files, fileSource, settings, {
this.importer.ImportFiles (inputFiles, settings, {
onFilesLoaded : () => {
callbacks.onImportStart ();
},

View File

@ -1,7 +1,8 @@
import { IsDefined } from '../core/core.js';
import { Direction } from '../geometry/geometry.js';
import { InputFilesFromFileObjects, InputFilesFromUrls } from '../import/filelist.js';
import { ImportErrorCode, ImportSettings } from '../import/importer.js';
import { FileSource, TransformFileHostUrls } from '../io/fileutils.js';
import { TransformFileHostUrls } from '../io/fileutils.js';
import { ParameterConverter } from '../parameters/parameterlist.js';
import { ThreeModelLoader } from '../threejs/threemodelloader.js';
import { Viewer } from './viewer.js';
@ -51,20 +52,22 @@ export class EmbeddedViewer
});
}
LoadModelFromUrls (modelUrls)
LoadModelFromUrlList (modelUrls)
{
TransformFileHostUrls (modelUrls);
this.LoadModelInternal (modelUrls, FileSource.Url);
let inputFiles = InputFilesFromUrls (modelUrls);
this.LoadModelFromInputFiles (inputFiles);
}
LoadModelFromFileList (fileList)
{
this.LoadModelInternal (fileList, FileSource.File);
let inputFiles = InputFilesFromFileObjects (fileList);
this.LoadModelFromInputFiles (inputFiles);
}
LoadModelInternal (fileList, fileSource)
LoadModelFromInputFiles (inputFiles)
{
if (fileList === null || fileList.length === 0) {
if (inputFiles === null || inputFiles.length === 0) {
return null;
}
@ -77,7 +80,7 @@ export class EmbeddedViewer
this.model = null;
let progressDiv = null;
let loader = new ThreeModelLoader ();
loader.LoadModel (fileList, fileSource, settings, {
loader.LoadModel (inputFiles, settings, {
onLoadStart : () => {
this.canvas.style.display = 'none';
progressDiv = document.createElement ('div');
@ -151,7 +154,7 @@ export class EmbeddedViewer
export function Init3DViewerElement (parentElement, modelUrls, parameters)
{
let viewer = new EmbeddedViewer (parentElement, parameters);
viewer.LoadModelFromUrls (modelUrls);
viewer.LoadModelFromUrlList (modelUrls);
return viewer;
}

View File

@ -1,5 +1,5 @@
import { CreateModelUrlParameters } from '../engine/parameters/parameterlist.js';
import { FileSource, TransformFileHostUrls } from '../engine/io/fileutils.js';
import { TransformFileHostUrls } from '../engine/io/fileutils.js';
import { ImportSettings } from '../engine/import/importer.js';
import { AddDomElement } from '../engine/viewer/domutils.js';
import { Viewer } from '../engine/viewer/viewer.js';
@ -7,6 +7,7 @@ import { HashHandler } from './hashhandler.js';
import { ThreeModelLoaderUI } from './threemodelloaderui.js';
import { Direction } from '../engine/geometry/geometry.js';
import { HandleEvent } from './eventhandler.js';
import { InputFilesFromUrls } from '../engine/import/filelist.js';
export class Embed
{
@ -66,7 +67,8 @@ export class Embed
if (defaultColor !== null) {
settings.defaultColor = defaultColor;
}
this.modelLoaderUI.LoadModel (urls, FileSource.Url, settings, {
let inputFiles = InputFilesFromUrls (urls);
this.modelLoaderUI.LoadModel (inputFiles, settings, {
onStart : () =>
{

View File

@ -118,7 +118,7 @@ export function ShowSharingDialog (fileList, settings, camera)
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
let file = files[fileIndex];
if (file.source === FileSource.Url) {
modelFiles.push (file.fileUrl);
modelFiles.push (file.data);
}
}

View File

@ -13,14 +13,14 @@ export class ThreeModelLoaderUI
this.modalDialog = null;
}
LoadModel (files, fileSource, settings, callbacks)
LoadModel (inputFiles, settings, callbacks)
{
if (this.modelLoader.InProgress ()) {
return;
}
let progressDialog = null;
this.modelLoader.LoadModel (files, fileSource, settings, {
this.modelLoader.LoadModel (inputFiles, settings, {
onLoadStart : () => {
this.CloseDialogIfOpen ();
callbacks.onStart ();

View File

@ -1,4 +1,5 @@
import { FileSource, GetFileExtension, TransformFileHostUrls } from '../engine/io/fileutils.js';
import { GetFileExtension, TransformFileHostUrls } from '../engine/io/fileutils.js';
import { InputFilesFromFileObjects, InputFilesFromUrls } from '../engine/import/filelist.js';
import { ImportErrorCode, ImportSettings } from '../engine/import/importer.js';
import { Viewer } from '../engine/viewer/viewer.js';
import { AddDiv, AddDomElement, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js';
@ -358,7 +359,8 @@ export class Website
LoadModelFromUrlList (urls, settings)
{
this.LoadModel (urls, FileSource.Url, settings);
let inputFiles = InputFilesFromUrls (urls);
this.LoadModelFromInputFiles (inputFiles, settings);
this.ClearHashIfNotOnlyUrlList ();
}
@ -366,13 +368,14 @@ export class Website
{
let importSettings = new ImportSettings ();
importSettings.defaultColor = this.settings.defaultColor;
this.LoadModel (files, FileSource.File, importSettings);
let inputFiles = InputFilesFromFileObjects (files);
this.LoadModelFromInputFiles (inputFiles, importSettings);
this.ClearHashIfNotOnlyUrlList ();
}
LoadModel (files, fileSource, settings)
LoadModelFromInputFiles (files, settings)
{
this.modelLoaderUI.LoadModel (files, fileSource, settings, {
this.modelLoaderUI.LoadModel (files, settings, {
onStart : () =>
{
this.SetUIState (WebsiteUIState.Loading);

View File

@ -0,0 +1,14 @@
newmtl Red
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.200000 0.200000
Ks 0.500000 0.500000 0.500000
newmtl Green
Ka 0.000000 0.000000 0.000000
Kd 0.152940 0.607840 0.380390
Ks 0.500000 0.500000 0.500000
newmtl Blue
Ka 0.000000 0.000000 0.000000
Kd 0.000000 0.541180 0.721570
Ks 0.500000 0.500000 0.500000

File diff suppressed because it is too large Load Diff

View File

@ -116,8 +116,8 @@ function ExportImport (model, format, extension, onReady)
onSuccess : function (exportedFiles) {
let importer = new OV.Importer ();
let settings = new OV.ImportSettings ();
let fileObjects = exportedFiles.map (file => new FileObject ('', file.name, file.content));
importer.ImportFiles (fileObjects, OV.FileSource.File, settings, {
let fileObjects = exportedFiles.map (file => new OV.InputFile (file.name, OV.FileSource.File, new FileObject ('', file.name, file.content)));
importer.ImportFiles (fileObjects, settings, {
onFilesLoaded : function () {
},

View File

@ -7,7 +7,8 @@ export default function suite ()
function ImportFilesWithImporter (importer, files, callbacks)
{
let settings = new OV.ImportSettings ();
importer.ImportFiles (files, OV.FileSource.File, settings, {
let inputFiles = OV.InputFilesFromFileObjects (files);
importer.ImportFiles (inputFiles, settings, {
onFilesLoaded : function () {
},
@ -259,7 +260,8 @@ describe ('Importer Test', function () {
let theImporter = new OV.Importer ();
let settings = new OV.ImportSettings ();
settings.defaultColor = new OV.Color (200, 0, 0);
theImporter.ImportFiles (files, OV.FileSource.File, settings, {
let inputFiles = OV.InputFilesFromFileObjects (files);
theImporter.ImportFiles (inputFiles, settings, {
onFilesLoaded : function () {
},