VTK编码笔记
智能指针等
- 创建对象的智能指针的做法已经改变了。
例如, 下面分别是新老代码:1
2
3
4// 以前的做法:
auto renWin = vtkSmartPointer<vtkRenderWindow>::New();
// 新的做法:
vtkNew<vtkRenderWindow> renWin1;
从文档中描述vtkNew<T>
是使用T::New()
分配一个对象. 看其源码:
1 | template <class T> |
RTTI
可以使用
GetClassName()
获取对象类型IsA()
判断类:if( obj->IsA("vtkExampleClass")){...}
类型转换:
SafeDownCase()
:vtkExampleClass* exmple = vtkExampleClass::SafeDownClass(obj)
对象状态打印:
obj->Print(count)
基本的VTK程序步骤
VTK程序基本上是这个流程:
source -> mapper -> actor -> renderer -> renderwindow
回调
VTK中和Widget的交互, 或者其他, 是使用的观察者/命令模式实现的.
在vtkObject
中定义了和Observer相关的函数, 比如AddObserver()
, RemoveObserver()
等.AddObserver()
函数接收多种形式, 并返回一个unsigned long
的tag
值, 这个值用于唯一标识这个observer, 可以被用于RemoveObserver()
中作为参数.
主要的使用场景是定义观察者, 并添加进去. Observer, 或者称之为回调, 有几种定义方式:
一种是定义一个函数, 并利用它来构造一个
vtkCallBackCommand
, 提供给AddObserver()
. 它本质上是动态生成一个btkCommand
对象, 并更改它的Execute()
方法而已.另一种是直接定义一个
vtkCommand
的派生类, 并将它的实例传递给AddObserver()
函数. 相对于第一种, 这种的好处是可以在这个Command类中保持自己的状态信息.还有一种是将任意的自己的类的实例和类方法前面传递给它. 例如:
1
2SomeClassOfMine* observer = SomeClassOfMine::New();\n
to_observe->AddObserver(event, observer, &SomeClassOfMine::SomeMethod);这种情况下, 类的方法可以有两种形式:
1
2void foo();\n
void foo(vtkObject*, unsigned long, void*);它实际上是
vtkCommand
派生类的增强. 但是, 目前还不支持lambda的方式, 这个有点遗憾. 也许更新的平台会利用更新的C++特性吧.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class MyClass
{
public:
void callback1(){
std::cout << "MyClass callback1 called!" << std::endl;
}
void callback2(vtkObject*, unsigned long, void*){
std::cout << "MyClass::callback2 called! " << std::endl;
}
};
...
MyClass o;
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, &o, &MyClass::callback1);
或
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, &o, &MyClass::callback2);
vtkStandardNewMacro()宏
这个宏是为一个类生成一个New()
的函数.
例如, 我们这么写vtkStandardNewMacro(A)
, 那么就可以这样用:
1 | vtkSmartPointer<A> style = vtkSmartPointer<A>::New(); |