I have some questions regarding modelBuilder and AggregateSelection.
When I load some models using scene builder, can I embed unique Id to model ? it seems the dbId is only meant for a mesh.
Is it possible to load multiple SceneBuilder models?. (not just some object in modelbuilder). I want to make a tool that can click an object and able to move it. But what happens is that all objects in the model builder moved.
addBox(dbId, position, rotation) {
this.viewer
.loadExtension("Autodesk.Viewing.SceneBuilder")
.then((builder) => {
this.sceneBuilder = builder;
return this.sceneBuilder.addNewModel({
modelNameOverride: "box",
conserveMemory: false,
});
})
.then((builder) => {
console.log("model builder created");
let modelBuilder = builder;
const box = new THREE.BoxGeometry(1, 1, 1);
const boxBuff = new THREE.BufferGeometry().fromGeometry(box);
this.box = new THREE.Mesh(boxBuff, this.globalMaterial);
this.box.dbId = dbId;
modelBuilder.addMesh(this.box);
});
}
addSphere(dbId, position, rotation) {
this.viewer
.loadExtension("Autodesk.Viewing.SceneBuilder")
.then((builder) => {
this.sceneBuilder = builder;
return this.sceneBuilder.addNewModel({
modelNameOverride: "sphere",
conserveMemory: false,
});
})
.then((builder) => {
let modelBuilder = builder;
console.log("model builder created");
let modelBuilder = builder;
const sphere = new THREE.SphereGeometry(0.5, 32, 16);
const sphereBuff = new THREE.BufferGeometry().fromGeometry(sphere);
this.sphere = new THREE.Mesh(boxBuff, this.globalMaterial);
this.sphere.dbId = dbId;
modelBuilder.addMesh(this.sphere);
});
}
There's no way to assign custom IDs to the actual model created using the SceneBuilder
extension (Forge Viewer assigns sequential numbers to all models automatically) but you can assign custom dbIDs to individual meshes exactly as you do in your code snippet, using the mesh.dbId
property.
And btw. you can easily manipulate individual meshes in the models using the ModelBuilder#changeFragmentTransform method. The following two functions insert a box and a sphere to the viewer, and each of these objects will be animated differently:
async function addBoxModel(viewer, dbid, position = new THREE.Vector3(0, 0, 0), orientation = new THREE.Quaternion(0, 0, 0, 1), scale = new THREE.Vector3(1, 1, 1)) {
const sceneBuilder = await viewer.loadExtension('Autodesk.Viewing.SceneBuilder');
const modelBuilder = await sceneBuilder.addNewModel({
modelNameOverride: 'box',
conserveMemory: false
});
const mesh = new THREE.Mesh(
new THREE.BufferGeometry().fromGeometry(new THREE.BoxGeometry(10, 10, 10)),
new THREE.MeshPhongMaterial({ color: new THREE.Color(1, 0, 0) })
);
mesh.matrix = new THREE.Matrix4().compose(position, orientation, scale);
mesh.dbId = dbid;
modelBuilder.addMesh(mesh);
// Animate the object, rotating it around the Z axis
let angle = 0;
setInterval(() => {
const offset = new THREE.Vector3(100.0 * Math.cos(angle), 100.0 * Math.sin(angle), 0.0);
const matrix = new THREE.Matrix4().compose(offset.add(position), orientation, scale);
modelBuilder.changeFragmentTransform(mesh, matrix);
viewer.impl.invalidate(true, true, true);
angle += Math.PI / 50;
}, 100);
}
async function addSphereModel(viewer, dbid, position = new THREE.Vector3(0, 0, 0), orientation = new THREE.Quaternion(0, 0, 0, 1), scale = new THREE.Vector3(1, 1, 1)) {
const sceneBuilder = await viewer.loadExtension('Autodesk.Viewing.SceneBuilder');
const modelBuilder = await sceneBuilder.addNewModel({
modelNameOverride: 'box',
conserveMemory: false
});
const mesh = new THREE.Mesh(
new THREE.BufferGeometry().fromGeometry(new THREE.SphereGeometry(10.0, 16, 16)),
new THREE.MeshPhongMaterial({ color: new THREE.Color(0, 1, 0) })
);
mesh.matrix = new THREE.Matrix4().compose(position, orientation, scale);
mesh.dbId = dbid;
modelBuilder.addMesh(mesh);
// Animate the object, rotating it around the X axis
let angle = 0;
setInterval(() => {
const offset = new THREE.Vector3(0.0, 100.0 * Math.cos(angle), 100.0 * Math.sin(angle));
const matrix = new THREE.Matrix4().compose(offset.add(position), orientation, scale);
modelBuilder.changeFragmentTransform(mesh, matrix);
viewer.impl.invalidate(true, true, true);
angle += Math.PI / 50;
}, 100);
}