问题
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