VTK的python接口

VTK的Python接口

翻译和修改自:https://github.com/Kitware/VTK/tree/master/Wrapping/Python
英文原作者:David Gobbi
有关VTK的Python包装器的说明

STL 容器

VTK提供’std :: vector’和Python序列之间的转换,例如“tuple”和“list”。 如果C ++方法返回vector,Python方法将返回一个tuple:

C++: const std::vector<std::string>& GetPaths()
C++: std::vector<std::string> GetPaths()
Python: GetPaths() -> Tuple[str]

如果C ++方法接vector,则Python方法可以是传递了具有兼容值的任何序列(Sequence):

C++: void SetPaths(const std::vector<std::string>& paths)
C++: void SetPaths(std::vector<std::string> paths)
Python: SetPaths(paths: Sequence[str]) -> None

此外,如果C ++方法接受非常量向量引用,然后可以向Python方法传递可变的序列(Sequence)(例如list):

C++: void GetPaths(std::vector<std::string>& paths)
Python: GetPaths(paths: MutableSequence[str]) -> None

std :: vector的值类型必须为std :: string或基本数字类型,例如“ double”或“ int”(包括“ signed char”和“ unsigned char”,但不包括“ char”)。

内建文件

VTK头文件和html手册页中所有可用的文档也可以通过python获得。
如果您想查看某个类可用的方法,例如:

>>> dir(vtk.vtkActor)

或者,等效地,

>>> a = vtk.vtkActor()
>>> dir(a)

还可以从内置的“文档字符串”中检索有关VTK类和方法的文档:

>>> help(vtk.vtkActor)
>>> help(vtk.vtkActor.SetUserTransform)

对于方法文档,该方法的所有不同“签名”均以Python格式和原始C ++格式给出:

>>> help(vtkActor.SetPosition)
SetPosition(...)
V.SetPosition(float, float, float)
C++: virtual void SetPosition(double _arg1, double _arg2, double _arg3)
V.SetPosition([float, float, float])
C++: virtual void SetPosition(double _arg[3])

Set/Get/Add the position of the Prop3D in world coordinates.

特殊性

删除vtkObject

由于python提供了一种自动垃圾收集机制,因此没有与vtk的delete()直接等价的方法。一旦从python内部或其他vtk对象中没有对该对象的剩余引用,该对象将被删除。通过使用python’del’命令(即’del o’)可以去掉对对象的本地引用,如果对对象的本地引用是python中对该对象的最后一个剩余引用,则这将导致调用delete()。

模板类

模板类在VTK中很少见。 在使用它们的地方,可以像在C ++中一样实例化它们,除了将[ ]括号用于模板参数而不是<>括号:

>>> v = vtkVector['float64',3]([1.0, 2.0, 3.0])
>>> a = vtkDenseArray[str]()

只能使用有限范围的模板args,通常由typedef和C ++代码中的其他类使用args决定。 可以通过在模板上调用help()来找到可用于特定模板的允许参数组合的列表:

>>> help(vtkVector)

这些类型通常以字符串形式给出,形式为“ int32”,“ uint16”,“ float32”,“ float64”,“ bool”,“ char”,“ str”,“ vtkVariant”。 如果类型的名称与可接受的类型字符串之一相同,则也可以使用Python类型对象:

>>> a = vtkDenseArray[int]()

请注意,python’int’与C ++'long’的大小相同,而python’float’与C ++'double’的大小相同。 为了与python数组模块兼容,允许使用以下列表中的单字符类型代码:“?”,“ c”,“ b”,“ B”,“ h”,“ H”,“ i”,“ I” ',‘l’,‘L’,‘q’,‘Q’,‘f’,‘d’。 python数组文档解释了这些含义。

运算符的重载

python中包装了一些有用的运算符:[]运算符被包装用于索引和项目分配,但是由于它依赖于提示来猜测哪些索引超出范围,因此仅被包装用于vtkVector和其他一些类 。

比较运算符’<’’<=’’==’’> =’’>'被包装为所有在C ++中具有这些运算符的类。

包装了用于打印的“ <<”运算符,并由python的“ print()”和“ str()”命令使用。

引用传递

仅可以使用vtkCommonCore Python模块中的vtk.reference()来传递在C++中可变但在Python中不可变的值的引用(例如字符串,int和float):

>>> plane = vtk.vtkPlane()
>>> t = vtk.reference(0.0)
>>> x = [0.0, 0.0, 0.0]
>>> plane.IntersectWithLine([0, 0, -1], [0, 0, 1], t, x)
>>> print(t)
0.5

观察者,事件和CallData

Simple callback

与C ++中的操作类似,每次在给定对象上调用VTK事件时,都可以调用python函数:

>>> def onObjectModified(object, event):
>>>     print('object: %s - event: %s' % (object.GetClassName(), event))
>>>
>>> o = vtkObject()
>>> o.AddObserver(vtkCommand.ModifiedEvent, onObjectModified)
1
>>> o.Modified()
object: vtkObject - event: ModifiedEvent

Callback with CallData

如果有与事件关联的’CallData’值,则在C ++中,必须使用reinterpret_cast将其从void*强制转换为期望的类型。 例如,请参阅 http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/CallData

python中的等效项是在关联的python回调上设置CallDataType属性。 支持的CallDataType是vtk.VTK_STRING,vtk.VTK_OBJECT,vtk.VTK_INT,vtk.VTK_LONG,vtk.VTK_DOUBLE,vtk.VTK _FLOAT

