|
51 | 51 | %module(package="itk",threads="1") VtkGluePython |
52 | 52 |
|
53 | 53 | %{ |
54 | | -#include "vtkPythonUtil.h" |
55 | | -#include "vtkVersion.h" |
56 | | -#if (VTK_MAJOR_VERSION > 5 ||((VTK_MAJOR_VERSION == 5)&&(VTK_MINOR_VERSION > 6))) |
57 | | -#define vtkPythonGetObjectFromPointer vtkPythonUtil::GetObjectFromPointer |
58 | | -#define vtkPythonGetPointerFromObject vtkPythonUtil::GetPointerFromObject |
59 | | -#endif |
| 54 | +#include <cinttypes> |
| 55 | +#include <cstdio> |
| 56 | +#include <cstring> |
| 57 | + |
| 58 | +// Pointer exchange with VTK's Python layer using only the Limited API, so this |
| 59 | +// module stays abi3 and needs no link against VTK::WrappingPythonCore. |
| 60 | +namespace itkVtkGlueABI3 |
| 61 | +{ |
| 62 | + |
| 63 | +// Parses the `_<hex>_p_<ClassName>` encoding VTK publishes as `__this__`. |
| 64 | +inline void * |
| 65 | +GetPointerFromObject(PyObject * obj, const char * className) |
| 66 | +{ |
| 67 | + PyObject * thisStr = PyObject_GetAttrString(obj, "__this__"); |
| 68 | + if (!thisStr) |
| 69 | + { |
| 70 | + PyErr_Clear(); |
| 71 | + PyErr_Format(PyExc_TypeError, "expected a VTK %s instance", className); |
| 72 | + return nullptr; |
| 73 | + } |
| 74 | + |
| 75 | + void * ptr = nullptr; |
| 76 | + Py_ssize_t len = 0; |
| 77 | + const char * s = PyUnicode_AsUTF8AndSize(thisStr, &len); |
| 78 | + if (s && len > 4 && s[0] == '_' && std::strlen(s) == static_cast<size_t>(len)) |
| 79 | + { |
| 80 | + const char * sep = std::strstr(s + 1, "_p_"); |
| 81 | + if (sep && std::strcmp(sep + 3, className) == 0) |
| 82 | + { |
| 83 | + std::uintptr_t addr = 0; |
| 84 | + // '_' is not a hex digit, so the conversion stops at the separator. |
| 85 | + if (std::sscanf(s + 1, "%" SCNxPTR, &addr) == 1 && addr != 0) |
| 86 | + { |
| 87 | + ptr = reinterpret_cast<void *>(addr); |
| 88 | + } |
| 89 | + } |
| 90 | + } |
| 91 | + Py_DECREF(thisStr); |
| 92 | + |
| 93 | + if (!ptr) |
| 94 | + { |
| 95 | + PyErr_Format(PyExc_TypeError, "expected a VTK %s instance", className); |
| 96 | + } |
| 97 | + return ptr; |
| 98 | +} |
| 99 | + |
| 100 | +// Reconstructs through VTK's own `Addr=0x...` path so the IsA() check, the |
| 101 | +// object map, and reference counting all stay VTK's responsibility. |
| 102 | +// `__new__` is called explicitly rather than `cls(addr)`: vtkmodules.util.data_model |
| 103 | +// registers keyword-only `override` subclasses for the data-model classes, whose |
| 104 | +// __init__ would reject the positional address string. |
| 105 | +inline PyObject * |
| 106 | +GetObjectFromPointer(void * ptr, const char * moduleName, const char * className) |
| 107 | +{ |
| 108 | + if (!ptr) |
| 109 | + { |
| 110 | + Py_RETURN_NONE; |
| 111 | + } |
| 112 | + |
| 113 | + PyObject * mod = PyImport_ImportModule(moduleName); |
| 114 | + if (!mod) |
| 115 | + { |
| 116 | + return nullptr; |
| 117 | + } |
| 118 | + PyObject * cls = PyObject_GetAttrString(mod, className); |
| 119 | + Py_DECREF(mod); |
| 120 | + if (!cls) |
| 121 | + { |
| 122 | + return nullptr; |
| 123 | + } |
| 124 | + |
| 125 | + char addr[64]; |
| 126 | + std::snprintf(addr, sizeof(addr), "Addr=0x%" PRIxPTR, reinterpret_cast<std::uintptr_t>(ptr)); |
| 127 | + PyObject * obj = PyObject_CallMethod(cls, "__new__", "Os", cls, addr); |
| 128 | + Py_DECREF(cls); |
| 129 | + return obj; |
| 130 | +} |
| 131 | + |
| 132 | +} // namespace itkVtkGlueABI3 |
60 | 133 | %} |
61 | 134 |
|
62 | 135 | %typemap(out) vtkImageExport* { |
63 | | - PyImport_ImportModule("vtk"); |
64 | | - $result = vtkPythonGetObjectFromPointer ( (vtkImageExport*)$1 ); |
| 136 | + $result = itkVtkGlueABI3::GetObjectFromPointer($1, "vtkmodules.vtkIOImage", "vtkImageExport"); |
| 137 | + if (!$result) { SWIG_fail; } |
65 | 138 | } |
66 | 139 |
|
67 | 140 | %typemap(out) vtkImageImport* { |
68 | | - PyImport_ImportModule("vtk"); |
69 | | - $result = vtkPythonGetObjectFromPointer ( (vtkImageImport*)$1 ); |
| 141 | + $result = itkVtkGlueABI3::GetObjectFromPointer($1, "vtkmodules.vtkIOImage", "vtkImageImport"); |
| 142 | + if (!$result) { SWIG_fail; } |
70 | 143 | } |
71 | 144 |
|
72 | 145 | %typemap(out) vtkImageData* { |
73 | | - PyImport_ImportModule("vtk"); |
74 | | - $result = vtkPythonGetObjectFromPointer ( (vtkImageData*)$1 ); |
| 146 | + $result = itkVtkGlueABI3::GetObjectFromPointer($1, "vtkmodules.vtkCommonDataModel", "vtkImageData"); |
| 147 | + if (!$result) { SWIG_fail; } |
75 | 148 | } |
76 | 149 |
|
77 | 150 | %typemap(in) vtkImageData* { |
78 | | - $1 = NULL; |
79 | | - $1 = (vtkImageData*) vtkPythonGetPointerFromObject ( $input, "vtkImageData" ); |
80 | | - if ( $1 == NULL ) { SWIG_fail; } |
| 151 | + $1 = static_cast<vtkImageData *>(itkVtkGlueABI3::GetPointerFromObject($input, "vtkImageData")); |
| 152 | + if (!$1) { SWIG_fail; } |
81 | 153 | } |
82 | 154 |
|
83 | 155 | %typemap(out) vtkPolyData* { |
84 | | - PyImport_ImportModule("vtk"); |
85 | | - $result = vtkPythonGetObjectFromPointer ( (vtkPolyData*)$1 ); |
| 156 | + $result = itkVtkGlueABI3::GetObjectFromPointer($1, "vtkmodules.vtkCommonDataModel", "vtkPolyData"); |
| 157 | + if (!$result) { SWIG_fail; } |
86 | 158 | } |
87 | 159 |
|
88 | 160 | %typemap(in) vtkPolyData* { |
89 | | - $1 = NULL; |
90 | | - $1 = (vtkPolyData*) vtkPythonGetPointerFromObject ( $input, "vtkPolyData" ); |
91 | | - if ( $1 == NULL ) { SWIG_fail; } |
| 161 | + $1 = static_cast<vtkPolyData *>(itkVtkGlueABI3::GetPointerFromObject($input, "vtkPolyData")); |
| 162 | + if (!$1) { SWIG_fail; } |
92 | 163 | } |
93 | 164 | #endif |
94 | 165 |
|
|
0 commit comments