How to wrap VTK-derived C++ function for Python

Is there any place I can find a working example to wrap a C++ function (using VTK) to be used by Python?

Searched and found this page mix VTK and SWIG Python but there is no compiling details, and this simple example on this page https://public.kitware.com/pipermail/vtkusers/2002-October/013980.html

But for my system Ubuntu 16.04, vtk 8.2.0, Python 3.6.8, I could not make the example work. I have to modify them to let the compiling done without error.

Details: #============simple.cpp===================

// simple.c
//based on https://public.kitware.com/pipermail/vtkusers/2002-October/013980.html
#include "Python.h"
#include "vtkPythonUtil.h"
#include "vtkObject.h"
#include "vtkObjectBase.h"
#include <stdio.h>
#include "vtkRenderer.h"

extern "C" 
{
   static PyObject* simple_vtk_function(PyObject *self, PyObject *args);
}


static PyObject* simple_vtk_function(PyObject *self, PyObject *args)
{
   PyObject *vtkpy;
   if (!PyArg_ParseTuple(args, "O", &vtkpy))
     return NULL;
   
   vtkObjectBase *obj = vtkPythonUtil::GetPointerFromObject(vtkpy,"PyObject");
   /* Do what you want to do here. */
   //printf("%s\n", obj->GetClassName());
   
   printf("inside module simple_vtk, function simple_vtk_function\n");
   
   Py_RETURN_NONE;
}
static char simple_docs[] =
   "simple( ): Any message you want to put here!!\n";

static PyMethodDef module_methods[] = 
{
    {
      "simple_vtk_function", (PyCFunction) simple_vtk_function, 
     METH_VARARGS, simple_docs
    },
    {NULL}
};

static struct PyModuleDef simple_vtk =
  {
    PyModuleDef_HEAD_INIT,
    "simple_vtk",/* name of module */
    "",/* module documentation, may be NULL */
    -1,
    module_methods
  };


PyMODINIT_FUNC PyInit_simple_vtk(void)
{
    return PyModule_Create(&simple_vtk);
}

#============setup.py===================

#!/usr/bin/env python3
import distutils.core as dc
module = dc.Extension('simple_vtk',
                      sources = ['simple.cpp'],
                      include_dirs=['/usr/local/include/vtk-8.2'],
                      libraries_dirs = ['/usr/local/include/vtk-8.2'],
                      #libraries=['vtkPythonUtil']
)
dc.setup(name = 'simple_vtk',
         version = '1.0',
         ext_modules = [module])

compile command

CFLAGS="-std=c++11" python setup.py build

and get this printing out

/home/jun/anaconda3/lib/python3.6/distutils/extension.py:131: UserWarning: Unknown Extension options: 'libraries_dirs'
  warnings.warn(msg)
running build
running build_ext
building 'simple_vtk' extension
gcc -pthread -B /home/jun/anaconda3/compiler_compat -Wl,--sysroot=/ -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -std=c++11 -fPIC -I/usr/local/include/vtk-8.2 -I/home/jun/anaconda3/include/python3.6m -c simple.cpp -o build/temp.linux-x86_64-3.6/simple.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
simple.cpp: In function ‘PyObject* simple_vtk_function(PyObject*, PyObject*)’:
simple.cpp:22:19: warning: unused variable ‘obj’ [-Wunused-variable]
    vtkObjectBase *obj = vtkPythonUtil::GetPointerFromObject(vtkpy,"PyObject");
                   ^
g++ -pthread -shared -B /home/jun/anaconda3/compiler_compat -L/home/jun/anaconda3/lib -Wl,-rpath=/home/jun/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ -std=c++11 build/temp.linux-x86_64-3.6/simple.o -o build/lib.linux-x86_64-3.6/simple_vtk.cpython-36m-x86_64-linux-gnu.so

to test in python

>>> import simple_vtk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/jun/project/play/swig/for_vtk_v2/simple_vtk.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN13vtkPythonUtil20GetPointerFromObjectEP7_objectPKc

Always got error

undefined symbol: _ZN13vtkPythonUtil20GetPointerFromObjectEP7_objectPKc

The C++ function is so simple, it just to convert a PyObject and convert to vtkObjectBase. I didn’t even remove the simple print printf("%s\n", obj->GetClassName());

But I could never make it work. I think it is a common need for people to wrap a custom C++ vtk function for Python, a little bit surpring there is almost no woring example on internet. Could you please help me on this? Thanks!

What do you mean by “a custom C++ vtk function”? VTK is mainly a library of C++ classes and those classes are wrapped in Python using a builtin mechanism (not SWIG) which is driven by a set of CMake macros. If you develop some new VTK-derived classes, you should be able to easily wrap them as well if your classes are organised as a custom VTK module. Does it make sense to you?

Thanks for your reply and explanation.
Have learned VTK has its own wrap macro also from here

What I described was not clear. Yes I mean, how to wrap a new VTK-derived classes? Is there a simplest example available?

Could you please give some indication which CMake file to look at for this topic, in VTK downloaed package? Is it CMake/vtkWrapPython.cmake ? Thanks.

In the latest release, there is code in CMake/vtkModule.cmake (basic wrapping infrastructure) and CMake/vtkModuleWrapPython.cmake for Python-specific bits. Note that the VTK-provided APIs assume you’re using the CMake infrastucture provided by VTK as well.