如何将Rhino块导出到Autodesk Viewer并保留为可整体选中的单一几何体
解决方案:Autodesk Viewer中保留Rhino块的整体选中功能
针对你遇到的Rhino块在Viewer中被拆分为独立部件的问题,以下是几种无需额外Revit中转的简便方案:
方案1:通过选择事件联动块结构实现整体选中
既然Viewer已经能识别块定义(可在模型浏览器中查看),可以通过监听选择事件,自动将选中的单个网格关联到所属块,实现点击任意部件选中整个块:
viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, (event) => { if (event.dbIdArray.length === 0) return; const selectedDbId = event.dbIdArray[0]; const tree = viewer.model.getInstanceTree(); // 遍历父节点,定位块的顶层节点 let parentId = tree.getParentId(selectedDbId); let blockTopId = selectedDbId; while (parentId) { const nodeName = tree.getNodeName(parentId); // 根据你的块标识(如示例中的"T.A.")判断顶层节点 if (nodeName.includes("T.A.") || nodeName.startsWith("Block")) { blockTopId = parentId; break; } parentId = tree.getParentId(parentId); } // 获取块下所有子节点的dbId const blockDbIds = []; tree.enumNodeChildren(blockTopId, (dbId) => { blockDbIds.push(dbId); }, true); // 选中整个块的所有部件 viewer.select(blockDbIds); });
该方案无需修改模型,仅通过前端代码实现,适合需要在不同视图切换选中模式的场景(可通过开关控制是否启用该逻辑)。
方案2:转换模型时配置保留Rhino块结构
通过Autodesk Forge Model Derivative API转换Rhino模型时,可添加参数控制块的拆分行为,直接将Rhino块导出为单一可选中实体:
在转换请求的JSON payload中,添加advanced配置:
{ "input": { "urn": "your-model-urn" }, "output": { "formats": [ { "type": "svf", "views": ["3d"], "advanced": { "rhino": { "mergeBlocks": true } } } ] } }
此配置会让转换后的SVF模型将Rhino块合并为单一几何体,加载到Viewer后即可直接点击选中整个块,无需额外前端逻辑。
方案3:自定义几何体合并(适合特殊场景)
如果上述方案无法满足需求,可在模型加载后,手动合并块内的所有网格为单一几何体:
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, async () => { const tree = viewer.model.getInstanceTree(); // 自定义函数:根据名称查找目标块的顶层节点dbId const blockTopId = findBlockTopNodeId(tree, "T.A."); // 获取块下所有子网格的dbId const childDbIds = []; tree.enumNodeChildren(blockTopId, (dbId) => childDbIds.push(dbId), true); // 合并几何体 const mergedGeometry = await mergeGeometries(viewer, childDbIds); // 隐藏原块的所有子部件 viewer.hide(childDbIds); // 添加合并后的几何体到场景 viewer.impl.scene.add(mergedGeometry); }); // 辅助函数:合并多个dbId的几何体 async function mergeGeometries(viewer, dbIds) { const merged = new THREE.BufferGeometry(); const material = new THREE.MeshPhongMaterial({ color: 0xcccccc }); for (const dbId of dbIds) { const fragIds = viewer.model.getFragmentList().fragments.dbId2fragIds[dbId]; for (const fragId of fragIds) { const geometry = viewer.model.getFragmentList().getGeometry(fragId); merged.merge(geometry); } } return new THREE.Mesh(merged, material); }
注意:此方案会增加前端计算量,建议仅针对小型块使用,避免影响大模型的加载性能。
内容的提问来源于stack exchange,提问作者konstantinAtMaestroTech
相关产品推荐
相关产品推荐

