# 构件强调与场景管理

设备状态的跟踪是运维平台核心的功能。一旦设备发生故障,第一时间获取发生故障的设备信息是十分关键的。在上一节 (opens new window)中,我们已经实现了定位到关注构件的场景,接下来我们将一起实现故障设备报警的场景。

# 教程内容

在定位到关注的构件之后,接下来我们需要:

  • 假设外墙二楼的窗破损,给该构件添加强调状态
  • 保存模型浏览状态及恢复浏览状态,便于模型的浏览
  • 对场景设置自动旋转
# 1. 构件强调

我们来为指定的构件添加强调状态,在BIMFACE中,处于强调状态的构件会间隔性地闪烁,其闪烁的颜色、间隔时间均可设置。 需要注意两点:

  • 在对构件进行强调设置前,先要启用构件强调功能;
  • 为避免构件强调对性能造成影响,建议控制被强调构件的数量。

首先我们添加一个按钮:

<button class="button" id="btnBlinkComponent" onclick="blinkComponents()">构件强调</button>

然后在script标签内构造函数:

// ************************** 构件闪烁 **************************
let isBlinkActivated = false;
function blinkComponents() {
  if (!isBlinkActivated) {
    let blinkColor = new Glodon.Web.Graphics.Color("#B22222", 0.8);
    // 打开构件强调开关
    viewer3D.enableBlinkComponents(true);
    // 给需要报警的构件添加强调状态
    viewer3D.getModel().addBlinkComponentsById(["389617"]);
    // 设置强调状态下的颜色
    viewer3D.getModel().setBlinkColor(blinkColor);
    // 设置强调状态下的频率
    viewer3D.getModel().setBlinkIntervalTime(500);
    viewer3D.render();
    setButtonText("btnBlinkComponent", "清除强调");
  } else {
    // 清除构件强调
    viewer3D.getModel().clearAllBlinkComponents();
    viewer3D.render();
    setButtonText("btnBlinkComponent", "构件强调");
  }
  isBlinkActivated = !isBlinkActivated;
}

加载页面,我们就可以进行构件强调操作了。

构件强调图

# 2. 模型状态管理

我们可以将某些视角保存下来,便于后期在模型浏览时,可以快速地切换到该视角进行查看。

在这里我们需要新建两个按钮:

<button class="button" id="btnSaveState" onclick="getCurrentState()">保存状态</button>
<button class="button" id="btnRestoreState" onclick="setState()">恢复状态</button>

然后在script标签内构造保存状态的函数:

// ************************** 状态 **************************
let state;
function getCurrentState(){
  // 保存当前模型浏览状态
  state = viewer3D.getCurrentState(); 
}

以及恢复状态的函数:

function setState(){
  if (state != null) {
    // 恢复模型浏览状态
    viewer3D.setState(state);
    viewer3D.render();
  } else {
    window.alert("请先保存一个模型浏览状态!");
  }
}

再次加载页面,我们就可以进行模型状态管理操作了。

状态管理

# 3. 场景旋转

最后,我们将整个场景缓慢旋转起来,提升整体的展示效果。

同样先添加一个按钮:

<button class="button" id="btnStartAutoRotate" onclick="startAutoRotate()">开始旋转场景</button>

然后在script标签内构造函数:

// ************************** 旋转场景 **************************
let isAutoRotateActivated = false;
function startAutoRotate() {
  if (!isAutoRotateActivated) {
    // 开始场景旋转
    viewer3D.startAutoRotate(5);
    setButtonText("btnStartAutoRotate", "结束旋转场景");
  } else {
    // 结束场景旋转
    viewer3D.stopAutoRotate();
    setButtonText("btnStartAutoRotate", "开始旋转场景");
  }
  isAutoRotateActivated = !isAutoRotateActivated;
}

这里需要说明的是,startAutoRotate中的参数类型为Number,正负号代表方向,绝对值大小代表旋转的速率。

再次加载页面,我们就可以进行场景旋转操作了。

场景旋转图

现在,你已经搭建了一个简易的运维场景,可以对模型构件或场景进行操作和浏览。

# 完整代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>BIMFACE model scene</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      html, body {
        height: 100%;
      }
      .buttons {
        font-size: 0;
      }
      .button {
        margin: 5px 0 5px 5px;
        width: 90px;
        height: 30px;
        border-radius: 3px;
        border: none;
        background: #11DAB7;
        color: #FFFFFF;
      }
      .main {
        display: flex;
        flex-direction: column;
        overflow: hidden;
        height: 100%;
      }
      #domId {
        flex: 1;
      }
    </style>
  </head>
  <body>
    <div class='main'>
      <div class='buttons'>
        <button class="button" id="btnIsolation" onclick="isolateComponents()">构件隔离</button>
        <button class="button" id="btnZoomToSelection" onclick="zoomToSelectedComponents()">构件定位</button>
        <button class="button" id="btnOverrideColor" onclick="overrideComponents()">构件着色</button>
        <button class="button" id="btnBlinkComponent" onclick="blinkComponents()">构件强调</button>
        <button class="button" id="btnSaveState" onclick="getCurrentState()">保存状态</button>
        <button class="button" id="btnRestoreState" onclick="setState()">恢复状态</button>
        <button class="button" id="btnStartAutoRotate" onclick="startAutoRotate()">开始旋转场景</button>
      </div>
      <div id="domId"></div>
    </div>
    <script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js"></script>
    <script>
      let viewToken = '<yourViewToken>';
      // 声明Viewer及App
      let viewer3D;
      let app;
      // 配置JSSDK加载项
      window.onload = function() {
        let loaderConfig = new BimfaceSDKLoaderConfig();
        loaderConfig.viewToken = viewToken;
        BimfaceSDKLoader.load(loaderConfig, successCallback, failureCallback);
      }
      // 加载成功回调函数
      function successCallback(viewMetaData) {
        let dom4Show = document.getElementById('domId');
        // 设置WebApplication3D的配置项
        let webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig();
        webAppConfig.domElement = dom4Show;
        // 创建WebApplication3D,用以显示模型
        app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig);  
        app.addView(viewToken);
        viewer3D = app.getViewer();
      }
      // 加载失败回调函数
      function failureCallback(error) {
        console.log(error);
      }

      // ************************** 隔离 **************************
      let isIsolationActivated = false;
      function isolateComponents() {
        if (!isIsolationActivated) {
          // 设置隔离选项,指定其他构件为半透明状态
          let makeOthersTranslucent = Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent;
          // 调用viewer3D.method,隔离楼层为"F2"的构件
          viewer3D.getModel().isolateComponentsByObjectData([{"levelName":"F2"}], makeOthersTranslucent);
          // 渲染三维模型
          viewer3D.render(); 
          // 修改按钮的文字内容
          setButtonText("btnIsolation", "取消隔离");
        } else {
          // 清除隔离
          viewer3D.getModel().clearIsolation();
          // 渲染三维模型
          viewer3D.render();
          // 修改按钮的文字内容
          setButtonText("btnIsolation", "构件隔离");
        }
        isIsolationActivated = !isIsolationActivated;
      }

      // ************************** 定位 **************************
      let isZoomToSelectionActivated = false;
      function zoomToSelectedComponents(){
        if (!isZoomToSelectionActivated) {
          // 选中id为"271431"的构件
          viewer3D.getModel().addSelectedComponentsById(["271431"]);
          // 定位到选中的构件
          viewer3D.getModel().zoomToSelectedComponents();
          // 清除构件选中状态
          viewer3D.getModel().clearSelectedComponents();
          setButtonText("btnZoomToSelection", "回到主视角");
        } else {
          // 切换至主视角
          viewer3D.setView(Glodon.Bimface.Viewer.ViewOption.Home);
          setButtonText("btnZoomToSelection", "构件定位");
        }
        isZoomToSelectionActivated = !isZoomToSelectionActivated;
      }

      // ************************** 着色 **************************
      let isOverrideActivated = false;
      function overrideComponents(){
        if (!isOverrideActivated) {
          // 新建color对象,指定关注构件被染色的数值
          let color = new Glodon.Web.Graphics.Color("#11DAB7", 0.5);
          // 对关注构件进行着色
          viewer3D.getModel().overrideComponentsColorById(["389601"], color);
          viewer3D.render();
          setButtonText("btnOverrideColor", "清除着色");
        } else {
          // 清除构件着色
          viewer3D.getModel().clearOverrideColorComponents();
          viewer3D.render();
          setButtonText("btnOverrideColor", "构件着色");
        }
        isOverrideActivated = !isOverrideActivated;
      }

      // ************************** 构件闪烁 **************************
      let isBlinkActivated = false;
      function blinkComponents() {
        if (!isBlinkActivated) {
          let blinkColor = new Glodon.Web.Graphics.Color("#B22222", 0.8);
          // 打开构件强调开关
          viewer3D.enableBlinkComponents(true);
          // 给需要报警的构件添加强调状态
          viewer3D.getModel().addBlinkComponentsById(["389617"]);
          // 设置强调状态下的颜色
          viewer3D.getModel().setBlinkColor(blinkColor);
          // 设置强调状态下的频率
          viewer3D.getModel().setBlinkIntervalTime(500);
          viewer3D.render();
          setButtonText("btnBlinkComponent", "清除强调");
        } else {
          // 清除构件强调
          viewer3D.getModel().clearAllBlinkComponents();
          viewer3D.render();
          setButtonText("btnBlinkComponent", "构件强调");
        }
        isBlinkActivated = !isBlinkActivated;
      }

      // ************************** 状态 **************************
      let state;
      function getCurrentState(){
        // 保存当前模型浏览状态
        state = viewer3D.getCurrentState(); 
      }

      function setState(){
        if (state != null) {
          // 恢复模型浏览状态
          viewer3D.setState(state);
          viewer3D.render();
        } else {
          window.alert("请先保存一个模型浏览状态!");
        }
      }

      // ************************** 旋转场景 **************************
      let isAutoRotateActivated = false;
      function startAutoRotate() {
        if (!isAutoRotateActivated) {
          // 开始场景旋转
          viewer3D.startAutoRotate(5);
          setButtonText("btnStartAutoRotate", "结束旋转场景");
        } else {
          // 结束场景旋转
          viewer3D.stopAutoRotate();
          setButtonText("btnStartAutoRotate", "开始旋转场景");
        }
        isAutoRotateActivated = !isAutoRotateActivated;
      }

      // ************************** 按钮文字 **************************
      function setButtonText(btnId, text) {
        let dom = document.getElementById(btnId);
        if (dom != null && dom.nodeName == "BUTTON") {
          dom.innerText = text;
        }
      }
    </script>
  </body>
</html>

恭喜你,你已经完成了基础模式教材(模型)的学习。接下来你可以学习: