Atamai软件包学习之ActorFactory(一)
ActorFactory, 3D可视化对象的基类。采用了设计模式中的工厂模式,一个ActorFactory可以用来组装不同的Actors。ActorFactory一个可视化对象,可以同时被显示在一个或者多个RenderPanes里。
ActorFactory可以组装许多vtkActors。每次把ActorFactory连接显示到RenderPane,ActorFactory将为这个RenderPane产生新的vtkActors副本。
ActorFactories也可以按分级体系的创建。例如:几个ActorFactories可以一起作为一个parent的ActorFactory的Children,可以作为单个单元来控制。
ActorFactory可以接受并处理事件(通常来源于RenderPane的鼠标和平移事件),用来驱动actors与用户的交互。
关于从ActorFactory派生自己的类, 你必须重写方法_MakeActors()去产生一组新的actors当Connect 到一个RenderPane中。_MakeActors() 方法应该首先去call_NewActor()方法去创建新的actors,尽量避免直接生成一个vtkActor()。
ActorFactory派生于:
EventHandler
可以参考:
RenderPane, OutlineFactory, OrthoPlanesFactory
初始化方法:
ActorFactory()
Public 方法:
下面是常用的方法:
- GetTransform() 获得actors的转换矩阵,如果要改变transform可以使用如下方法
factory.GetTransform().SetInput(*transform*)
- HasChangedSince(*time*) 如果factory从这个time开始已经被修改了花,那么该方法返回True。如果factory拥有任何inputs或者其它的额外的可修改的VTK对象,也需要去检测。
- GetClassName(*name*) 获得类名
- IsA(*classname*) 设置是否该factory属于特别的类或者其子类。
- SetName(*name*) 设置个factory的名字。该factory的模式认识是类名去掉Factory。
- GetRenderers() 返回所有renderers的一个列表。
- GetRenderWindows() 返回所有RenderWindows的一个列表
- GetActors(*renderer*) 返回该renderer的所有actors的一个列表,包括子factories
- Render() 重绘包含该ActorFactory所有PaneFrames
主要被RenderPane用到的方法。
- AddToRenderer(*renderer*) 添加actors到renderer中
- RemoveFromRenderer(*renderer*) 从renderer中移除actors
- GetPickList(*event*) pick一次后,返回pick到的对象(属于该factory的每个被拾到的每个actor)的一个列表。
- HandleEvent(*event*) 处理一个event
派生类内部主要用到的方法
- AddChild(*factory*) 添加一个子的ActorFactory
- RemoveChild(*factory*) 删除一个子的ActorFactory
- GetChildren() 返回所有的children的一个列表
- GetChild(*name*) 返回特别名字的child
- Modified() 更新修改时间。无论哪个属性被修改,应该call这个方法。
- ScheduleOnce(*ms*,*func*) 计划在一个特别的时间后,执行一个方法。(可以返回一个id,可以用这个id去取消该计划)
- ScheduleEvery(*ms*,*func*) 计划当一个特别的时间段过去后执行一次该function。(可以返回一个id,可以用这个id去取消该计划)
- UnSchedule(*id*) id去取消该计划
受保护的方法:
- _MakeActors() 产生显示在renderer的一列actors。(该类需要被重写在派生类中)
- _NewActor() 为该factory产生一个新的actor
- _FreeActor() 释放被_NewActor()创建的actor
受保护的属性:
- _Name factory的名字
- _Mtime vtkTimeStamp 使用Modified()改变该值
- _Renderers factory关联的renderers的列表
- _ActorDict actor字典类renderer和factory提供的actors的列表的对应关系
- _Children actor factories列表,该factory的子actorfactories
- _Transform 应用用所有actors的转换矩阵
关于actors的重要信息:
ActorFactory必须要为每个renderer维护分离的actors列表。这是由于VTK的一个限制,无法实现一个vtkactor可以被多个render所共享。这也意味着如果actorFactory没有被连到任何Renderer或者RenderPane上,那么 它不应该包含任何actors,发ishengleiye应该遵循该设计/。不应该在__init__方法中手动创建actors。一般你应该创建actors通过重写_MaskActors()方法。
如果想增加更多的actors到factory中当它已经被添加到renderer中。一个最简单的方法就是制作一个子的actorFactory类给每个你想增加的块。使用AddChild()方法和RemoveChild()方法按需要增加和删除块。此外,可以参考ThinPlateSplineFactory类,作为一个学习从factory中增加和删除actors的例子。必须要注意的是:连接factory到一个每个render的时候必须要创建actors的副本。
关于events的一些额外信息:
参考EventHandler,一般的信息关于binding/handling事件。
所有送到该ActorFactory的鼠标相关的事件必须要包含的属性:
Event.x, event.y 鼠标位置,从窗口的左下角为0,0点
Event.actor 在鼠标下的cursor的actor
Event.render 鼠标所在的renderer
此外 如果event是按钮按下出发的话,下面的属性肯定存在
Event.picker 上次按钮按下的拾取信息
一些额外的信息 关于变换矩阵
所有ActorFactory产生的actors共享一个vtkTransform作为他们的UserTransform。这个UserTransform必须不要被其它目的来使用。
你可以直接修改这个变换矩阵来改变一个ActorFactory的位置和方向。
- actorFactory.GetTransform().Identity()
- actorFactory.GetTransform().Translate(*x*,*y*,*z*)
没有提供SetTransform()方法,替代的做法,可是使用:
- actorFactory.GetTransform().SetInput(*newTransform*)
一些额外的信息关于child组件:
最好的访问ActorFactory的一个组件的方法是通过name。例如 actorFactory.GetChild(*name*) name就是child.GetName()返回的name 字符串。ActorFactory的默认的名字是没类名不带Factory。
默认下,一个组件ActorFactory的变换矩阵就是相关的父亲的位置/方向矩阵。如果不想要继承该行为,可以调用方法,在actorFactory.AddChild(*child*)方法执行完后,call child.GetTransform().SetInput(None)设置其child 的变换矩阵为None.