如何在视窗内添加自定义装饰


如何在视窗内添加自定义装饰

基本使用

Imodel.js可以在前端视窗内添加/删除用户自定义装饰(Decorator)。其类层次如下所示:

其中AccuSnapHyperModelingDecoratorimodel.js系统预定义的装饰(Decorator),CustomDecorator是用户自定义装饰(Decorator),也就说用户至少需要实现接口Decorator中的decorate(context: DecorateContext): void方法即可实现自己的装饰(Decorator)。然后创建CustomDecorator的实例customDecorator,并调用:IModelApp.viewManager.addDecorator(customDecorator);即可将自定义装饰(Decorator)显示在视窗上,同时调用IModelApp.viewManager.dropDecorator(d)可将自定义装饰(Decorator)从视窗上删除。

示例

希望在视窗上显示一个用户自定义三角形,效果如下所示:

使用以下代码即可实现:

class CustomDecorator implements Decorator {
  public decorate(context: DecorateContext) {
    // draw semi-transparent polyline from top left to bottom right of vp
    const overlayBuilder = context.createGraphicBuilder(
      GraphicType.ViewOverlay
    );
    const polylineColor = ColorDef.from(0, 255, 0, 128);
    overlayBuilder.setSymbology(polylineColor, polylineColor, 10);
    const ps: Point3d[] = [
      new Point3d(100, 0, 0),
      new Point3d(100, 500, 0),
      new Point3d(500, 500, 0),
      new Point3d(100, 0, 0),
    ];
    overlayBuilder.addShape(ps);
    context.addDecorationFromBuilder(overlayBuilder);
  }
}

const cd = new CustomDecorator();
//添加装饰
IModelApp.viewManager.addDecorator(cd);
//删除装饰
IModelApp.viewManager.dropDecorator(cd);

原理

IModelApp.viewManager维护着一个Decorator[]数组,每当显式调用:IModelApp.viewManager.addDecoratorIModelApp.viewManager.dropDecorator的时候遍历标记所有viewport中的_decorationsValid为无效(异常情况下不会触发此标记),然后主动调用IModelApp.requestNextAnimation()以更新帧,因为此时_decorationsValid已经被标记为无效,所以会将IModelApp.viewManager维护者的Decorator[]数组中的所有内容更新到窗口上。注意,通过IModelApp.viewManager.addDecorator添加的装饰(Decorator)会在所有的ViewState的视窗上出现。

其大概流程如下所示: