Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2006 lines
54 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkPythonUtil.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// This include allows VTK to build on some platforms with broken Python
// header files.
#include "vtkPythonUtil.h"
#include "vtkSystemIncludes.h"
#include "vtkObject.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointerBase.h"
#include "vtkTimeStamp.h"
#include "vtkWindows.h"
#include <vtkstd/map>
#include <vtkstd/string>
#if defined ( _MSC_VER )
# define vtkConvertPtrToLong(x) ((long)(PtrToUlong(x)))
#else
# define vtkConvertPtrToLong(x) ((long)(x))
#endif
// The following macro is used to supress missing initializer
// warnings. Python documentation says these should not be necessary.
// We define it as a macro in case the length needs to change across
// python versions.
#if PY_VERSION_HEX >= 0x02030000
#define VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED \
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,
#elif PY_VERSION_HEX >= 0x02020000
#define VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED \
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
#else
#define VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED
#endif
//#define VTKPYTHONDEBUG
//--------------------------------------------------------------------
// There are two hash tables associated with the Python wrappers
class vtkPythonUtil
{
public:
vtkPythonUtil();
~vtkPythonUtil();
vtkstd::map<vtkSmartPointerBase, PyObject*> *ObjectHash;
vtkstd::map<vtkstd::string, PyObject*> *ClassHash;
};
//--------------------------------------------------------------------
vtkPythonUtil *vtkPythonHash = NULL;
//--------------------------------------------------------------------
vtkPythonUtil::vtkPythonUtil()
{
this->ObjectHash = new vtkstd::map<vtkSmartPointerBase, PyObject*>;
this->ClassHash = new vtkstd::map<vtkstd::string, PyObject*>;;
}
//--------------------------------------------------------------------
vtkPythonUtil::~vtkPythonUtil()
{
delete this->ObjectHash;
delete this->ClassHash;
}
//--------------------------------------------------------------------
extern "C" void vtkPythonHashDelete()
{
delete vtkPythonHash;
vtkPythonHash = 0;
}
//--------------------------------------------------------------------
static PyObject *PyVTKObject_PyString(PyVTKObject *self)
{
PyObject *func = PyObject_GetAttrString((PyObject *)self, (char*)"__str__");
if (func)
{
PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
return res;
}
PyErr_Clear();
ostrstream vtkmsg_with_warning_C4701;
self->vtk_ptr->Print(vtkmsg_with_warning_C4701);
vtkmsg_with_warning_C4701.put('\0');
PyObject *res = PyString_FromString(vtkmsg_with_warning_C4701.str());
vtkmsg_with_warning_C4701.rdbuf()->freeze(0);
return res;
}
//--------------------------------------------------------------------
static PyObject *PyVTKObject_PyRepr(PyVTKObject *self)
{
PyObject *func = PyObject_GetAttrString((PyObject *)self, (char*)"__repr__");
if (func)
{
PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
Py_DECREF(func);
return res;
}
PyErr_Clear();
char buf[255];
sprintf(buf,"<%s.%s %s at %p>",
PyString_AsString(self->vtk_class->vtk_module),
PyString_AsString(self->vtk_class->vtk_name),
self->ob_type->tp_name,self);
return PyString_FromString(buf);
}
//--------------------------------------------------------------------
int PyVTKObject_PySetAttr(PyVTKObject *self, PyObject *attr,
PyObject *value)
{
char *name = PyString_AsString(attr);
if (name[0] == '_' && name[1] == '_')
{
if (strcmp(name, "__dict__") == 0)
{
PyErr_SetString(PyExc_RuntimeError,
"__dict__ is a read-only attribute");
return -1;
}
if (strcmp(name, "__class__") == 0)
{
PyErr_SetString(PyExc_RuntimeError,
"__class__ is a read-only attribute");
return -1;
}
}
if (value)
{
PyObject *func = self->vtk_class->vtk_setattr;
if (func)
{
PyObject *args = Py_BuildValue((char*)"(OOO)", self, attr, value);
PyObject *res = PyEval_CallObject(func, args);
Py_DECREF(args);
if (res)
{
Py_DECREF(res);
return 0;
}
return -1;
}
return PyDict_SetItem(self->vtk_dict, attr, value);
}
else
{
PyObject *func = self->vtk_class->vtk_delattr;
if (func)
{
PyObject *args = Py_BuildValue((char*)"(OO)", self, attr);
PyObject *res = PyEval_CallObject(func, args);
Py_DECREF(args);
if (res)
{
Py_DECREF(res);
return 0;
}
return -1;
}
int rv = PyDict_DelItem(self->vtk_dict, attr);
if (rv < 0)
{
PyErr_SetString(PyExc_AttributeError,
"delete non-existing class attribute");
}
return rv;
}
}
//--------------------------------------------------------------------
static PyObject *PyVTKObject_PyGetAttr(PyVTKObject *self, PyObject *attr)
{
char *name = PyString_AsString(attr);
PyVTKClass *pyclass = self->vtk_class;
PyObject *bases;
PyObject *value;
if ((value = PyDict_GetItem(self->vtk_dict, attr)))
{
Py_INCREF(value);
return value;
}
if (name[0] == '_')
{
if (strcmp(name,"__class__") == 0)
{
Py_INCREF(self->vtk_class);
return (PyObject *)self->vtk_class;
}
if (strcmp(name,"__this__") == 0)
{
char buf[256];
sprintf(buf,"p_%s", self->vtk_ptr->GetClassName());
return PyString_FromString(vtkPythonManglePointer(self->vtk_ptr,buf));
}
if (strcmp(name,"__doc__") == 0)
{
Py_INCREF(pyclass->vtk_doc);
return pyclass->vtk_doc;
}
if (strcmp(name,"__dict__") == 0)
{
Py_INCREF(self->vtk_dict);
return self->vtk_dict;
}
/* __methods__ is no longer applicable, methods are in __dict__
if (strcmp(name,"__methods__") == 0)
{
PyMethodDef *meth = pyclass->vtk_methods;
PyObject *lst;
int i, n, m;
n = 0;
if ((lst = PyList_New(0)) == NULL)
{
return NULL;
}
bases = NULL;
while (pyclass != NULL)
{
m = 0;
for (meth = pyclass->vtk_methods; meth && meth->ml_name; meth++)
{
for (i = 0; i < n; i++)
{
if (strcmp(PyString_AsString(PyList_GetItem(lst,i)),
meth->ml_name) == 0)
{
break;
}
}
if (i == n &&
PyDict_GetItemString(self->vtk_dict, meth->ml_name) == 0)
{
if (PyList_Append(lst,PyString_FromString(meth->ml_name)) == -1)
{
Py_DECREF(lst);
return NULL;
}
m++;
}
}
n += m;
bases = pyclass->vtk_bases;
pyclass = NULL;
if (PyTuple_Size(bases))
{
pyclass = (PyVTKClass *)PyTuple_GetItem(bases,0);
}
}
PyList_Sort(lst);
return lst;
}
if (strcmp(name,"__members__") == 0)
{
PyObject *lst;
if ((lst = PyList_New(6)) != NULL)
{
PyList_SetItem(lst,0,PyString_FromString("__class__"));
PyList_SetItem(lst,1,PyString_FromString("__dict__"));
PyList_SetItem(lst,2,PyString_FromString("__doc__"));
PyList_SetItem(lst,3,PyString_FromString("__members__"));
PyList_SetItem(lst,4,PyString_FromString("__methods__"));
PyList_SetItem(lst,5,PyString_FromString("__this__"));
}
return lst;
}
*/
}
while (pyclass != NULL)
{
PyMethodDef *meth;
if (pyclass->vtk_dict == NULL)
{
pyclass->vtk_dict = PyDict_New();
for (meth = pyclass->vtk_methods; meth && meth->ml_name; meth++)
{
PyDict_SetItemString(pyclass->vtk_dict,meth->ml_name,
PyCFunction_New(meth, (PyObject *)pyclass));
}
}
value = PyDict_GetItem(pyclass->vtk_dict, attr);
if (value)
{
if (PyCFunction_Check(value))
{
return PyCFunction_New(((PyCFunctionObject *)value)->m_ml,
(PyObject *)self);
}
else if (PyCallable_Check(value))
{
return PyMethod_New(value, (PyObject *)self,
(PyObject *)self->vtk_class);
}
Py_INCREF(value);
return value;
}
bases = ((PyVTKClass *)pyclass)->vtk_bases;
pyclass = NULL;
if (PyTuple_Size(bases))
{
pyclass = (PyVTKClass *)PyTuple_GetItem(bases,0);
}
}
// try the __getattr__ attribute if set
pyclass = self->vtk_class;
if (pyclass->vtk_getattr)
{
PyObject *args = Py_BuildValue((char*)"(OO)", self, attr);
PyObject *res = PyEval_CallObject(pyclass->vtk_getattr, args);
Py_DECREF(args);
return res;
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
//--------------------------------------------------------------------
class vtkPythonDeleteCommand : public vtkCommand
{
public:
static vtkPythonDeleteCommand *New(PyVTKObject *obj) {
return new vtkPythonDeleteCommand(obj); };
void Execute(vtkObject *caller, unsigned long, void *);
private:
vtkPythonDeleteCommand(PyVTKObject *obj) : Self(obj) {};
PyVTKObject *Self;
};
void vtkPythonDeleteCommand::Execute(vtkObject *caller,
unsigned long vtkNotUsed(id),
void *vtkNotUsed(data))
{
if (this->Self->vtk_ptr != caller)
{
vtkGenericWarningMacro("Python vs. VTK mismatch for " << caller);
return;
}
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_STATE state = PyGILState_Ensure();
#endif
vtkPythonDeleteObjectFromHash((PyObject *)this->Self);
Py_DECREF((PyObject *)this->Self->vtk_class);
Py_DECREF(this->Self->vtk_dict);
#if (PY_MAJOR_VERSION >= 2)
PyObject_Del(this->Self);
#else
PyMem_DEL(this->Self);
#endif
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_Release(state);
#endif
}
//--------------------------------------------------------------------
static void PyVTKObject_PyDelete(PyVTKObject *self)
{
#if PY_VERSION_HEX >= 0x02010000
if (self->vtk_weakreflist != NULL)
{
PyObject_ClearWeakRefs((PyObject *) self);
}
#endif
self->vtk_ptr->Delete();
// the rest of the delection is handled when the VTK-level object
// is destroyed
vtkPythonDeleteObjectFromHash((PyObject *)self);
Py_DECREF((PyObject *)self->vtk_class);
Py_DECREF(self->vtk_dict);
#if (PY_MAJOR_VERSION >= 2)
PyObject_Del(self);
#else
PyMem_DEL(self);
#endif
}
//--------------------------------------------------------------------
static PyTypeObject PyVTKObjectType = {
PyObject_HEAD_INIT(&PyType_Type)
0,
(char*)"vtkobject", // tp_name
sizeof(PyVTKObject), // tp_basicsize
0, // tp_itemsize
(destructor)PyVTKObject_PyDelete, // tp_dealloc
(printfunc)0, // tp_print
(getattrfunc)0, // tp_getattr
(setattrfunc)0, // tp_setattr
(cmpfunc)0, // tp_compare
(reprfunc)PyVTKObject_PyRepr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
(hashfunc)0, // tp_hash
(ternaryfunc)0, // tp_call
(reprfunc)PyVTKObject_PyString, // tp_string
(getattrofunc)PyVTKObject_PyGetAttr, // tp_getattro
(setattrofunc)PyVTKObject_PySetAttr, // tp_setattro
0, // tp_as_buffer
#if PY_VERSION_HEX >= 0x02010000
Py_TPFLAGS_HAVE_WEAKREFS, // tp_flags
#else
0, // tp_flags
#endif
(char*)"A VTK object. Special attributes are: __class__ (the class that this object belongs to), __dict__ (user-controlled attributes), __doc__ (the docstring for the class), __methods__ (a list of all methods for this object), and __this__ (a string that contains the hexidecimal address of the underlying VTK object)", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
#if PY_VERSION_HEX >= 0x02010000
offsetof(PyVTKObject, vtk_weakreflist),// tp_weaklistoffset
#else
0, // tp_weaklistoffset
#endif
VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED
};
int PyVTKObject_Check(PyObject *obj)
{
return (obj->ob_type == &PyVTKObjectType);
}
PyObject *PyVTKObject_New(PyObject *pyvtkclass, vtkObjectBase *ptr)
{
PyVTKClass *vtkclass = (PyVTKClass *)pyvtkclass;
if (ptr)
{
ptr->Register(NULL);
}
else if (vtkclass->vtk_new != NULL)
{
ptr = vtkclass->vtk_new();
}
else
{
PyErr_SetString(PyExc_TypeError,
(char*)"this is an abstract class and cannot be instantiated");
return 0;
}
#if (PY_MAJOR_VERSION >= 2)
PyVTKObject *self = PyObject_New(PyVTKObject, &PyVTKObjectType);
#else
PyVTKObject *self = PyObject_NEW(PyVTKObject, &PyVTKObjectType);
#endif
self->vtk_ptr = ptr;
PyObject *cls = NULL;
vtkstd::map<vtkstd::string, PyObject*>::iterator i =
vtkPythonHash->ClassHash->find(ptr->GetClassName());
if(i != vtkPythonHash->ClassHash->end())
{
cls = i->second;
}
self->vtk_class = (PyVTKClass *)cls;
// If the class was not in the dictionary (i.e. if there is no 'python'
// level class to support the VTK level class) we fall back to this.
if (self->vtk_class == NULL || vtkclass->vtk_methods == NULL)
{
self->vtk_class = vtkclass;
}
Py_INCREF(self->vtk_class);
self->vtk_dict = PyDict_New();
#if PY_VERSION_HEX >= 0x02010000
self->vtk_weakreflist = NULL;
#endif
vtkPythonAddObjectToHash((PyObject *)self, ptr);
/* I'll reinstate this later
ptr->AddObserver(vtkCommand::DeleteEvent,
vtkPythonDeleteCommand::New(self));
*/
return (PyObject *)self;
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_PyString(PyVTKClass *self)
{
char buf[255];
sprintf(buf,"%s.%s",
PyString_AsString(self->vtk_module),
PyString_AsString(self->vtk_name));
return PyString_FromString(buf);
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_PyRepr(PyVTKClass *self)
{
char buf[255];
sprintf(buf,"<%s %s.%s at %p>",self->ob_type->tp_name,
PyString_AsString(self->vtk_module),
PyString_AsString(self->vtk_name),
self);
return PyString_FromString(buf);
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_PyCall(PyVTKClass *self, PyObject *arg,
PyObject *kw)
{
static PyObject *initstr = 0;
if (((PyVTKClass *)self)->vtk_dict)
{
if (initstr == 0)
{
initstr = PyString_FromString("__init__");
}
PyObject *initfunc;
initfunc = PyDict_GetItem(self->vtk_dict, initstr);
if (initfunc)
{
PyObject *obj = PyVTKObject_New((PyObject *)self,NULL);
PyObject *cinitfunc = PyVTKObject_PyGetAttr((PyVTKObject *)obj, initstr);
PyObject *res = PyEval_CallObjectWithKeywords(cinitfunc, arg, kw);
if (res == NULL)
{
Py_DECREF(obj);
obj = NULL;
}
else if (res != Py_None)
{
PyErr_SetString(PyExc_TypeError, "__init__() should return None");
Py_DECREF(obj);
obj = NULL;
}
Py_DECREF(cinitfunc);
return obj;
}
}
if (kw != NULL)
{
PyErr_SetString(PyExc_TypeError,
"this function takes no keyword arguments");
return NULL;
}
if (PyArg_ParseTuple(arg,(char*)""))
{
return PyVTKObject_New((PyObject *)self, NULL);
}
PyErr_Clear();
if (PyArg_ParseTuple(arg,(char*)"O", &arg))
{
return vtkPythonGetObjectFromObject(arg,
PyString_AsString(self->vtk_name));
}
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"function requires 0 or 1 arguments");
return NULL;
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_PyGetAttr(PyVTKClass *self, PyObject *attr)
{
char *name = PyString_AsString(attr);
PyVTKClass *pyclass = self;
PyObject *bases;
while (pyclass != NULL)
{
PyMethodDef *meth;
PyObject *value;
if (pyclass->vtk_dict == NULL)
{
pyclass->vtk_dict = PyDict_New();
for (meth = pyclass->vtk_methods; meth && meth->ml_name; meth++)
{
PyDict_SetItemString(pyclass->vtk_dict,meth->ml_name,
PyCFunction_New(meth, (PyObject *)pyclass));
}
}
value = PyDict_GetItem(pyclass->vtk_dict, attr);
if (value)
{
Py_INCREF(value);
return value;
}
bases = pyclass->vtk_bases;
pyclass = NULL;
if (PyTuple_Size(bases))
{
pyclass = (PyVTKClass *)PyTuple_GetItem(bases,0);
}
}
if (name[0] == '_')
{
pyclass = (PyVTKClass *)self;
if (strcmp(name,"__bases__") == 0)
{
Py_INCREF(pyclass->vtk_bases);
return pyclass->vtk_bases;
}
if (strcmp(name,"__name__") == 0)
{
Py_INCREF(pyclass->vtk_name);
return pyclass->vtk_name;
}
if (strcmp(name,"__module__") == 0)
{
Py_INCREF(pyclass->vtk_module);
return pyclass->vtk_module;
}
if (strcmp(name,"__dict__") == 0 && pyclass->vtk_dict)
{
Py_INCREF(pyclass->vtk_dict);
return pyclass->vtk_dict;
}
if (strcmp(name,"__doc__") == 0)
{
Py_INCREF(pyclass->vtk_doc);
return pyclass->vtk_doc;
}
/* methods are stored in __dict__, so this is irrelevant
if (strcmp(name,"__methods__") == 0)
{
PyMethodDef *meth = pyclass->vtk_methods;
PyObject *lst;
int i, n;
for (n = 0; meth && meth[n].ml_name; n++);
if ((lst = PyList_New(0)) != NULL)
{
meth = pyclass->vtk_methods;
for (i = 0; i < n; i++)
{
if (pyclass->vtk_dict == NULL ||
PyDict_GetItemString(pyclass->vtk_dict, meth[i].ml_name) == 0)
{
PyList_Append(lst, PyString_FromString(meth[i].ml_name));
}
}
PyList_Sort(lst);
}
return lst;
}
if (strcmp(name,"__members__") == 0)
{
int n = 6;
int i = 0;
PyObject *lst;
if (pyclass->vtk_dict)
{
n++;
}
if ((lst = PyList_New(n)) != NULL)
{
PyList_SetItem(lst,i++,PyString_FromString("__bases__"));
if (pyclass->vtk_dict)
{
PyList_SetItem(lst,i++,PyString_FromString("__dict__"));
}
PyList_SetItem(lst,i++,PyString_FromString("__doc__"));
PyList_SetItem(lst,i++,PyString_FromString("__members__"));
PyList_SetItem(lst,i++,PyString_FromString("__methods__"));
PyList_SetItem(lst,i++,PyString_FromString("__module__"));
PyList_SetItem(lst,i++,PyString_FromString("__name__"));
}
return lst;
}
*/
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
//--------------------------------------------------------------------
static void PyVTKClass_PyDelete(PyVTKClass *self)
{
Py_XDECREF(self->vtk_bases);
Py_XDECREF(self->vtk_dict);
Py_XDECREF(self->vtk_name);
Py_XDECREF(self->vtk_getattr);
Py_XDECREF(self->vtk_setattr);
Py_XDECREF(self->vtk_delattr);
Py_XDECREF(self->vtk_module);
Py_XDECREF(self->vtk_doc);
#if (PY_MAJOR_VERSION >= 2)
PyObject_Del(self);
#else
PyMem_DEL(self);
#endif
}
//--------------------------------------------------------------------
static PyObject *PyVTKClassMetaType_GetAttr(PyTypeObject *t, char *name)
{
if (strcmp(name, "__name__") == 0)
{
return PyString_FromString(t->tp_name);
}
if (strcmp(name, "__doc__") == 0)
{
const char *doc = t->tp_doc;
if (doc != NULL)
{
return PyString_FromString(doc);
}
Py_INCREF(Py_None);
return Py_None;
}
if (strcmp(name, "__members__") == 0)
{
return Py_BuildValue((char*)"[ss]", "__doc__", "__name__");
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
//--------------------------------------------------------------------
static PyObject *PyVTKClassMetaType_Repr(PyTypeObject *v)
{
char buf[100];
sprintf(buf, "<type '%.80s'>", v->tp_name);
return PyString_FromString(buf);
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_NewSubclass(PyObject *self, PyObject *args,
PyObject *kw);
//--------------------------------------------------------------------
PyTypeObject PyVTKClassMetaType = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* Number of items for varobject */
(char*)"vtkclass type", /* Name of this type */
sizeof(PyTypeObject), /* Basic object size */
0, /* Item size for varobject */
0, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)PyVTKClassMetaType_GetAttr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)PyVTKClassMetaType_Repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
(ternaryfunc)PyVTKClass_NewSubclass, /*tp_call*/
0, /*tp_str*/
0, /*tp_xxx1*/
0, /*tp_xxx2*/
0, /*tp_xxx3*/
0, /*tp_xxx4*/
(char*)"Define the behavior of a particular type of object.",
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED
};
//--------------------------------------------------------------------
static PyTypeObject PyVTKClassType = {
PyObject_HEAD_INIT(&PyVTKClassMetaType)
0,
(char*)"vtkclass", // tp_name
sizeof(PyVTKClass), // tp_basicsize
0, // tp_itemsize
(destructor)PyVTKClass_PyDelete, // tp_dealloc
(printfunc)0, // tp_print
(getattrfunc)0, // tp_getattr
(setattrfunc)0, // tp_setattr
(cmpfunc)0, // tp_compare
(reprfunc)PyVTKClass_PyRepr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
(hashfunc)0, // tp_hash
(ternaryfunc)PyVTKClass_PyCall, // tp_call
(reprfunc)PyVTKClass_PyString, // tp_string
(getattrofunc)PyVTKClass_PyGetAttr, // tp_getattro
(setattrofunc)0, // tp_setattro
0, // tp_as_buffer
0, // tp_flags
(char*)"A generator for VTK objects. Special attributes are: __bases__ (a tuple of base classes), __dict__ (user-defined methods and attributes), __doc__ (the docstring for the class), __name__ (the name of class), __methods__ (methods for this class, not including inherited methods or user-defined methods), and __module__ (module that the class is defined in).", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED
};
int PyVTKClass_Check(PyObject *obj)
{
return (obj->ob_type == &PyVTKClassType);
}
//--------------------------------------------------------------------
// Concatenate an array of strings into a single string. The resulting
// string is allocated via new. The array of strings must be null-terminated,
// e.g. static char *strings[] = {"string1", "string2", NULL};
static PyObject *vtkBuildDocString(char *docstring[])
{
PyObject *result;
char *data;
int i, j, n;
int *m;
int total = 0;
for (n = 0; docstring[n] != NULL; n++);
m = new int[n];
for (i = 0; i < n; i++)
{
m[i] = static_cast<int>(strlen(docstring[i]));
total += m[i];
}
result = PyString_FromStringAndSize(docstring[0], m[0]);
if (n > 1)
{
_PyString_Resize(&result, total);
}
data = PyString_AsString(result);
j = m[0];
for (i = 1; i < n; i++)
{
strcpy(&data[j], docstring[i]);
j += m[i];
}
delete [] m;
return result;
}
PyObject *PyVTKClass_New(vtknewfunc constructor,
PyMethodDef *methods,
char *classname, char *modulename, char *docstring[],
PyObject *base)
{
static PyObject *modulestr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static int nmodulestr = 10;
PyObject *moduleobj = 0;
PyObject *self = NULL;
int i;
if (vtkPythonHash)
{
vtkstd::map<vtkstd::string, PyObject*>::iterator it =
vtkPythonHash->ClassHash->find(classname);
if(it != vtkPythonHash->ClassHash->end())
{
self = it->second;
}
}
if (self)
{
Py_INCREF(self);
}
else
{
#if (PY_MAJOR_VERSION >= 2)
PyVTKClass *class_self = PyObject_New(PyVTKClass, &PyVTKClassType);
#else
PyVTKClass *class_self = PyObject_NEW(PyVTKClass, &PyVTKClassType);
#endif
self = (PyObject *)class_self;
if (base)
{
class_self->vtk_bases = PyTuple_New(1);
PyTuple_SET_ITEM(class_self->vtk_bases, 0, base);
}
else
{
class_self->vtk_bases = PyTuple_New(0);
}
class_self->vtk_dict = NULL;
class_self->vtk_name = PyString_FromString(classname);
class_self->vtk_getattr = NULL;
class_self->vtk_setattr = NULL;
class_self->vtk_delattr = NULL;
class_self->vtk_methods = methods;
class_self->vtk_new = constructor;
class_self->vtk_doc = vtkBuildDocString(docstring);
// intern the module string
for (i = 0; i < nmodulestr; i++)
{
if (modulestr[i] == 0)
{
modulestr[i] = PyString_InternFromString(modulename);
moduleobj = modulestr[i];
Py_INCREF(moduleobj);
break;
}
else if (strcmp(modulename,PyString_AsString(modulestr[i])) == 0)
{
moduleobj = modulestr[i];
Py_INCREF(moduleobj);
break;
}
}
if (i == nmodulestr)
{
moduleobj = PyString_FromString(modulename);
}
class_self->vtk_module = moduleobj;
vtkPythonAddClassToHash(self,classname);
}
return (PyObject *)self;
}
//--------------------------------------------------------------------
static PyObject *PyVTKClass_NewSubclass(PyObject *, PyObject *args,
PyObject *kw)
{
static const char *kwlist[] = {"name", "bases", "dict", NULL};
PyVTKClass *newclass;
char *classname;
PyObject *globals;
PyObject *bases;
PyVTKClass *base;
PyObject *attributes;
if ((PyArg_ParseTupleAndKeywords(args, kw, (char*)"sOO", (char**)kwlist,
&classname, &bases, &attributes)))
{
if (!PyTuple_Check(bases) || PyTuple_Size(bases) != 1)
{
PyErr_SetString(PyExc_ValueError,
"multiple inheritence is not allowed with VTK classes");
return NULL;
}
base = (PyVTKClass *)PyTuple_GetItem(bases,0);
if (base == 0)
{
PyErr_SetString(PyExc_ValueError,"bases must be a tuple");
return NULL;
}
if (!PyVTKClass_Check((PyObject *)base))
{
PyErr_SetString(PyExc_ValueError,"base class is not a VTK class");
return NULL;
}
if (!PyDict_Check(attributes))
{
PyErr_SetString(PyExc_ValueError,"namespace not provided");
return NULL;
}
if (PyDict_GetItemString(attributes, (char*)"__del__"))
{
PyErr_SetString(PyExc_ValueError, "__del__ attribute is not supported");
return NULL;
}
#if (PY_MAJOR_VERSION >= 2)
newclass = PyObject_New(PyVTKClass, &PyVTKClassType);
#else
newclass = PyObject_NEW(PyVTKClass, &PyVTKClassType);
#endif
Py_INCREF(bases);
Py_INCREF(attributes);
newclass->vtk_bases = bases;
newclass->vtk_dict = attributes;
newclass->vtk_name = PyString_FromString(classname);
newclass->vtk_getattr = PyDict_GetItemString(attributes, (char*)"__getattr__");
if (newclass->vtk_getattr == 0)
{
newclass->vtk_getattr = base->vtk_getattr;
}
Py_XINCREF(newclass->vtk_getattr);
newclass->vtk_setattr = PyDict_GetItemString(attributes, (char*)"__setattr__");
if (newclass->vtk_setattr == 0)
{
newclass->vtk_setattr = base->vtk_setattr;
}
Py_XINCREF(newclass->vtk_setattr);
newclass->vtk_delattr = PyDict_GetItemString(attributes, (char*)"__delattr__");
if (newclass->vtk_delattr == 0)
{
newclass->vtk_delattr = base->vtk_delattr;
}
Py_XINCREF(newclass->vtk_delattr);
newclass->vtk_methods = NULL;
newclass->vtk_new = base->vtk_new;
newclass->vtk_module = NULL;
newclass->vtk_doc = NULL;
globals = PyEval_GetGlobals();
if (globals != NULL)
{
PyObject *modname = PyDict_GetItemString(globals, (char*)"__name__");
if (modname != NULL)
{
Py_INCREF(modname);
newclass->vtk_module = modname;
}
}
if (newclass->vtk_module == NULL)
{
newclass->vtk_module = PyString_FromString("__main__");
}
newclass->vtk_doc = PyDict_GetItemString(attributes, (char*)"__doc__");
if (newclass->vtk_doc)
{
Py_INCREF(newclass->vtk_doc);
PyDict_DelItemString(attributes, (char*)"__doc__");
}
else
{
newclass->vtk_doc = PyString_FromString("");
}
return (PyObject *)newclass;
}
return NULL;
}
//--------------------------------------------------------------------
static PyObject *PyVTKSpecialObject_PyString(PyVTKSpecialObject *self)
{
Py_INCREF(self->vtk_name);
return self->vtk_name;
}
//--------------------------------------------------------------------
static PyObject *PyVTKSpecialObject_PyRepr(PyVTKSpecialObject *self)
{
char buf[255];
sprintf(buf,"<%s %s at %p>", self->ob_type->tp_name,
PyString_AsString(self->vtk_name), self);
return PyString_FromString(buf);
}
//--------------------------------------------------------------------
static PyObject *PyVTKSpecialObject_PyGetAttr(PyVTKSpecialObject *self,
PyObject *attr)
{
char *name = PyString_AsString(attr);
PyMethodDef *meth;
if (name[0] == '_')
{
if (strcmp(name,"__name__") == 0)
{
Py_INCREF(self->vtk_name);
return self->vtk_name;
}
if (strcmp(name,"__doc__") == 0)
{
Py_INCREF(self->vtk_doc);
return self->vtk_doc;
}
if (strcmp(name,"__methods__") == 0)
{
meth = self->vtk_methods;
PyObject *lst;
int i, n;
for (n = 0; meth && meth[n].ml_name; n++);
if ((lst = PyList_New(n)) != NULL)
{
meth = self->vtk_methods;
for (i = 0; i < n; i++)
{
PyList_SetItem(lst, i, PyString_FromString(meth[i].ml_name));
}
PyList_Sort(lst);
}
return lst;
}
if (strcmp(name,"__members__") == 0)
{
PyObject *lst;
if ((lst = PyList_New(4)) != NULL)
{
PyList_SetItem(lst,0,PyString_FromString("__doc__"));
PyList_SetItem(lst,1,PyString_FromString("__members__"));
PyList_SetItem(lst,2,PyString_FromString("__methods__"));
PyList_SetItem(lst,3,PyString_FromString("__name__"));
}
return lst;
}
}
for (meth = self->vtk_methods; meth && meth->ml_name; meth++)
{
if (name[0] == meth->ml_name[0] && strcmp(name+1, meth->ml_name+1) == 0)
{
return PyCFunction_New(meth, (PyObject *)self);
}
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
//--------------------------------------------------------------------
static void PyVTKSpecialObject_PyDelete(PyVTKSpecialObject *self)
{
self->vtk_ptr = NULL;
Py_XDECREF(self->vtk_name);
Py_XDECREF(self->vtk_doc);
#if (PY_MAJOR_VERSION >= 2)
PyObject_Del(self);
#else
PyMem_DEL(self);
#endif
}
//--------------------------------------------------------------------
static PyTypeObject PyVTKSpecialObjectType = {
PyObject_HEAD_INIT(&PyType_Type)
0,
(char*)"vtkspecialobject", // tp_name
sizeof(PyVTKSpecialObject), // tp_basicsize
0, // tp_itemsize
(destructor)PyVTKSpecialObject_PyDelete, // tp_dealloc
(printfunc)0, // tp_print
(getattrfunc)0, // tp_getattr
(setattrfunc)0, // tp_setattr
(cmpfunc)0, // tp_compare
(reprfunc)PyVTKSpecialObject_PyRepr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
(hashfunc)0, // tp_hash
(ternaryfunc)0, // tp_call
(reprfunc)PyVTKSpecialObject_PyString, // tp_string
(getattrofunc)PyVTKSpecialObject_PyGetAttr, // tp_getattro
(setattrofunc)0, // tp_setattro
0, // tp_as_buffer
0, // tp_flags
(char*)"vtkspecialobject - a vtk object not derived from vtkObjectBase.", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
VTK_PYTHON_UTIL_SUPRESS_UNINITIALIZED
};
int PyVTKSpecialObject_Check(PyObject *obj)
{
return (obj->ob_type == &PyVTKSpecialObjectType);
}
PyObject *PyVTKSpecialObject_New(void *ptr, PyMethodDef *methods,
char *classname, char *docstring[])
{
#if (PY_MAJOR_VERSION >= 2)
PyVTKSpecialObject *self = PyObject_New(PyVTKSpecialObject,
&PyVTKSpecialObjectType);
#else
PyVTKSpecialObject *self = PyObject_NEW(PyVTKSpecialObject,
&PyVTKSpecialObjectType);
#endif
self->vtk_ptr = ptr;
self->vtk_methods = methods;
self->vtk_name = PyString_FromString(classname);
self->vtk_doc = vtkBuildDocString(docstring);
return (PyObject *)self;
}
//--------------------------------------------------------------------
vtkObjectBase *PyArg_VTKParseTuple(PyObject *pself, PyObject *args,
char *format, ...)
{
PyVTKObject *self = (PyVTKObject *)pself;
vtkObjectBase *obj = NULL;
va_list va;
va_start(va, format);
/* check if this was called as an unbound method */
if (self->ob_type == &PyVTKClassType)
{
int n = PyTuple_Size(args);
PyVTKClass *vtkclass = (PyVTKClass *)self;
if (n == 0 || (self = (PyVTKObject *)PyTuple_GetItem(args, 0)) == NULL ||
self->ob_type != &PyVTKObjectType ||
!self->vtk_ptr->IsA(PyString_AsString(vtkclass->vtk_name)))
{
char buf[256];
sprintf(buf,"unbound method requires a %s as the first argument",
PyString_AsString(vtkclass->vtk_name));
PyErr_SetString(PyExc_ValueError,buf);
return NULL;
}
// re-slice the args to remove 'self'
args = PyTuple_GetSlice(args,1,n);
if (PyArg_VaParse(args,format,va))
{
obj = self->vtk_ptr;
}
Py_DECREF(args);
}
/* it was called as a bound method */
else
{
if (PyArg_VaParse(args,format,va))
{
obj = self->vtk_ptr;
}
}
return obj;
}
//--------------------------------------------------------------------
void vtkPythonAddClassToHash(PyObject *vtkclass, const char *classname)
{
if (vtkPythonHash == NULL)
{
vtkPythonHash = new vtkPythonUtil();
Py_AtExit(vtkPythonHashDelete);
}
#ifdef VTKPYTHONDEBUG
// vtkGenericWarningMacro("Adding an type " << type << " to hash ptr");
#endif
// lets make sure it isn't already there
vtkstd::map<vtkstd::string, PyObject*>::iterator i =
vtkPythonHash->ClassHash->find(classname);
if(i != vtkPythonHash->ClassHash->end())
{
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Attempt to add type to the hash when already there!!!");
#endif
return;
}
(*vtkPythonHash->ClassHash)[classname] = vtkclass;
#ifdef VTKPYTHONDEBUG
// vtkGenericWarningMacro("Added type to hash type = " << typeObject);
#endif
}
//--------------------------------------------------------------------
void vtkPythonAddObjectToHash(PyObject *obj, vtkObjectBase *ptr)
{
if (vtkPythonHash == NULL)
{
vtkPythonHash = new vtkPythonUtil();
Py_AtExit(vtkPythonHashDelete);
}
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Adding an object to hash ptr = " << ptr);
#endif
((PyVTKObject *)obj)->vtk_ptr = ptr;
(*vtkPythonHash->ObjectHash)[ptr] = obj;
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Added object to hash obj= " << obj << " "
<< ptr);
#endif
}
//--------------------------------------------------------------------
void vtkPythonDeleteObjectFromHash(PyObject *obj)
{
vtkObjectBase *ptr = ((PyVTKObject *)obj)->vtk_ptr;
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Deleting an object from hash obj = " << obj << " "
<< obj->vtk_ptr);
#endif
vtkPythonHash->ObjectHash->erase(ptr);
}
//--------------------------------------------------------------------
static PyObject *vtkFindNearestBase(vtkObjectBase *ptr);
PyObject *vtkPythonGetObjectFromPointer(vtkObjectBase *ptr)
{
PyObject *obj = NULL;
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Checking into pointer " << ptr);
#endif
if (ptr)
{
vtkstd::map<vtkSmartPointerBase, PyObject*>::iterator i =
vtkPythonHash->ObjectHash->find(ptr);
if(i != vtkPythonHash->ObjectHash->end())
{
obj = i->second;
}
if (obj)
{
Py_INCREF(obj);
}
}
else
{
Py_INCREF(Py_None);
obj = Py_None;
}
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Checking into pointer " << ptr << " obj = " << obj);
#endif
if (obj == NULL)
{
PyObject *vtkclass = NULL;
vtkstd::map<vtkstd::string, PyObject*>::iterator i =
vtkPythonHash->ClassHash->find(ptr->GetClassName());
if(i != vtkPythonHash->ClassHash->end())
{
vtkclass = i->second;
}
// if the class was not in the hash, then find the nearest base class
// that is and associate ptr->GetClassName() with that base class
if (vtkclass == NULL)
{
vtkclass = vtkFindNearestBase(ptr);
vtkPythonAddClassToHash(vtkclass, ptr->GetClassName());
}
obj = PyVTKObject_New(vtkclass, ptr);
}
return obj;
}
// this is a helper function to find the nearest base class for an
// object whose class is not in the ClassDict
static PyObject *vtkFindNearestBase(vtkObjectBase *ptr)
{
PyObject *nearestbase = NULL;
int maxdepth = 0;
int depth;
for(vtkstd::map<vtkstd::string, PyObject*>::iterator classes =
vtkPythonHash->ClassHash->begin();
classes != vtkPythonHash->ClassHash->end(); ++classes)
{
PyObject *pyclass = classes->second;
if (ptr->IsA(PyString_AsString(((PyVTKClass *)pyclass)->vtk_name)))
{
PyObject *cls = pyclass;
PyObject *bases = ((PyVTKClass *)pyclass)->vtk_bases;
// count the heirarchy depth for this class
for (depth = 0; PyTuple_Size(bases) != 0; depth++)
{
cls = PyTuple_GetItem(bases,0);
bases = ((PyVTKClass *)cls)->vtk_bases;
}
// we want the class that is furthest from vtkObjectBase
if (depth > maxdepth)
{
maxdepth = depth;
nearestbase = pyclass;
}
}
}
return nearestbase;
}
//--------------------------------------------------------------------
vtkObjectBase *vtkPythonGetPointerFromObject(PyObject *obj,
const char *result_type)
{
vtkObjectBase *ptr;
// convert Py_None to NULL every time
if (obj == Py_None)
{
return NULL;
}
// check to ensure it is a vtk object
if (obj->ob_type != &PyVTKObjectType)
{
obj = PyObject_GetAttrString(obj,(char*)"__vtk__");
if (obj)
{
PyObject *arglist = Py_BuildValue((char*)"()");
PyObject *result = PyEval_CallObject(obj, arglist);
Py_DECREF(arglist);
Py_DECREF(obj);
if (result == NULL)
{
return NULL;
}
if (result->ob_type != &PyVTKObjectType)
{
PyErr_SetString(PyExc_ValueError,"__vtk__() doesn't return a VTK object");
Py_DECREF(result);
return NULL;
}
else
{
ptr = ((PyVTKObject *)result)->vtk_ptr;
Py_DECREF(result);
}
}
else
{
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Object " << obj << " is not a VTK object!!");
#endif
PyErr_SetString(PyExc_ValueError,"method requires a VTK object");
return NULL;
}
}
else
{
ptr = ((PyVTKObject *)obj)->vtk_ptr;
}
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Checking into obj " << obj << " ptr = " << ptr);
#endif
if (ptr->IsA(result_type))
{
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("Got obj= " << obj << " ptr= " << ptr << " " << result_type);
#endif
return ptr;
}
else
{
char error_string[256];
#ifdef VTKPYTHONDEBUG
vtkGenericWarningMacro("vtk bad argument, type conversion failed.");
#endif
sprintf(error_string,"method requires a %s, a %s was provided.",
result_type,((vtkObjectBase *)ptr)->GetClassName());
PyErr_SetString(PyExc_ValueError,error_string);
return NULL;
}
}
PyObject *vtkPythonGetObjectFromObject(PyObject *arg, const char *type)
{
if (PyString_Check(arg))
{
char *ptrText = PyString_AsString(arg);
vtkObjectBase *ptr;
char typeCheck[256]; // typeCheck is currently not used
int i = sscanf(ptrText,"_%lx_%s",(long *)&ptr,typeCheck);
if (i <= 0)
{
i = sscanf(ptrText,"Addr=0x%lx",(long *)&ptr);
}
if (i <= 0)
{
i = sscanf(ptrText,"%lx",(long *)&ptr);
}
if (i <= 0)
{
PyErr_SetString(PyExc_ValueError,"could not extract hexidecimal address from argument string");
return NULL;
}
if (!ptr->IsA(type))
{
char error_string[256];
sprintf(error_string,"method requires a %s address, a %s address was provided.",
type,((vtkObjectBase *)ptr)->GetClassName());
PyErr_SetString(PyExc_TypeError,error_string);
return NULL;
}
return vtkPythonGetObjectFromPointer(ptr);
}
PyErr_SetString(PyExc_TypeError,"method requires a string argument");
return NULL;
}
//--------------------------------------------------------------------
// mangle a void pointer into a SWIG-style string
char *vtkPythonManglePointer(void *ptr, const char *type)
{
static char ptrText[128];
sprintf(ptrText,"_%*.*lx_%s",2*(int)sizeof(void *),2*(int)sizeof(void *),
vtkConvertPtrToLong(ptr),type);
return ptrText;
}
//--------------------------------------------------------------------
// unmangle a void pointer from a SWIG-style string
void *vtkPythonUnmanglePointer(char *ptrText, int *len, const char *type)
{
int i;
void *ptr;
char typeCheck[128];
if (*len < 128)
{
i = sscanf(ptrText,"_%lx_%s",(long *)&ptr,typeCheck);
if (strcmp(type,typeCheck) == 0)
{ // sucessfully unmangle
*len = 0;
return ptr;
}
else if (i == 2)
{ // mangled pointer of wrong type
*len = -1;
return NULL;
}
}
// couldn't unmangle: return string as void pointer if it didn't look
// like a SWIG mangled pointer
return (void *)ptrText;
}
//--------------------------------------------------------------------
// These functions check an array that was sent to a method to see if
// any of the values were changed by the method.
// If a value was changed, then the corresponding value in the python
// list is modified.
template<class T>
static inline
int vtkPythonCheckFloatArray(PyObject *args, int i, T *a, int n)
{
int changed = 0;
PyObject *seq = PyTuple_GET_ITEM(args, i);
for (i = 0; i < n; i++)
{
PyObject *oldobj = PySequence_GetItem(seq, i);
T oldval = (T)PyFloat_AsDouble(oldobj);
Py_DECREF(oldobj);
changed |= (a[i] != oldval);
}
if (changed)
{
for (i = 0; i < n; i++)
{
PyObject *newobj = PyFloat_FromDouble(a[i]);
int rval = PySequence_SetItem(seq, i, newobj);
Py_DECREF(newobj);
if (rval == -1)
{
return -1;
}
}
}
return 0;
}
template<class T>
static inline
int vtkPythonCheckIntArray(PyObject *args, int i, T *a, int n)
{
int changed = 0;
PyObject *seq = PyTuple_GET_ITEM(args, i);
for (i = 0; i < n; i++)
{
PyObject *oldobj = PySequence_GetItem(seq, i);
T oldval = (T)PyInt_AsLong(oldobj);
Py_DECREF(oldobj);
changed |= (a[i] != oldval);
}
if (changed)
{
for (i = 0; i < n; i++)
{
PyObject *newobj = PyInt_FromLong(a[i]);
int rval = PySequence_SetItem(seq, i, newobj);
Py_DECREF(newobj);
if (rval == -1)
{
return -1;
}
}
}
return 0;
}
#if defined(VTK_TYPE_USE_LONG_LONG) || defined(VTK_TYPE_USE___INT64)
template<class T>
static inline
int vtkPythonCheckLongArray(PyObject *args, int i, T *a, int n)
{
int changed = 0;
PyObject *seq = PyTuple_GET_ITEM(args, i);
for (i = 0; i < n; i++)
{
PyObject *oldobj = PySequence_GetItem(seq, i);
T oldval;
if (PyLong_Check(oldobj))
{
#ifdef PY_LONG_LONG
oldval = PyLong_AsLongLong(oldobj);
#else
oldval = PyLong_AsLong(oldobj);
#endif
}
else
{
oldval = PyInt_AsLong(oldobj);
}
Py_DECREF(oldobj);
changed |= (a[i] != oldval);
}
if (changed)
{
for (i = 0; i < n; i++)
{
#if defined(VTK_TYPE_USE_LONG_LONG)
# if defined(PY_LONG_LONG) && (VTK_SIZEOF_LONG != VTK_SIZEOF_LONG_LONG)
PyObject *newobj = PyLong_FromLongLong(a[i]);
# else
PyObject *newobj = PyInt_FromLong((long)a[i]);
# endif
#else
# if defined(PY_LONG_LONG) && (VTK_SIZEOF_LONG != VTK_SIZEOF___INT64)
PyObject *newobj = PyLong_FromLongLong(a[i]);
# else
PyObject *newobj = PyInt_FromLong((long)a[i]);
# endif
#endif
int rval = PySequence_SetItem(seq, i, newobj);
Py_DECREF(newobj);
if (rval == -1)
{
return -1;
}
}
}
return 0;
}
#endif
int vtkPythonCheckArray(PyObject *args, int i, char *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, signed char *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned char *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, short *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned short *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, int *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned int *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, long *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned long *a, int n)
{
return vtkPythonCheckIntArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, float *a, int n)
{
return vtkPythonCheckFloatArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, double *a, int n)
{
return vtkPythonCheckFloatArray(args, i, a, n);
}
#if defined(VTK_TYPE_USE_LONG_LONG)
int vtkPythonCheckArray(PyObject *args, int i, long long *a, int n)
{
return vtkPythonCheckLongArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned long long *a, int n)
{
return vtkPythonCheckLongArray(args, i, a, n);
}
#endif
#if defined(VTK_TYPE_USE___INT64)
int vtkPythonCheckArray(PyObject *args, int i, __int64 *a, int n)
{
return vtkPythonCheckLongArray(args, i, a, n);
}
int vtkPythonCheckArray(PyObject *args, int i, unsigned __int64 *a, int n)
{
return vtkPythonCheckLongArray(args, i, a, n);
}
#endif
//--------------------------------------------------------------------
void vtkPythonVoidFunc(void *arg)
{
PyObject *arglist, *result;
PyObject *func = (PyObject *)arg;
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_STATE state = PyGILState_Ensure();
#endif
arglist = Py_BuildValue((char*)"()");
result = PyEval_CallObject(func, arglist);
Py_DECREF(arglist);
if (result)
{
Py_XDECREF(result);
}
else
{
if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt))
{
cerr << "Caught a Ctrl-C within python, exiting program.\n";
Py_Exit(1);
}
PyErr_Print();
}
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_Release(state);
#endif
}
//--------------------------------------------------------------------
void vtkPythonVoidFuncArgDelete(void *arg)
{
PyObject *func = (PyObject *)arg;
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_STATE state = PyGILState_Ensure();
#endif
if (func)
{
Py_DECREF(func);
}
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_Release(state);
#endif
}
//--------------------------------------------------------------------
vtkPythonCommand::vtkPythonCommand()
{
this->obj = NULL;
}
vtkPythonCommand::~vtkPythonCommand()
{
if (this->obj)
{
Py_DECREF(this->obj);
}
this->obj = NULL;
}
void vtkPythonCommand::SetObject(PyObject *o)
{
this->obj = o;
}
void vtkPythonCommand::Execute(vtkObject *ptr, unsigned long eventtype,
void *CallData)
{
PyObject *arglist, *result, *obj2;
const char *eventname;
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_STATE state = PyGILState_Ensure();
#endif
if (ptr && ptr->GetReferenceCount() > 0)
{
obj2 = vtkPythonGetObjectFromPointer(ptr);
}
else
{
Py_INCREF(Py_None);
obj2 = Py_None;
}
eventname = this->GetStringFromEventId(eventtype);
// extension by Charl P. Botha so that CallData is available from Python:
// * CallData used to be ignored completely: this is not entirely desirable,
// e.g. with catching ErrorEvent
// * I have extended this code so that CallData can be caught whilst not
// affecting any existing VTK Python code
// * make sure your observer python function has a CallDataType string
// attribute that describes how CallData should be passed through, e.g.:
// def handler(theObject, eventType, message):
// print "Error: %s" % (message)
// # we know that ErrorEvent passes a null-terminated string
// handler.CallDataType = "string0"
// someObject.AddObserver('ErrorEvent', handler)
// * At the moment, only string0 is supported as that is what ErrorEvent
// generates.
//
char CallDataTypeLiteral[] = "CallDataType"; // Need char*, not const char*.
PyObject *CallDataTypeObj = PyObject_GetAttrString(this->obj,
CallDataTypeLiteral);
char *CallDataTypeString = NULL;
if (CallDataTypeObj)
{
CallDataTypeString = PyString_AsString(CallDataTypeObj);
if (CallDataTypeString)
{
if (strcmp(CallDataTypeString, "string0") == 0)
{
// this means the user wants the CallData cast as a string
PyObject* CallDataAsString = PyString_FromString((char*)CallData);
if (CallDataAsString)
{
arglist = Py_BuildValue((char*)"(NsN)", obj2, eventname, CallDataAsString);
}
else
{
PyErr_Clear();
// we couldn't create a string, so we pass in None
Py_INCREF(Py_None);
arglist = Py_BuildValue((char*)"(NsN)", obj2, eventname, Py_None);
}
}
else
{
// we don't handle this, so we pass in a None as the third parameter
Py_INCREF(Py_None);
arglist = Py_BuildValue((char*)"(NsN)", obj2, eventname, Py_None);
}
}
else
{
// the handler object has a CallDataType attribute, but it's not a
// string -- then we do traditional arguments
arglist = Py_BuildValue((char*)"(Ns)",obj2,eventname);
}
// we have to do this
Py_DECREF(CallDataTypeObj);
}
else
{
// this means there was no CallDataType attribute, so we do the
// traditional obj(object, eventname) call
PyErr_Clear();
arglist = Py_BuildValue((char*)"(Ns)",obj2,eventname);
}
result = PyEval_CallObject(this->obj, arglist);
Py_DECREF(arglist);
if (result)
{
Py_DECREF(result);
}
else
{
if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt))
{
cerr << "Caught a Ctrl-C within python, exiting program.\n";
Py_Exit(1);
}
PyErr_Print();
}
#if (PY_MAJOR_VERSION > 2) || \
((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
PyGILState_Release(state);
#endif
}
//--------------------------------------------------------------------