Nektar++
VtkWrapper.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: VtkWrapper.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Helper routines from extracting VTK object pointers.
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <vtkPoints.h>
36#include <vtkUnstructuredGrid.h>
37#include <vtkVersion.h>
38
40
41/*
42 * Adapted from the code at:
43 * https://www.paraview.org/Wiki/Example_from_and_to_python_converters
44 */
45
46template <class T> struct vtkObjectPointer_to_python
47{
48 static PyObject *convert(const T &p)
49 {
50 if (p == NULL)
51 {
52 return py::incref(Py_None);
53 }
54 std::ostringstream oss;
55 oss << (vtkObjectBase *)p; // here don't get address
56 std::string address_str = oss.str();
57
58 try
59 {
60 py::object obj = py::import("vtkmodules.vtkCommonCore")
61 .attr("vtkObjectBase")(address_str);
62 return py::incref(obj.ptr());
63 }
64 catch (py::error_already_set &)
65 {
66 // Clear error to avoid potential failure to catch error in
67 // next try-catch block.
68 PyErr_Clear();
69 }
70
71 try
72 {
73 py::object obj =
74 py::import("vtk").attr("vtkObjectBase")(address_str);
75 return py::incref(obj.ptr());
76 }
77 catch (py::error_already_set &)
78 {
80 throw NekError("Unable to import VTK.");
81 }
82
83 return py::incref(py::object().ptr());
84 }
85};
86
87//
88// This python to C++ converter uses the fact that VTK Python objects have an
89// attribute called __this__, which is a string containing the memory address
90// of the VTK C++ object and its class name.
91// E.g. for a vtkPoints object __this__ might be "_0000000105a64420_p_vtkPoints"
92//
93void *extract_vtk_wrapped_pointer(PyObject *obj)
94{
95 std::string thisStr = "__this__";
96
97 // first we need to get the __this__ attribute from the Python Object
98 if (!PyObject_HasAttrString(obj, thisStr.c_str()))
99 {
100 return nullptr;
101 }
102
103 PyObject *thisAttr = PyObject_GetAttrString(obj, thisStr.c_str());
104 if (thisAttr == nullptr)
105 {
106 return nullptr;
107 }
108
109#if PY_MAJOR_VERSION == 2
110 std::string str = PyString_AsString(thisAttr);
111#else
112 std::string str = PyUnicode_AsUTF8(thisAttr);
113#endif
114
115 if (str.size() < 21)
116 {
117 return nullptr;
118 }
119
120 char hex_address[32], *pEnd;
121 auto iter = str.find("_p_vtk");
122
123 if (iter == std::string::npos)
124 {
125 return nullptr;
126 }
127
128 auto className = str.substr(iter).find("vtk");
129 if (className == std::string::npos)
130 {
131 return nullptr;
132 }
133
134 long address = stol(str.substr(1, 17));
135 vtkObjectBase *vtkObject = (vtkObjectBase *)((void *)address);
136
137 if (vtkObject->IsA(str.substr(className).c_str()))
138 {
139 return vtkObject;
140 }
141
142 return nullptr;
143}
144
145#define VTK_PYTHON_CONVERSION(type) \
146 /* register the to-python converter */ \
147 py::to_python_converter<type *, vtkObjectPointer_to_python<type *>>(); \
148 /* register the from-python converter */ \
149 py::converter::registry::insert(&extract_vtk_wrapped_pointer, \
150 py::type_id<type>());
Nektar::ErrorUtil::NekError NekError
void * extract_vtk_wrapped_pointer(PyObject *obj)
Definition: VtkWrapper.hpp:93
static PyObject * convert(const T &p)
Definition: VtkWrapper.hpp:48