three.jsbuffer-geometryobjloader

Three.js - exporting scene with TextGeometry to OBJ/GLTF then load by OBJ/GLTF Loader


I have problem with import/export scenes in Three.js I have few objects (models loaded with OBJLoader, Text generated with TextGeometry). Im able to export it to string definition using OBjExporter/GLTFExporter, but when Im trying to load it again, it loads text to BufferGeometry not TextGeometry. Is it possible to load all scene meshes with proper geometries? Or maybe its possible to parse geometries? I know I can save scene without text (store text parametries in different definition then generate it again), but I would like to avoid it. Im looking forward for Your help. Thanks.

Code samples:
1. Function to export scene to OBJ

function CanvasToOBJ(callback) {

var exporter = new THREE.OBJExporter();

var options = {
    trs: false,
    onlyVisible: true,
    truncateDrawRange: true,
    binary: false,
    forceIndices: false,
    forcePowerOfTwoTextures: false,
    embedImages: true
};

var result = exporter.parse(scene);
callback(result);
exporter.parse(scene, function (result) {
    if (result instanceof ArrayBuffer) {
        callback(null);
    } else {
        var output = JSON.stringify(result, null, 2);
        callback(output);
    }
}, options);
}
  1. Function to import from OBJ string
function LoadOBJ() {
    var elem = document.getElementById("modelEditor");
    if (elem != null && elem !== "undefined" && elem.value !== "undefined" && elem.value != null && elem.value != "") {
        var gltfString = elem.value;
        var loader = new THREE.OBJLoader();
        loader.load = function load(url, localtext, onLoad, onProgress, onError) {
            var scope = this;
            var loader = new THREE.XHRLoader(scope.manager);
            loader.setPath(this.path);
            loader.load(url, function (text) {
                if (url == "") {
                    text = localtext;
                }
                onLoad(scope.parse(text));
            }, onProgress, onError);
        },

            loader.load('', gltfString, function (gltf) {

                scene = new THREE.Scene();
                scene.background = new THREE.Color(0xf0f0f0);

                scene.add(new THREE.AmbientLight(0x505050));

                var light = new THREE.SpotLight(0xffffff, 1.5);
                light.position.set(0, 500, 2000);
                light.angle = Math.PI / 9;

                light.castShadow = true;
                light.shadow.camera.near = 1000;
                light.shadow.camera.far = 4000;
                light.shadow.mapSize.width = 1024;
                light.shadow.mapSize.height = 1024;

                scene.add(light);

                var elem = gltf.children[0];
                scene.add(elem);
                objects.push(elem);
                renderer.setSize(renderer.domElement.width, renderer.domElement.height, false);
            })
    }
}


Solution

  • Answer: NO. Neither .obj nor .gltf support anything other than plain buffergeometry.

    If you want to keep everything in its original format, for a example a sphere defined by a radius and number of subdivisions rather than just a bunch of triangles, you'll need to use three.js's custom format .json format used by the three.js editor which AFAICT is undocumented.

    Unfortunately even it doesn't support any Geometry formats, only BufferGeometry formats like SphereBufferGeometry but it also doesn't currently support TextBufferGeometry though you could try to add support.

    https://github.com/mrdoob/three.js/blob/513eceb0fedfd05089168bde81c5bb85ba0e6ec1/src/loaders/ObjectLoader.js#L200

    One issue you'll need to deal with is loading and saving references to fonts.