Xeokit TreeViewPlugin与GLB模型交互异常问题排查
问题诊断与修复方案
核心问题分析
- 勾选无反应:你仅监听了
nodeTitleClicked事件,但TreeView的勾选/取消勾选操作触发的是nodeToggled事件,未处理该事件自然不会产生任何反馈。 - 默认未勾选:TreeView节点的勾选状态与模型对象的
visible属性同步,若节点未默认勾选,要么是加载模型时对象未设为可见,要么是metaModelSrc指向的元模型文件不存在/格式错误,导致TreeView无法正确关联对象ID。
修复步骤
1. 移除无效的metaModelSrc参数
如果没有为GLB文件生成对应的元模型JSON文件,加载时不要指定metaModelSrc,xeokit会自动从GLB中解析层级结构:
gltfLoader.load({ id: "myModel", src: src, edges: true, excludeUnclassifiedObjects: false });
2. 监听nodeToggled事件实现勾选控制
添加nodeToggled事件监听,根据节点的勾选状态切换对应对象的可见性:
treeView.on("nodeToggled", (e) => { const objectIds = []; e.treeViewPlugin.withNodeTree(e.treeViewNode, (treeViewNode) => { if (treeViewNode.objectId) { objectIds.push(treeViewNode.objectId); } }); viewer.scene.setObjectsVisible(objectIds, e.treeViewNode.checked); });
3. 确保模型对象默认可见(可选)
如果加载后对象仍未默认可见,可以在loaded事件中手动设置所有对象可见,确保TreeView节点同步勾选状态:
gltfLoader.on("loaded", (model) => { treeView.setModel(model); // 强制设置所有对象可见,同步TreeView勾选状态 viewer.scene.setObjectsVisible(model.objectIds, true); });
完整修改后的main.js关键部分
// ... 其他代码保持不变 ... const treeView = new TreeViewPlugin(viewer, { containerElement: document.getElementById("treeViewContainer"), autoExpandDepth: 3, hierarchy: "containment" }); // 保留原有节点标题点击逻辑 treeView.on("nodeTitleClicked", (e) => { const scene = viewer.scene; const objectIds = []; e.treeViewPlugin.withNodeTree(e.treeViewNode, (treeViewNode) => { if (treeViewNode.objectId) { objectIds.push(treeViewNode.objectId); } }); e.treeViewPlugin.unShowNode(); scene.setObjectsXRayed(scene.objectIds, true); scene.setObjectsVisible(scene.objectIds, true); scene.setObjectsXRayed(objectIds, false); viewer.cameraFlight.flyTo({ aabb: scene.getAABB(objectIds), duration: 0.5 }, () => { setTimeout(function () { scene.setObjectsVisible(scene.xrayedObjectIds, false); scene.setObjectsXRayed(scene.xrayedObjectIds, false); }, 500); }); }); // 新增:处理节点勾选/取消勾选事件 treeView.on("nodeToggled", (e) => { const objectIds = []; e.treeViewPlugin.withNodeTree(e.treeViewNode, (treeViewNode) => { if (treeViewNode.objectId) { objectIds.push(treeViewNode.objectId); } }); viewer.scene.setObjectsVisible(objectIds, e.treeViewNode.checked); }); // ... 其他代码 ... const gltfLoader = new GLTFLoaderPlugin(viewer); // 移除无效的metaModelSrc参数 gltfLoader.load({ id: "myModel", src: src, edges: true, excludeUnclassifiedObjects: false }); gltfLoader.on("loaded", (model) => { treeView.setModel(model); // 可选:强制同步对象可见性与TreeView勾选状态 viewer.scene.setObjectsVisible(model.objectIds, true); }); // ... 其他代码 ...
额外说明
- 如果确实需要使用自定义元模型,确保
metaModelSrc指向的JSON文件符合xeokit的元模型格式,包含正确的objects和hierarchy结构。 - TreeView的节点状态完全依赖于场景中对象的
visible属性,只要对象可见,节点就会自动勾选,反之亦然。
内容的提问来源于stack exchange,提问作者Mr. Boombastick
相关产品推荐
相关产品推荐

