vtk.js widgets
vtk Widget是官方提供的常用小工具,如LineWidget、AngleWidget、PaitWidget等
vtk Widget架构遵循MVC,分为三个组件
- vtkWidgetState (model)
 
- vtkWidgetRepresentation (view)
 
- vtkAbstractWidget (control)
 
下图示意调用widget的不同组件的通信关系

Widget 工厂用于组装Widget及其state、representations
构建vtkWidgetState
调用getWidgetForView 工厂new一个widget对象 将state赋给该对象 创建并设置representations即SetRepresentation
开发者应继承vtkAbstractWidgetFactory开发widget
与InteractorStyle相比
VTK的交互器样式(vtkInteractorStyle)通常只是控制相机以及提供一些简单的键盘和鼠标事件的交互技术。交互器样式在渲染场景中并没有一种表达形式,也就是说,在交互时我们看不见交互器样式到底是什么样子的,用户在使用这些交互器样式时,必须事先知道哪些键盘和鼠标事件是控制哪些操作的。FromCSDN: Widgets简介
vtkWidget同为vtkInteractorObserver子类,监听并响应交互器事件,又添加可视化的representation
Developing Widgets
vtkWidgetManager 是管理widgets创建、抑制(suppression)及聚焦(focus)的对象,每个render中唯一
1 2 3 4 5 6 7 8
   | widget = vtkWidget.newInstance() handle = widgetManager.addWidget(widget, viewType) widgetManager.setRenderer(renderer) widgetManager.grabFocus(widget) widgetManager.enablePicking()
  widgetManager.removeWidget(widget) widget.delete()
   | 
focus至多一个widget 激活并使能其响应事件(其实behaviour也可以在unfocus的状态下响应)
使用widget的newInstance方法创建widget对象 这时widget state被创建 用于在不同组件间同步状态 比如工具栏和canvas的相互交互
viewType用于指示widget manager该使用的representation。
创建子状态
1 2 3 4 5 6 7 8 9 10 11 12
   | vtkStateBuilder .createBuilder() .addStateFromMixin({     labels: ['{LABEL0}'],     mixins: ['origin', 'color', 'scale1', 'visible'],     name: '{NAME}',     initialValues: {       scale1: 0.1,       origin: [1, 2, 3],       visible: false,     } })
   | 
- name是子状态唯一标识 调用state.get{NAME}()从widget state中读取子状态
 
- labels决定哪些representation可以用来渲染该子状态
 
- mixins存放子状态有效数据 representation会使用到这些数据 因而是有限且标准的 get/set方法:subState.get{NAME}(), subState.set{NAME}() 修改子状态触发场景渲染
 
- initialValues子状态初始值 非必须的
 
动态子状态
Mixins
调用widgetManager.getRepresentationsForViewType(viewType)返回含representation的集合 参数viewType是addWidget时指定的参数
返回各项 {builder, labels} 前者是Representation类 后者是representation对象要用到的子状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | switch (viewType) {   case ViewTypes.DEFAULT:   case ViewTypes.GEOMETRY:   case ViewTypes.SLICE:     return [       {         builder: vtkCircleContextRepresentation,         labels: ['handle', 'trail'],       },       {         builder: vtkPolyLineRepresentation,         labels: ['trail'],       },     ];   case ViewTypes.VOLUME:     return [         {             builder: vtkSphereHandleRepresentation,             labels: ['handles'],             initialValues: {               scaleInPixels: true,             },           },           {             builder: vtkSphereHandleRepresentation,             labels: ['moveHandle'],             initialValues: {               scaleInPixels: true,             },           },           {             builder: vtkSVGCircleHandleRepresentation,             labels: ['handles', 'moveHandle'],           }     ];   default:     return [{ builder: vtkSphereHandleRepresentation, labels: ['handle'] }]; }
  | 
Representation托管自身actors和mappers, actor在Representation创建时创建,推入model.actors中进而渲染
Representation应继承vtkHandleRepresentation 或 vtkContextRepresentation
Widget behavior
widgetManager.addWidget返回的handle就是widget behavior对象 它控制这widget的行为:接收并响应鼠标、键盘事件 见其定义的方法形如 PublicAPI.handle{XXX}(callData)
widget behavior也可以访问renderer rendererWindow 和 interactor