例如:

>>> def onError(object, event, calldata):
>>>     print('object: %s - event: %s - msg: %s' % (object.GetClassName(),
                                                    event, calldata))
>>>
>>> onError.CallDataType = vtk.VTK_INT
>>>
>>> lt = vtkLookupTable()
>>> lt.AddObserver(vtkCommand.ErrorEvent, onError)
1
>>> lt.SetTableRange(2,1)
object: vtkLookupTable - event: ErrorEvent - msg: ERROR:
In /home/jchris/Projects/VTK6/Common/Core/vtkLookupTable.cxx, line 122
vtkLookupTable (0x6b40b30): Bad table range: [2, 1]

为了方便起见,还可以在首先使用’calldata_type’装饰器声明函数的位置指定CallDataType:

>>> @calldata_type(vtk.VTK_INT)
>>> def onError(object, event, calldata):
>>>     print('object: %s - event: %s - msg: %s' % (object.GetClassName(),
                                                    event, calldata))

子类化VTK类

可以从Python内部对VTK类进行子类化,但是无法正确覆盖该类的虚方法。 VTK C ++代码将看不到python级别的代码,因此从C ++调用虚拟方法时,将不会调用您在Python内部定义的方法。 仅当您在Python中调用该方法时,才会执行该方法。

因此,例如,将vtkInteractorStyle子类化以提供自定义python交互是不合理的。相反,您必须通过将观察者添加到vtkInteractor对象来执行此操作。

类方法的调用

在C ++中,如果要从超类调用方法,则可以执行以下操作:

vtkActor *a = vtkActor::New();
a->vtkProp3D::SetPosition(10,20,50);

python中的等效项是

>>> a = vtkActor()
>>> vtkProp3D.SetPosition(a,10,20,50)

Void 指针

作为一项特殊功能,可以将需要“ void *”的C ++方法传递给任何支持“缓冲区”协议的python对象,其中包括字符串对象,numpy数组甚至VTK数组。 使用此功能时应格外小心。

在Python中,在C ++中返回“ void *”的方法将返回带有十六进制数字的字符串,该字符串给出了内存地址。

将数据从Python传输到VTK

如果要从VTK中访问Python中的大量数据(例如,数值数组),则可以使用vtkDataArray.SetVoidArray()方法进行操作。

仅从VTK对象的地址创建Python对象

实例化一个类时,可以提供一个十六进制字符串,其中包含现有vtk对象的地址,例如

t = vtkTransform('_1010e068_vtkTransform_p')

该字符串遵循SWIG修改约定。 如果指定对象的包装已经存在,则将使用该包装,而不是创建新的包装。 如果要使用vtkpython的此功能,请三思。

具有“ pythonic”等效项的VTK C ++方法

SafeDownCast(): 不必要,Python已经知道真实类型
IsA():          Python提供了内置的isinstance()方法。
IsTypeOf():     Python提供了一个内置的issubclass()方法。
GetClassName(): 此信息由o .__ class __.__ name__提供

特殊VTK类型

除了从vtkObjectBase派生的VTK对象外,VTK中还有许多轻量级类型,例如vtkTimeStamp或vtkVariant。这些通常可以与vtkObjects区别开来,因为它们没有C ++的’:: New()'构造方法。

这些类型与vtkObject派生类的包装方式略有不同。内存管理的细节有所不同,因为Python实际上将对象的副本保留在其“包装器”中,而对于vtkObjects,它仅保留了一个指针。

这些类型的不完整列表如下:vtkVariant,vtkTimeStamp,vtkArrayCoordinates,vtkArrayExtents,vtkArrayExtentsList,vtkArrayRange

自动转换

这些特殊类型可以具有多个构造函数,并且这些构造函数可以用于VTK方法的自动类型转换。例如,vtkVariantArray具有方法InsertNextItem(vtkVariant v),而vtkVariant具有构造函数vtkVariant(int x)。因此,可以这样做:

>>> variantArray.InsertNextItem(1)

包装器将自动从“ 1”构造一个vtkVariant,然后将其作为参数传递给InsertNextItem。

比较和映射

某些特殊类型可以按值排序,而某些可以用作dict键。 排序要求存在比较运算符,例如’<’’<=’’==’’> =’’>’,并且这些运算符不会自动包装。 使用对象作为dict键需要计算哈希值。 vtkVariant和vtkTimeStamp支持比较和哈希处理,其他类型将视情况进行支持。

可以轻松地对所有vtkObject进行哈希处理而又很难对vtk特殊类型进行哈希处理的原因是,vtkObjects是按内存地址进行哈希处理的。 对于特殊类型,不能这样做,因为它们必须按值而不是按地址进行散列。 即 vtkVariant(1)必须与其他所有vtkVariant(1)相等,即使存在各种实例且具有不同的内存地址。

VTK-Python提供的特殊属性

特殊的vtk对象属性:

o.__class__   该对象是其实例的类
o.__doc__     类的描述(从C ++头文件获得)
o.__this__    包含VTK对象地址的字符串

特殊方法属性:

m.__doc__     方法的描述(从C ++头文件获得)

vtk类的特殊属性:

c.__bases__   该类的基类的元组(vtkObject为空)
c.__doc__     类的描述(从C ++头文件获得)
c.__name__    类的名称,与GetClassName()返回的名称相同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值