2

I'm using OBJ format, but OBJ is too heavy to download it, for that reason, I would like to upload the OBJ files in Zip, then, the viewer unzip it and call the function OBJLoader. Do you know what's the best way to do it? Thanks, Rafa

Rafa
  • 21
  • 1
  • 2
  • And you want every thing to be done on the client side only or you can do something on the server side too... ??? – Shiva Nov 12 '14 at 05:32
  • In stead of messing about with .zip files in javascript, you might want to just pick a (much) more compact format than .obj to start with: http://threejs.org/examples/webgl_loader_ctm.html – Paul-Jan Nov 12 '14 at 13:13

5 Answers5

3

Problem solved by :

1) add jszip script to your page 2) Goto OBJMTLLoader.js (about line 33) and place these 10 lines to uncompress the zip (assuming that the file.zip contains only the file.obj) inside the loader.load function

loader.load( url, function ( text ) { 


                if (url.split('/').pop().split('.')[1] == 'zip'){
                //- Uncompress url e.g.  http:// .... / PTERO.zip -> PTERO.obj -

                    // zip should contain only one file !

                    // uncompression object
                    var new_zip = new JSZip(); 

                    // uncompress
                    new_zip.load(text);

                    // the single file name convention
                    filename = url.split('/').pop().split('.')[0] + ".obj";

                    // get the file content as text
                    text = new_zip.file(filename).asText();
                }
                //--------------------------------------------

                var object = scope.parse( text );

3) Add these 2 lines in the XHRLoader in Three.js so that it loads binary when extension is zip:

 THREE.XHRLoader.prototype = {

    constructor: THREE.XHRLoader,

    load: function ( url, onLoad, onProgress, onError ) {

        var scope = this;

        var cached = scope.cache.get( url );

        if ( cached !== undefined ) {

            if ( onLoad ) onLoad( cached );
            return;

        }

        var request = new XMLHttpRequest();
        request.open( 'GET', url, true );


        // ----------  for zipped obj ------------
        if ( url.split('.').pop() == 'zip')
            request.responseType = "arraybuffer";
        //--------------------------------------

        request.addEventListener( 'load', function ( event ) {

        scope.cache.add( url, this.response );

        ...
Dimitrios Ververidis
  • 1,118
  • 1
  • 9
  • 33
  • This question is over a year old... the obj to binary converter in three.js is probably better than using a zip anyway – 2pha Feb 12 '16 at 11:56
2

Beyond what is the best solution, it's really senseless that you can't pass a buffer to the loader instead of a URL. I needed that too, so I used @jimver's answer but changing the JSZip methods because they were deprecated. Use this instead (in my case I made the changes on file STLLoader.js because I was working with STL files, but this applies to any loader):

THREE.STLLoader.prototype = {

constructor: THREE.STLLoader,

load: function ( url, onLoad, onProgress, onError ) {

    var scope = this;

    var loader = new THREE.XHRLoader( scope.manager );
    loader.setResponseType( 'arraybuffer' );
    loader.load( url, function ( text ) {

        if (url.split('/').pop().split('.')[1] == 'zip') {
                JSZip.loadAsync(text)
                .then(function (zip) {
                    return zip.file(Object.keys(zip.files)[0]).async("arrayBuffer");
                })
                .then(function success(text) {
                        onLoad( scope.parse( text ) );
                    }, function error(e) {
                        console.log(e);
                });
        }
        else {
            onLoad( scope.parse( text ) );
        }

    }, onProgress, onError );
},

// rest of the code
fsinisi90
  • 1,138
  • 1
  • 16
  • 45
1

I would try using jszip

JSZipUtils.getBinaryContent('path/to/objzipped.zip', function(err, data) { 
  if(err) {
    throw err; // or handle err
  }
  var zip = new JSZip(data);
  var objData = zip.file("objfile.obj").asText();
  var object3D = new OBJLoader().parse(objData); // ...
});
jrbedard
  • 3,662
  • 5
  • 30
  • 34
0

In case you really want to use zip in the browser,

I think you could go with unzip a downloaded file with zip.js and parse the result with OLBJLoader.parse.

vincent
  • 1,525
  • 12
  • 18
0

Decoding gzip is built into the browsers. You dont need any client side code at all. All you need to do is make sure the server is setting the right MIME type. See: What 'Content-Type' header to use when serving gzipped files?

Community
  • 1
  • 1
fluffybunny
  • 496
  • 3
  • 8