You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Autodesk Forge Viewer:如何隔离自定义对象?

Solution: Isolating Custom IFC Room Objects in Forge Viewer

Got it, let's break down why your custom room objects aren't responding to the viewer.isolate() call—even though you can select them and get their DbIds correctly. The core issue here is that simply setting a DbId on your fragments doesn't register those objects with the Viewer's InstanceTree (the structure that powers selection, isolation, and other scene navigation features). Here's how to fix it:

Why the Current Approaches Aren't Working

When you use modelBuilder.changeFragmentsDbId(), you're only updating the DbId stored on the fragment itself. But the Viewer's isolate() method relies on the InstanceTree to locate and manipulate objects. If your custom DbIds (whether negative or above the max existing) aren't registered in the InstanceTree, the Viewer can't find them to isolate.

The selection event works because it directly reads the DbId from the clicked fragment, bypassing the InstanceTree check for that step.

Step-by-Step Fix

1. Use Positive DbIds (Avoid Negative Values)

Viewer's internal logic is optimized for positive DbIds (since native IFC models always use positive integers). Negative DbIds might get filtered out during operations like isolation, so stick with the "above max existing DbId" approach.

2. Get the Real Max DbId from the InstanceTree

First, correctly fetch the highest DbId used by the original model. Don't rely on a hardcoded value—use the InstanceTree to enumerate all nodes:

function getMaxDbId(model) {
    let maxDbId = 0;
    const instanceTree = model.getInstanceTree();
    // Enumerate all nodes starting from the root
    instanceTree.enumNodeChildren(instanceTree.getRootId(), (dbId) => {
        if (dbId > maxDbId) maxDbId = dbId;
    }, true); // true = include nested children
    return maxDbId;
}

3. Register Custom DbIds in the InstanceTree

After setting the fragment's DbId, create a corresponding node in the InstanceTree and refresh it. This tells the Viewer about your custom objects:

// Get the model and max DbId
const model = this.viewer.model;
const maxDbId = getMaxDbId(model);

// Add your room fragment as before
const roomFragId = this.modelBuilder.addFragment(roomGeometryId, materialName, transform);
const customDbId = maxDbId + roomFragId;
this.modelBuilder.changeFragmentsDbId(roomFragId, customDbId);

// Register the custom DbId in the InstanceTree
const instanceTree = model.getInstanceTree();
// Create a new node: (dbId, parentDbId, nodeName, isLeaf)
instanceTree.createNode(customDbId, instanceTree.getRootId(), `Custom Room ${customDbId}`, true);

// Refresh the InstanceTree and notify the Viewer to update
instanceTree.refresh();
this.viewer.impl.invalidate(true); // Force a scene redraw

4. Test the Isolate Call

Now when you call viewer.isolate(customDbId), the Viewer will find the registered node in the InstanceTree and isolate your custom room object correctly.

Additional Checks

  • Ensure your custom fragments are fully added to the scene before calling isolate(). You can listen for the geometry.loaded event from the ModelBuilder to confirm.
  • Verify the DbId exists in the InstanceTree with model.getInstanceTree().containsDbId(customDbId) before calling isolate.

内容的提问来源于stack exchange,提问作者Toni Maccheroni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:32:36