混合 VTK 和 SWIG Python

Posted

技术标签:

【中文标题】混合 VTK 和 SWIG Python【英文标题】:mix VTK and SWIG Python 【发布时间】:2012-01-17 16:20:19 【问题描述】:

这是我的课:

#include <vtkPolyData>

class VTKUtilities

Mesh3D MeshfromVTKPolyData(vtkPolyData* pdmesh)

   Mesh3D mesh;
   //...
   //my conversion code to do the actual conversion
   //...
   return mesh;

我尝试通过 SWIG 将其包装到 python 但我尝试像这样在 python 中调用我的函数:

import VTKUtilities
import vtk

pd = vtk.vtkPolyData()
VTKUtilities.MeshfromVTKPolyData(pd)

我收到如下错误:

NotImplementedError: Wrong number of arguments... for VTKUtilities_MeshfromVTKPolyData
...
Possible prototypes are VTKUtilities::MeshfromVTKPolyData(vtkPolyData *);

我一直在阅读有关类型映射的一些内容,但我认为我不必纠结它,因为 SWIG 应该为我处理这个问题? 有人能告诉我我的流量广告中缺少什么可能需要修复吗?

【问题讨论】:

VTK 不是已经为您提供了 Python 接口(通过 SWIG 生成)吗? 确实如此,但我的情况是我有一些用 swig 为 python 包装的外部代码。例如上面的 mesh3D 来自外部,我希望它与 vtks WrapVTK 进行通信。 这对我来说也是一次很好的学习经历... 那么您是否尝试扩充现有的 vtk 接口?您可以在问题中编辑显示您的.i 文件吗?我怀疑你实际上有两个不同的包装器包装相同的类型,需要小心使用%import 来解决这个问题(swig.org/Doc1.3/Modules.html 你在林地。我想知道是否可以混合两个包装纸?即我用自己的包装编译了VTK,然后我们有一些使用一些vtk库的外部代码,我们用swig包装这个项目。以前有人试过吗? 【参考方案1】:

我通过这种方式成功包装了参数为 vtkPolyData 的函数:

首先,您必须在 swig .i 文件中包含 vtkPythonUtil:

%

#include <vtkPythonUtil.h>

%

然后,您必须在 swig .i 文件中映射 vtkPolydata:

 %typemap(out) vtkPolyData* 

    PyImport_ImportModule("vtk");

    $result = vtkPythonUtil::GetObjectFromPointer ( (vtkPolyData*)$1 );
 

%typemap(in) vtkPolyData* 

    $1 = (vtkPolyData*) vtkPythonUtil::GetPointerFromObject ( $input, "vtkPolyData" );

    if ( $1 == NULL )  SWIG_fail; 

我在 ITK itkVTKGlue 中发现了这一点。

最后,你需要将你的模块链接到库vtkPythonCore

【讨论】:

【参考方案2】:

这是一个vtk.i,为 VTK 的类提供 SWIG 类型映射,并为您的项目中定义的类提供内存管理挂钩,这些类派生自 SWIG 包装的 VTK 对象。

代码

这里是完整的代码。这是用 VTK 8 和 SWIG 3.7 测试的。请注意,以上链接包含示例,并且可能包含未来的更新。

/*
vtk.i a SWIG interface to VTK classes
Copyright (C)  2017 Burlen Loring

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
%
#include <vtkPythonUtil.h>
%

%include "exception.i"

/*---------------------------------------------------------------------------
macro: VTK_SWIG_INTEROP(vtk_t)

arguments:
  vtk_t - a VTK class name that is used in the SWIG generated API.

The macro defines the typemaps needed for SWIG to convert to and
from VTK's Python bindings. Use this when your API containes pointers
to classes defined in VTK.
---------------------------------------------------------------------------*/
%define VTK_SWIG_INTEROP(vtk_t)
%
#include <vtk_t##.h>
%
%typemap(out) vtk_t*

  $result = vtkPythonUtil::GetObjectFromPointer(
    static_cast<vtkObjectBase*>($1));

%typemap(in) vtk_t*

  $1 = static_cast<vtk_t*>(
    vtkPythonUtil::GetPointerFromObject($input,#vtk_t));
  if (!$1)
  
    SWIG_exception(SWIG_TypeError,
      "an object of type " #vtk_t " is required");
  

%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) vtk_t*

  $1 = vtkPythonUtil::GetPointerFromObject($input,#vtk_t) ? 1 : 0;

%enddef

/*---------------------------------------------------------------------------
macro: VTK_DERIVED(derived_t)

arguments:
  derived_t - name of a class that derives from vtkObjectBase.

The macro causes SWIG to wrap the class and defines memory management hooks
that prevent memory leaks when SWIG creates the objects. Use this to wrap
VTK classes defined in your project.
---------------------------------------------------------------------------*/
%define VTK_DERIVED(derived_t)
%
#include <derived_t##.h>
%
%feature("ref") derived_t "$this->Register(nullptr);"
%feature("unref") derived_t "$this->UnRegister(nullptr);"
%newobject derived_t##::New();
%include <derived_t##.h>
%enddef

如果您的 API 使用 vtkObjectBase 和 vtkDataObject 您的 SWIG .i 文件将包括:

VTK_SWIG_INTEROP(vtkObjectBase)
VTK_SWIG_INTEROP(vtkDataObject)

每个 VTK 类都会有一个宏调用出现在您的 API 中。

示例用法

如果您定义一个派生自 vtkObject 的类或其一个名为 DataAdaptor 的子类,您的 SWIG .i 文件将包括:

VTK_DERIVED(DataAdaptor)

请注意,您还需要为您的类 API 中的任何 VTK 类调用 VTK_SWIG_INTEROP,包括 vtkObjectBase。

【讨论】:

好的,感谢您的反馈。我希望我的编辑解决了您的问题。

以上是关于混合 VTK 和 SWIG Python的主要内容,如果未能解决你的问题,请参考以下文章

C++ 与 Python 混合编程

CMake - SWIG - 移植动态库

SWIG Python 绑定到本地代码不适用于 OpenCV 2.1

SWIG:返回原始指针与共享 ptrs 的向量

QT Designer config

Python混合图片操作