如何将唯一 ID 嵌入模型构建器并加载多个模型?

How to embed unique Id to modelBuilder and load multiple model?

我有一些关于 modelBuilder 和 AggregateSelection 的问题。

  1. 当我使用场景构建器加载一些模型时,我可以将唯一 ID 嵌入到模型中吗? dbId 似乎只适用于网格。

  2. 是否可以加载多个SceneBuilder模型?. (不仅仅是模型构建器中的一些对象)。我想制作一个可以单击对象并能够移动它的工具。但是发生的是模型构建器中的所有对象都移动了。

     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);
       });
    

    }

根据用于生成 Forge 模型的种子 CAD 软件,externalId 属性 可能已经包含合适的唯一 ID。

Unique IDs for Forge Viewer Elements 上的文章从 Revit 的角度对此进行了解释。

无法将自定义 ID 分配给使用 SceneBuilder 扩展创建的实际 模型 (Forge Viewer 会自动为所有模型分配序列号),但您可以分配使用 mesh.dbId 属性.

完全按照您在代码片段中所做的那样,为单个 meshes 自定义 dbID

顺便说一句。您可以使用 ModelBuilder#changeFragmentTransform 方法轻松操作模型中的单个网格。以下两个函数向查看器插入一个长方体和一个球体,这些对象中的每一个都将以不同的方式进行动画处理:

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);
}