Greetings to all,
I have been encountering numerous discussions on this subject, yet none of the proposed solutions seem to work for me. I am currently working with an object that is loaded using the STLLoader in three.js, and I need to obtain its bounding box.
// Function to add STL objects along with 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 the element, use:
// mesh.scale.set(0.01, 0.01, 0.01);
// Assign a name to the object for easy identification
mesh.name = name;
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
scene.add(mesh);
});
}
This is how I load the object:
addSTLObject('model/cases/iphone5.stl', 'phone-model');
var phoneModelAdded = scene.getObjectByName('phone-model', true);
I have tried implementing the solutions provided here: https://github.com/mrdoob/three.js/issues/3471 and here 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();
However, the initial solution returns an error stating "Cannot read property 'updateMatrixWorld' of undefined", while the second solution does not display any errors but does not perform as expected either. When trying to access the "geometry" property, it claims that it does not exist.
If anyone has a functional solution, I would greatly appreciate your assistance.
Wishing you a pleasant day!
UPDATE:
// Function to add STL objects along with 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 the element, use:
// mesh.scale.set(0.01, 0.01, 0.01);
// Assign a name to the object for easy identification
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;
});
}
Followed by:
var bbox = addSTLObject('model/cases/iphone5.stl', 'phone-model');
scene.add(bbox);
Error: "THREE.Object3D.add: object not an instance of THREE.Object3D"
UPDATE 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 the element, use:
// mesh.scale.set(0.01, 0.01, 0.01);
// Assign a name to the object for easy identification
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 );
This approach fails to yield the desired outcome.
UPDATE 3: I attempted to devise a function that encompasses all necessary operations and returns an object containing all pertinent information:
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 the element, use:
// mesh.scale.set(0.01, 0.01, 0.01);
// Assign a name to the object for easy identification
mesh.name = name;
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
// Compute the bounding box for the element
STLbbox = new THREE.BoundingBoxHelper(mesh);
STLbbox.update();
// Retrieve the geometry of the case
STLGeometry = geometry;
STLComputed = true;
});
// Utilize an interval to wait until the corresponding bounding box and geometry are 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;
}
Unfortunately, there seems to be an issue with passing the object through, resulting in a final output of "undefined" when attempting to save it:
var STLObjectLoaded = calculateSTLProperties('model/cases/iphone5.stl', 'phone-model');
console.log(STLObjectLoaded);
What might I be overlooking?