mix VTK and SWIG Python

混江龙づ霸主 提交于 2021-02-07 09:33:47

问题


Here is my class:

#include <vtkPolyData>

class VTKUtilities

Mesh3D MeshfromVTKPolyData(vtkPolyData* pdmesh)
{
   Mesh3D mesh;
   //...
   //my conversion code to do the actual conversion
   //...
   return mesh;
}

I tried wrapping this to python by SWIG but I try to call my function in python like this:

import VTKUtilities
import vtk

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

I get errors like :

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

I have been reading something about typemaps but I thought I didn't have to mess with that as SWIG should handle this for me ?
Can someone tell me what is missing in my flow ad possibly some fix ?


回答1:


I succeed to wrapping functions whose arguments are vtkPolyData by doing this way:

First, you have to include vtkPythonUtil in swig .i file:

%{

#include <vtkPythonUtil.h>

}%

Then, you have to map the vtkPolydata in the swig .i file:

 %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; }
}

I find that in ITK itkVTKGlue.

Finally, you need to link your module with the library vtkPythonCore




回答2:


Here is a vtk.i providing SWIG typemaps for VTK's classes and memory management hooks for classes defined within your project derived from VTK Objects wrapped by SWIG.

Code

here is the code in its entirety. this is tested with VTK 8 and SWIG 3.7. Note that the above link includes examples and may include future updates.

/*
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

If your API makes use of vtkObjectBase and vtkDataObject your SWIG .i file would include:

VTK_SWIG_INTEROP(vtkObjectBase)
VTK_SWIG_INTEROP(vtkDataObject)

There will be one macro invocation per VTK class appearing in your API.

Example usage

If you define a class derived from vtkObject or one of its subclasses called DataAdaptor your SWIG .i file would include:

VTK_DERIVED(DataAdaptor)

Note that you will also need to call VTK_SWIG_INTEROP for any VTK classes in your class's API including vtkObjectBase.



来源:https://stackoverflow.com/questions/8898041/mix-vtk-and-swig-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!