如何检测Forge 3D Viewer中模型默认隐藏元素并独立控制其可见性?
解决方案
1. 直接查询IfcOpeningElements的dbIds,跳过延迟的隐藏节点检测
不要依赖getHiddenNodes(),而是通过模型的属性数据库直接查询所有IfcOpeningElements的标识,这可以在模型核心数据加载完成后立即执行,无需等待额外场景初始化:
async function getOpeningDbIds(model) { // 先获取IfcOpeningElement对应的分类ID const category = await model.getPropertyDb().executeUserFunction(async (propsDb) => { const categories = await propsDb.getCategories(); return categories.find(cat => cat.name === 'IfcOpeningElement'); }); if (!category) return []; // 根据分类ID搜索所有元素的dbId return await model.search({ category: category.id }); }
监听模型的AGGREGATE_LOADED_EVENT事件(模型几何和属性数据加载完成的标志),调用上述方法即可快速拿到所有IfcOpeningElements的dbIds。
2. 单独维护IfcOpeningElements的可见性状态,隔离全局操作影响
提前获取并保存IfcOpeningElements的dbIds,在执行全局显示/隐藏操作时,先记录它们的当前可见状态,操作完成后再恢复,避免被全局设置覆盖:
let openingDbIds = []; const openingVisibilityState = {}; // 模型加载完成后初始化数据 model.addEventListener(Autodesk.Viewing.AGGREGATE_LOADED_EVENT, async () => { openingDbIds = await getOpeningDbIds(model); // 记录初始隐藏状态(默认隐藏) openingDbIds.forEach(dbId => { openingVisibilityState[dbId] = false; }); }); // 自定义全局显示/隐藏方法,替代原生model.setAllVisibility function setModelGlobalVisibility(model, show) { // 先保存当前IfcOpeningElements的可见状态 openingDbIds.forEach(dbId => { openingVisibilityState[dbId] = viewer.isVisible(dbId, model); }); // 执行全局可见性设置 model.setAllVisibility(show); // 恢复IfcOpeningElements的状态 openingDbIds.forEach(dbId => { viewer.setVisibility(dbId, openingVisibilityState[dbId], model); }); }
3. 关于默认隐藏元素的检测时机
AGGREGATE_LOADED_EVENT是可靠的模型就绪节点,此时模型的元数据和属性数据库已完全加载,通过分类查询可以立即确认是否存在IfcOpeningElements,无需等待getHiddenNodes()的延迟。getHiddenNodes()的延迟源于场景图的遍历和渲染节点初始化,而属性数据库查询直接读取模型元数据,效率更高。
内容的提问来源于stack exchange,提问作者simen-andresen
相关产品推荐
相关产品推荐

