vasturiano / 3d-force-graph

3D force-directed graph component using ThreeJS/WebGL
https://vasturiano.github.io/3d-force-graph/example/large-graph/
MIT License
4.8k stars 831 forks source link

How to load xxx.stl #441

Open lyyf2002 opened 3 years ago

lyyf2002 commented 3 years ago

I can not use a xx.stl in it.WHY? this is my code:(it can not work)

.nodeThreeObject(node=>nodePainting(node))

//this is my function
function nodePainting(node) {
    var loader = new THREE.STLLoader();
    var mesh ;
    var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
    loader.load("3dmodel/xxx.stl", function (geometry) {
        mesh = new THREE.Mesh(geometry, mat);
    });
    return mesh;
}

However,if I write like this,the nodes will be changed(but I want use xx.stl) :

.nodeThreeObject(node=>nodePainting(node))

//this is my function
function nodePainting(node) {
    //var loader = new THREE.STLLoader();   
    var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
    /*loader.load("3dmodel/xxx.stl", function (geometry) {
        var mesh = new THREE.Mesh(geometry, mat);
    });*/
        var mesh = new THREE.Mesh(new THREE.DodecahedronGeometry(Math.random() * 10),mat);
    return mesh;
}

thanks.

RaulPROP commented 3 years ago

I don't really know the problem and I can not help much without a repository that reproduced the error, but it looks like it is a promise related error. Try waiting for the loader to finish before returning the mesh.

async function nodePainting(node) {
    var loader = new THREE.STLLoader();
    var mesh ;
    var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
    await new Promise((resolve) => {
        loader.load("3dmodel/xxx.stl", async function (geometry) {
            mesh = new THREE.Mesh(geometry, mat);
            resolve();
        });
    });
    return mesh;
}
lyyf2002 commented 3 years ago

I create a repository: test_for_stl And I have use your solution in it ,but it could not work.

boostpaal commented 3 years ago

The nodeThreeObject() function doesn't accept promises, it expects a three.js object.

I thought most loaders also worked synchronously:

function nodePainting(node) {
    var loader = new THREE.STLLoader();
    var mesh ;
    var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
    var geometry = loader.load("3dmodel/xxx.stl");
        mesh = new THREE.Mesh(geometry, mat);
    return mesh;
}
lyyf2002 commented 3 years ago
function nodePainting(node) {
    var loader = new THREE.STLLoader();
    var mesh ;
    var mat = new THREE.MeshLambertMaterial({color: 0x00ffff});
    var geometry = loader.load("3dmodel/xxx.stl");
        mesh = new THREE.Mesh(geometry, mat);
    return mesh;
}

It does not work .Error:

TypeError: onLoad is not a function
    at Object.onLoad (STLLoader.js:77)
    at XMLHttpRequest.<anonymous> (three.js:26996)
(anonymous) @ STLLoader.js:87

See the code at the branch test:test

boostpaal commented 3 years ago

Under closer inspection, the STLoader does not support synchronous loading. Loaders that support synchronous loading are listed here.

Your only option is to load your geometries before you load the graph, so that they are loaded before the nodePainting() function is called.