Commit f055428b authored by Scott Wittenburg's avatar Scott Wittenburg

Provide a simple python Context2D item, similar to vtkPythonAlgorithm

parent 74d94885
set(module_SRCS
vtkPythonItem.cxx
)
vtk_module_library(vtkPythonContext2D ${module_SRCS})
if (VTK_WRAP_PYTHON)
vtk_module(vtkPythonContext2D
GROUPS
StandAlone
COMPILE_DEPENDS
vtkPython
OPTIONAL_PYTHON_LINK
EXCLUDE_FROM_JAVA_WRAPPING
TEST_DEPENDS
vtkTestingCore
KIT
vtkWrapping
DEPENDS
vtkRenderingContext2D
PRIVATE_DEPENDS
vtkCommonCore
vtkWrappingPythonCore
)
endif ()
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPythonItem.cxx
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.
=========================================================================*/
#include "vtkPythonItem.h"
#include "vtkObjectFactory.h"
#include "vtkContext2D.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkPythonUtil.h"
#include "vtkSmartPyObject.h"
vtkStandardNewMacro(vtkPythonItem);
//------------------------------------------------------------------------------
void vtkPythonItem::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
vtkPythonScopeGilEnsurer gilEnsurer;
vtkSmartPyObject str;
if (this->Object)
{
str.TakeReference(PyObject_Str(this->Object));
}
os << indent << "Object: " << Object << std::endl;
if (str)
{
os << indent << "Object (string): ";
#ifndef VTK_PY3K
os << PyString_AsString(str);
#else
PyObject *bytes = PyUnicode_EncodeLocale(str, VTK_PYUNICODE_ENC);
if (bytes)
{
os << PyBytes_AsString(bytes);
Py_DECREF(bytes);
}
#endif
os << std::endl;
}
}
//------------------------------------------------------------------------------
vtkPythonItem::vtkPythonItem()
{
this->Object = nullptr;
}
//------------------------------------------------------------------------------
vtkPythonItem::~vtkPythonItem()
{
// we check if Python is still initialized since the Python interpreter may
// have been finalized before the VTK object is released.
if (Py_IsInitialized())
{
vtkPythonScopeGilEnsurer gilEnsurer;
Py_XDECREF(this->Object);
}
}
// This macro gets the method passed in as the parameter method
// from the PyObject passed in as the parameter obj and creates a
// vtkSmartPyObject variable with the name passed in as the parameter
// var containing that method's PyObject. If obj is nullptr, obj.method
// does not exist or obj.method is not a callable method, this macro
// causes the function using it to return with the return value
// passed in as the parameter failValue
// var - the name of the resulting vtkSmartPyObject with the
// method object in it. Can be used in the code following
// the macro's use as the variable name
// obj - the PyObject to get the method from
// method - the name of the method to look for. Should be a
// C string.
// failValue - the value to return if the lookup fails and the
// function using the macro should return. Pass in a
// block comment /**/ for void functions using this macro
#define VTK_GET_METHOD(var, obj, method, failValue) \
if (!(obj)) \
{ \
return failValue; \
} \
vtkSmartPyObject var(PyObject_GetAttrString(obj, method)); \
if (!(var)) \
{ \
return failValue; \
} \
if (!PyCallable_Check(var)) \
{ \
return failValue; \
}
//------------------------------------------------------------------------------
static PyObject* VTKToPython(vtkObjectBase* obj)
{
// Return value: New reference.
return vtkPythonUtil::GetObjectFromPointer(obj);
}
//------------------------------------------------------------------------------
bool vtkPythonItem::CheckResult(const char* method, const vtkSmartPyObject &res)
{
vtkPythonScopeGilEnsurer gilEnsurer;
if (!res)
{
vtkErrorMacro("Failure when calling method: \"" << method << "\":");
if (PyErr_Occurred() != nullptr)
{
PyErr_Print();
PyErr_Clear();
}
return false;
}
if (!PyBool_Check(res))
{
vtkWarningMacro("The method \"" << method << "\" should have returned boolean but did not")
return false;
}
if (res == Py_False)
{
return false;
}
return true;
}
//------------------------------------------------------------------------------
void vtkPythonItem::SetPythonObject(PyObject* obj)
{
vtkPythonScopeGilEnsurer gilEnsurer;
if (!obj)
{
return;
}
Py_XDECREF(this->Object);
this->Object = obj;
Py_INCREF(this->Object);
char mname[] = "Initialize";
VTK_GET_METHOD(method, this->Object, mname, /* no return */)
vtkSmartPyObject args(PyTuple_New(1));
PyObject* vtkself = VTKToPython(this);
PyTuple_SET_ITEM(args.GetPointer(), 0, vtkself);
vtkSmartPyObject result(PyObject_Call(method, args, nullptr));
CheckResult(mname, result);
}
//------------------------------------------------------------------------------
bool vtkPythonItem::Paint(vtkContext2D *painter)
{
vtkPythonScopeGilEnsurer gilEnsurer;
char mname[] = "Paint";
VTK_GET_METHOD(method, this->Object, mname, 0)
vtkSmartPyObject args(PyTuple_New(2));
PyObject* vtkself = VTKToPython(this);
PyTuple_SET_ITEM(args.GetPointer(), 0, vtkself);
PyObject* pypainter = VTKToPython(painter);
PyTuple_SET_ITEM(args.GetPointer(), 1, pypainter);
vtkSmartPyObject result(PyObject_Call(method, args, nullptr));
return CheckResult(mname, result);
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPythonItem.h
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.
=========================================================================*/
/**
* @class vtkPythonItem
* @brief A vtkContextItem that can be implemented in Python
*
*
* This class allows implementation of arbitrary context items in Python.
*
* @sa
* vtkAbstractContextItem
*/
#ifndef vtkPythonItem_h
#define vtkPythonItem_h
#if !defined(__VTK_WRAP__) || defined(__VTK_WRAP_HIERARCHY__) || defined(__VTK_WRAP_PYTHON__)
#include "vtkPython.h" // Must be first
#include "vtkPythonContext2DModule.h" // For export macro
#include "vtkContextItem.h"
class vtkSmartPyObject;
class VTKPYTHONCONTEXT2D_EXPORT vtkPythonItem : public vtkContextItem
{
public:
vtkTypeMacro(vtkPythonItem, vtkContextItem);
void PrintSelf(ostream &os, vtkIndent indent) override;
static vtkPythonItem * New();
/**
* Specify the Python object to use to operate on the data. A reference will
* be taken on the object. This will also invoke Initialize() on the Python
* object, providing an opportunity to perform tasks commonly done in the
* constructor of C++ vtkContextItem subclasses.
*/
void SetPythonObject(PyObject* obj);
bool Paint(vtkContext2D *painter) override;
protected:
vtkPythonItem();
~vtkPythonItem() override;
private:
vtkPythonItem(const vtkPythonItem &) = delete;
void operator=(const vtkPythonItem &) = delete;
bool CheckResult(const char* method, const vtkSmartPyObject& res);
PyObject* Object;
};
#endif // #ifndef vtkPythonItem_h
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment