智能指针等

  • 创建对象的智能指针的做法已经改变了。
    例如, 下面分别是新老代码:
    1
    2
    3
    4
    // 以前的做法:
    auto renWin = vtkSmartPointer<vtkRenderWindow>::New();
    // 新的做法:
    vtkNew<vtkRenderWindow> renWin1;

从文档中描述vtkNew<T>是使用T::New()分配一个对象. 看其源码:

1
2
3
4
5
6
7
8
9
10
11
template <class T>
class vtkNew
{
T* Object;
public:
vtkNew()
: Object(T::New())
{
vtkNew::CheckTypes();
}
}

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 longtag值, 这个值用于唯一标识这个observer, 可以被用于RemoveObserver()中作为参数.

主要的使用场景是定义观察者, 并添加进去. Observer, 或者称之为回调, 有几种定义方式:

  • 一种是定义一个函数, 并利用它来构造一个vtkCallBackCommand, 提供给AddObserver(). 它本质上是动态生成一个btkCommand对象, 并更改它的Execute()方法而已.

  • 另一种是直接定义一个vtkCommand的派生类, 并将它的实例传递给AddObserver()函数. 相对于第一种, 这种的好处是可以在这个Command类中保持自己的状态信息.

  • 还有一种是将任意的自己的类的实例和类方法前面传递给它. 例如:

    1
    2
    SomeClassOfMine* observer = SomeClassOfMine::New();\n
    to_observe->AddObserver(event, observer, &SomeClassOfMine::SomeMethod);

    这种情况下, 类的方法可以有两种形式:

    1
    2
    void 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
    15
    class 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();