如何在APS Viewer中复刻BIM360的拆分视图模式与对比按钮?
问题描述
我开发了一个Next.js应用,集成Autodesk Platform Services(APS)Viewer来展示Revit模型。现需复刻BIM360默认自带的工具栏拆分视图模式(Split View Mode)与对比(Compare)按钮。我认为这些功能应为扩展,但未找到对应扩展。我尝试了如下代码实现:
// handle the split screen button let splitScreenButton = new Autodesk.Viewing.UI.Button( "splitScreenButton" ); let isSplitScreenLoaded = false; splitScreenButton.onClick = function () { if (isSplitScreenLoaded) { newViewer.unloadExtension("Autodesk.SplitScreen"); isSplitScreenLoaded = false; } else { newViewer.loadExtension("Autodesk.SplitScreen"); isSplitScreenLoaded = true; } }; splitScreenButton.setToolTip("Split Screen"); splitScreenButton.setIcon("adsk-icon-second"); compareTools.addControl(splitScreenButton); // coppied straight from the docs, and typically, dosent work let compareButton = new Autodesk.Viewing.UI.Button("compareButton"); let isCompareLoaded = false; var config = { availableDiffModes: ["overlay", "sidebyside"], // diffModels: A, // primaryModels: B, mimeType: "application/vnd.autodesk.revit", diffadp: false, diffMode: "overlay", // versionA: "A", // versionB: "B", propertyFilter: { Category1: ["Property1", "Property2"] }, }; compareButton.onClick = function () { if (isCompareLoaded) { newViewer.unloadExtension("Autodesk.DiffTool", config); isCompareLoaded = false; } else { newViewer.loadExtension("Autodesk.DiffTool", config); isCompareLoaded = true; } }; compareButton.setToolTip("Compare"); compareButton.setIcon("adsk-icon-live-review"); compareTools.addControl(compareButton);
但Autodesk.SplitScreen仅重复显示模型,实用性低。我希望能使用类似newViewer.loadExtension("Autodesk.SplitViewMode")的扩展来替代现有实现,但未找到。对比功能也存在同样问题,请问这些扩展是否存在?若不存在,该如何复刻对应功能?
解决方案
一、拆分视图模式(Split View Mode)
BIM 360中的拆分视图模式并非独立的官方扩展(Autodesk.SplitViewMode这类扩展不存在),它是基于APS Viewer的多视口能力自定义实现的功能,而非直接通过加载扩展启用。
复刻思路
- 创建多视口容器:在Viewer的DOM容器内添加多个子容器,每个容器对应一个视口实例。
- 初始化多Viewer实例:为每个子容器初始化独立的Viewer实例,共享同一个模型文档(避免重复加载模型数据)。
- 同步视口状态:监听每个Viewer的相机变化、选择事件等,同步到其他视口,保证操作一致性。
- 控制布局样式:通过CSS控制多个视口的排列(左右分栏、上下分栏等),实现拆分效果。
核心代码示例
// 假设已有主Viewer实例:mainViewer const container = mainViewer.container; // 创建两个子视口容器 const viewport1 = document.createElement('div'); const viewport2 = document.createElement('div'); viewport1.style.cssText = 'width:50%;height:100%;float:left;'; viewport2.style.cssText = 'width:50%;height:100%;float:left;'; container.appendChild(viewport1); container.appendChild(viewport2); // 初始化第二个Viewer实例,共享主实例的文档配置 const options = { env: mainViewer.config.env, accessToken: mainViewer.config.accessToken, documentId: mainViewer.model.getDocumentId() }; Autodesk.Viewing.Initializer(options, () => { const secondViewer = new Autodesk.Viewing.GuiViewer3D(viewport2); secondViewer.start(); // 加载同一文档,复用缓存数据 secondViewer.loadDocument(options.documentId, () => { // 同步主视图的相机位置 mainViewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, () => { const camera = mainViewer.getCamera(); secondViewer.setCamera(camera); }); }); });
二、对比(Compare)功能
官方的Autodesk.DiffTool扩展确实存在,但你当前的代码缺少关键的模型版本配置,导致功能无法生效。BIM 360的对比功能正是基于该扩展的定制化实现。
修复及复刻思路
- 获取模型版本URN:需要明确要对比的两个Revit模型版本的URN(或文档ID+版本ID)。
- 完善DiffTool配置:
primaryModels:指定基准模型的URN数组diffModels:指定对比模型的URN数组- 确保
mimeType与模型类型匹配(Revit模型用application/vnd.autodesk.revit)
- 修正扩展加载逻辑:卸载扩展时无需传递config参数,加载时传入完整配置。
修正后的代码示例
let compareButton = new Autodesk.Viewing.UI.Button("compareButton"); let isCompareLoaded = false; // 替换为实际的模型URN const baseModelUrn = "urn:xxx"; const compareModelUrn = "urn:yyy"; compareButton.onClick = function () { if (isCompareLoaded) { // 卸载扩展无需传config newViewer.unloadExtension("Autodesk.DiffTool"); isCompareLoaded = false; } else { const config = { availableDiffModes: ["overlay", "sidebyside"], primaryModels: [baseModelUrn], diffModels: [compareModelUrn], mimeType: "application/vnd.autodesk.revit", diffMode: "overlay", // 可选:过滤需要对比的属性 propertyFilter: { Walls: ["Height", "Area"] } }; newViewer.loadExtension("Autodesk.DiffTool", config).then(() => { isCompareLoaded = true; }).catch(err => { console.error("加载DiffTool失败:", err); }); } }; compareButton.setToolTip("Compare"); compareButton.setIcon("adsk-icon-live-review"); compareTools.addControl(compareButton);
注意事项
- 确保两个模型属于同一项目,且Viewer有权限访问这两个版本。
- 如果对比同一模型的不同版本,可通过BIM 360 API获取对应版本的URN。
内容的提问来源于stack exchange,提问作者Duncan Findlay
相关产品推荐
相关产品推荐

