Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions editor/js/Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,17 +434,37 @@ var Loader = function ( editor ) {

var contents = event.target.result;

var zip = new JSZip( contents );
var zip = new JSZip();

// BLOCKS

if ( zip.files[ 'model.obj' ] && zip.files[ 'materials.mtl' ] ) {
zip.loadAsync( contents ).then( function ( zip ) {

var materials = new THREE.MTLLoader().parse( zip.file( 'materials.mtl' ).asText() );
var object = new THREE.OBJLoader().setMaterials( materials ).parse( zip.file( 'model.obj' ).asText() );
if ( zip.files[ 'model.obj' ] && zip.files[ 'materials.mtl' ] ) {

var pendings = [];

pendings.push( zip.file( 'materials.mtl' ).async( 'text' ) );
pendings.push( zip.file( 'model.obj' ).async( 'text' ) );

// Use JSZip.external.Promise instead of global Promise for IE11 here.
// Seems JSZip.external.Promise is Promise for Promise-support browser and
// Polyfill Promise for non-Promise-support browser.
return JSZip.external.Promise.all( pendings );

}

return null;

} ).then( function ( texts ) {

if ( texts === null ) return;

var materials = new THREE.MTLLoader().parse( texts[ 0 ] );
var object = new THREE.OBJLoader().setMaterials( materials ).parse( texts[ 1 ] );
editor.execute( new AddObjectCommand( object ) );

}
} );

}, false );
reader.readAsBinaryString( file );
Expand Down
6 changes: 5 additions & 1 deletion editor/js/Menubar.File.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,11 @@ Menubar.File = function ( editor ) {

var manager = new THREE.LoadingManager( function () {

save( zip.generate( { type: 'blob' } ), ( title !== '' ? title : 'untitled' ) + '.zip' );
zip.generateAsync( { type: 'blob' } ).then( function ( blob ) {

save( blob, ( title !== '' ? title : 'untitled' ) + '.zip' );

} );

} );

Expand Down
11 changes: 6 additions & 5 deletions examples/js/libs/jszip.min.js

Large diffs are not rendered by default.

156 changes: 95 additions & 61 deletions examples/js/loaders/3MFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,34 @@ THREE.ThreeMFLoader.prototype = {
loader.setResponseType( 'arraybuffer' );
loader.load( url, function ( buffer ) {

onLoad( scope.parse( buffer ) );
scope.parse( buffer ).then( onLoad ).catch( onError );

}, onProgress, onError );

},

parse: function ( data ) {

if ( typeof JSZip === 'undefined' ) {

var error = new Error( 'THREE.ThreeMFLoader: jszip missing and file is compressed.' );

if ( typeof Promise === 'undefined' ) {

throw error;

} else {

return Promise.reject( error );

}

}

// Use JSZip.external.Promise instead of global Promise for IE11.
// Seems like JSZip.external.Promise === Promise is true on Promise support browser.
var promise = JSZip.external.Promise;

var scope = this;

function loadDocument( data ) {
Expand All @@ -47,106 +67,117 @@ THREE.ThreeMFLoader.prototype = {
var texturesParts = {};
var otherParts = {};

try {
zip = new JSZip(); // eslint-disable-line no-undef

zip = new JSZip( data ); // eslint-disable-line no-undef
return zip.loadAsync( data ).then( function ( zip ) {

} catch ( e ) {
for ( file in zip.files ) {

if ( e instanceof ReferenceError ) {
if ( file.match( /\.rels$/ ) ) {

console.error( 'THREE.ThreeMFLoader: jszip missing and file is compressed.' );
return null;
relsName = file;

}
} else if ( file.match( /^3D\/.*\.model$/ ) ) {

}
modelPartNames.push( file );

for ( file in zip.files ) {
} else if ( file.match( /^3D\/Metadata\/.*\.xml$/ ) ) {

if ( file.match( /\.rels$/ ) ) {
printTicketPartNames.push( file );

relsName = file;
} else if ( file.match( /^3D\/Textures\/.*/ ) ) {

} else if ( file.match( /^3D\/.*\.model$/ ) ) {
texturesPartNames.push( file );

modelPartNames.push( file );
} else if ( file.match( /^3D\/Other\/.*/ ) ) {

} else if ( file.match( /^3D\/Metadata\/.*\.xml$/ ) ) {
otherPartNames.push( file );

printTicketPartNames.push( file );
}

} else if ( file.match( /^3D\/Textures\/.*/ ) ) {
}

texturesPartNames.push( file );
return zip.file( relsName ).async( 'arraybuffer' );

} else if ( file.match( /^3D\/Other\/.*/ ) ) {
} ).then( function ( buffer ) {

otherPartNames.push( file );
var relsView = new Uint8Array( buffer );
var relsFileText = THREE.LoaderUtils.decodeText( relsView );
rels = parseRelsXml( relsFileText );

}
var pendings = [];

}
for ( var i = 0; i < modelPartNames.length; i ++ ) {

var relsView = new Uint8Array( zip.file( relsName ).asArrayBuffer() );
var relsFileText = THREE.LoaderUtils.decodeText( relsView );
rels = parseRelsXml( relsFileText );
var modelPart = modelPartNames[ i ];

for ( var i = 0; i < modelPartNames.length; i ++ ) {
pendings.push( zip.file( modelPart ).async( 'arraybuffer' ).then( function ( modelPart, buffer ) {

var modelPart = modelPartNames[ i ];
var view = new Uint8Array( zip.file( modelPart ).asArrayBuffer() );
var view = new Uint8Array( buffer );

var fileText = THREE.LoaderUtils.decodeText( view );
var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
var fileText = THREE.LoaderUtils.decodeText( view );
var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );

if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {

console.error( 'THREE.ThreeMFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
return promise.reject( 'THREE.ThreeMFLoader: Error loading 3MF - no 3MF document found: ' + modelPart );

}
}

var modelNode = xmlData.querySelector( 'model' );
var extensions = {};
var modelNode = xmlData.querySelector( 'model' );
var extensions = {};

for ( var i = 0; i < modelNode.attributes.length; i ++ ) {
for ( var i = 0; i < modelNode.attributes.length; i ++ ) {

var attr = modelNode.attributes[ i ];
if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
var attr = modelNode.attributes[ i ];
if ( attr.name.match( /^xmlns:(.+)$/ ) ) {

extensions[ attr.value ] = RegExp.$1;
extensions[ attr.value ] = RegExp.$1;

}
}

}
}

var modelData = parseModelNode( modelNode );
modelData[ 'xml' ] = modelNode;

if ( 0 < Object.keys( extensions ).length ) {

var modelData = parseModelNode( modelNode );
modelData[ 'xml' ] = modelNode;
modelData[ 'extensions' ] = extensions;

if ( 0 < Object.keys( extensions ).length ) {
}

modelData[ 'extensions' ] = extensions;
modelParts[ modelPart ] = modelData;

}.bind( this, modelPart ) ) );

}

modelParts[ modelPart ] = modelData;
for ( var i = 0; i < texturesPartNames.length; i ++ ) {

}
var texturesPartName = texturesPartNames[ i ];

for ( var i = 0; i < texturesPartNames.length; i ++ ) {
pendings.push( zip.file( texturesPartName ).async( 'binarystring' ).then( function ( texturesPartName, content ) {

var texturesPartName = texturesPartNames[ i ];
texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary();
texturesParts[ texturesPartName ] = content;

}
}.bind( this, texturesPartName ) ) );

return {
rels: rels,
model: modelParts,
printTicket: printTicketParts,
texture: texturesParts,
other: otherParts
};
}

return promise.all( pendings ).then( function () {

return {
rels: rels,
model: modelParts,
printTicket: printTicketParts,
texture: texturesParts,
other: otherParts
};

} );

} );

}

Expand Down Expand Up @@ -590,10 +621,13 @@ THREE.ThreeMFLoader.prototype = {

}

var data3mf = loadDocument( data );
var meshes = buildMeshes( data3mf );
return loadDocument( data ).then( function ( data3mf ) {

var meshes = buildMeshes( data3mf );

return build( meshes, data3mf[ 'rels' ], data3mf );

return build( meshes, data3mf[ 'rels' ], data3mf );
} );

},

Expand Down
Loading