javascript - three.js 中 STL 对象的边界框

标签 javascript three.js bounding-box

大家好

我看过几篇关于这个主题的帖子,但没有解决方案。我在 three.js 中借助 STLLoader 加载了一个对象,我想为其获取一个边界框。

    // Add stl objects and a name
function addSTLObject(url, name) {
    var loader = new THREE.STLLoader();
    loader.load(url, function (geometry) {

        var material = new THREE.MeshPhongMaterial({ color: 0xff5533 });
        var mesh = new THREE.Mesh(geometry, material);
        // To scale element, use:
        // mesh.scale.set(0.01, 0.01, 0.01);
        // Add a name to the object to find it if it needs to be removed
        mesh.name = name;
        mesh.position.x = 0;
        mesh.position.y = 0;
        mesh.position.z = 0;

        scene.add(mesh);
    });
}

我正在加载这个对象如下:

addSTLObject('model/cases/iphone5.stl', 'phone-model');
var phoneModelAdded = scene.getObjectByName('phone-model', true);

现在我已经尝试了这里提供的解决方案:https://github.com/mrdoob/three.js/issues/3471在这里 Any way to get a bounding box from a three.js Object3D?

var bbox = new THREE.Box3().setFromObject(phoneModelAdded);

var geometry = phoneModel.children[0].children[0].geometry;
geometry.computeBoundingBox();

虽然第一个解决方案给我一个错误,说“无法读取未定义的属性‘updateMatrixWorld’”,但第二个解决方案没有给我任何错误,但什么都不做,如果我尝试访问“几何”属性,它说它没有不存在。

有人有可行的解决方案吗? 感谢您的帮助。

祝你有美好的一天!

编辑:

        // Add stl objects and a name
function addSTLObject(url, name) {
    var bbox;
    var loader = new THREE.STLLoader();
    loader.load(url, function (geometry) {

        var material = new THREE.MeshPhongMaterial({ color: 0xff5533 });
        var mesh = new THREE.Mesh(geometry, material);
        // To scale element, use:
        // mesh.scale.set(0.01, 0.01, 0.01);
        // Add a name to the object to find it if it needs to be removed
        mesh.name = name;
        mesh.position.x = 0;
        mesh.position.y = 0;
        mesh.position.z = 0;

        bbox = new THREE.Box3().setFromObject(mesh);

        scene.add(mesh);

        return bbox;
    });
}

之后

var bbox = addSTLObject('model/cases/iphone5.stl', 'phone-model');
    scene.add(bbox);

错误:“THREE.Object3D.add:对象不是 THREE.Object3D 的实例”

编辑 2:

var bbox, bboxComputed = false;

    function addSTLObject(url, name) {
    var bbox;
    var loader = new THREE.STLLoader();
    loader.load(url, function (geometry) {

        var material = new THREE.MeshPhongMaterial({ color: 0xff5533 });
        var mesh = new THREE.Mesh(geometry, material);
        // To scale element, use:
        // mesh.scale.set(0.01, 0.01, 0.01);
        // Add a name to the object to find it if it needs to be removed
        mesh.name = name;
        mesh.position.x = 0;
        mesh.position.y = 0;
        mesh.position.z = 0;

        bbox = new THREE.BoundingBoxHelper(mesh);
        bbox.update();
        bboxComputed = true;

        scene.add(mesh);
    });

}

addSTLObject('model/cases/iphone5.stl', 'phone-model');
    var myInterval = setInterval( function(){
        if( bboxComputed ) {
            alert( bbox.box.min, bbox.box.max, bbox.box.size() );
            scene.add(bbox);
            clearInterval( myInterval );
            bboxComputed = false;
        }
    }, 100 );

这行不通。

编辑 3: 我试图建立一个函数,它拥有我需要的一切,并返回一个包含所有计算信息的对象:

    function calculateSTLProperties(url, name) {
    var STLObject, STLbbox, STLComputed = false, STLGeometry;

    var loader = new THREE.STLLoader();
    loader.load(url, function (geometry) {

        var material = new THREE.MeshPhongMaterial({ color: 0xff5533 });
        var mesh = new THREE.Mesh(geometry, material);
        // To scale element, use:
        // mesh.scale.set(0.01, 0.01, 0.01);
        // Add a name to the object to find it if it needs to be removed
        mesh.name = name;
        mesh.position.x = 0;
        mesh.position.y = 0;
        mesh.position.z = 0;

        // Compute a bounding box for the element
        STLbbox = new THREE.BoundingBoxHelper(mesh);
        STLbbox.update();

        // Get the geometry of the case
        STLGeometry = geometry;
        STLComputed = true;
    });

    // Set an interval to wait for the corresponding bounding box and geometry to be computed
    var myInterval = setInterval( function(){
        if( STLComputed ) {
        STLObject = {
            "geometry" : STLGeometry,
            "bbox" : STLbbox,
            "x" : STLbbox.box.size().x,
            "y" : STLbbox.box.size().y,
            "z" : STLbbox.box.size().z
        };

        clearInterval( myInterval );
        bboxComputed = false;

        }
    }, 100 );

    return STLObject;
}

不幸的是,不知何故对象没有通过,我在尝试保存它时最终得到了一个“未定义”:

var STLObjectLoaded = calculateSTLProperties('model/cases/iphone5.stl', 'phone-model');
    console.log(STLObjectLoaded);

我错过了什么?

最佳答案

模型加载是异步的,因此所有计算都应该在模型加载后进行。添加一个回调,它在模型加载时调用,并在其中添加对 bbox 的调用。 scene.getObjectByName() 调用的方式是使用一个空对象进行的,您还验证了该对象(“如果我尝试访问“几何”属性,它会说它不存在” )

更新:

使用:

var bbox = new THREE.BoundingBoxHelper( mesh ); bbox.update();
scene.add( bbox );

loader.load() 函数内部。

setFromObject() 调用仅创建边界框,但不创建 bbox 的几何图形。

更新二

如果您希望 bbox 在您的 loader.load() 函数之外可用,您需要使用全局变量

var bboxComputed = false;

在计算 loader.load() 函数中的 bbox 后立即将其设置为 true:

scene.add( bbox );
bboxComputed = true;

然后在你的 main 而不是使用:

console.log( bbox.box.min, bbox.box.max, bbox.box.size() );

你会使用类似的东西:

var myInterval = setInterval( function(){
    if( bboxComputed ) {
        console.log( bbox.box.min, bbox.box.max, bbox.box.size() );
        clearInterval( myInterval );
    }
}, 100 );

我设置了 0.1 秒的延迟,当最终计算出 bbox 时,我清除了间隔,这样它就不会永远运行。

关于javascript - three.js 中 STL 对象的边界框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31809854/

相关文章:

javascript - React Horizo​​ntal Timeline distance of undefined 错误

php - Zend Ajax 提交表单

javascript - 创建一个简单的 PDF 模式

javascript - 我如何在我的 React 页面中使用 jquery/html/css 组件

javascript - 轨道控制.js : How to Zoom In/Zoom Out

javascript - 如何从一个笛卡尔坐标获得边界框?

image-processing - 使用 MATLAB 对图像进行边界框

javascript - 在 ThreeJS 中检测标签

javascript - 在 Three.js 中根据方向和相机位置旋转、移动和缩放对象

java - 碰撞检测 : What side was hit? [Java、Slick2D]