#include "src/_contour.h"
#include "src/mplutils.h"
#include "src/py_exceptions.h"
/* QuadContourGenerator */
typedef struct
{
PyObject_HEAD
QuadContourGenerator* ptr;
} PyQuadContourGenerator;
static PyTypeObject PyQuadContourGeneratorType;
static PyObject* PyQuadContourGenerator_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
{
PyQuadContourGenerator* self;
self = (PyQuadContourGenerator*)type->tp_alloc(type, 0);
self->ptr = NULL;
return (PyObject*)self;
}
const char* PyQuadContourGenerator_init__doc__ =
"QuadContourGenerator(x, y, z, mask, corner_mask, chunk_size)\n"
"\n"
"Create a new C++ QuadContourGenerator object\n";
static int PyQuadContourGenerator_init(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
{
QuadContourGenerator::CoordinateArray x, y, z;
QuadContourGenerator::MaskArray mask;
int corner_mask;
long chunk_size;
if (!PyArg_ParseTuple(args, "O&O&O&O&il",
&x.converter_contiguous, &x,
&y.converter_contiguous, &y,
&z.converter_contiguous, &z,
&mask.converter_contiguous, &mask,
&corner_mask,
&chunk_size)) {
return -1;
}
if (x.empty() || y.empty() || z.empty() ||
y.dim(0) != x.dim(0) || z.dim(0) != x.dim(0) ||
y.dim(1) != x.dim(1) || z.dim(1) != x.dim(1)) {
PyErr_SetString(PyExc_ValueError,
"x, y and z must all be 2D arrays with the same dimensions");
return -1;
}
if (z.dim(0) < 2 || z.dim(1) < 2) {
PyErr_SetString(PyExc_ValueError,
"x, y and z must all be at least 2x2 arrays");
return -1;
}
// Mask array is optional, if set must be same size as other arrays.
if (!mask.empty() && (mask.dim(0) != x.dim(0) || mask.dim(1) != x.dim(1))) {
PyErr_SetString(PyExc_ValueError,
"If mask is set it must be a 2D array with the same dimensions as x.");
return -1;
}
CALL_CPP_INIT("QuadContourGenerator",
(self->ptr = new QuadContourGenerator(
x, y, z, mask, corner_mask, chunk_size)));
return 0;
}
static void PyQuadContourGenerator_dealloc(PyQuadContourGenerator* self)
{
delete self->ptr;
Py_TYPE(self)->tp_free((PyObject *)self);
}
const char* PyQuadContourGenerator_create_contour__doc__ =
"create_contour(level)\n"
"\n"
"Create and return a non-filled contour.";
static PyObject* PyQuadContourGenerator_create_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
{
double level;
if (!PyArg_ParseTuple(args, "d:create_contour", &level)) {
return NULL;
}
PyObject* result;
CALL_CPP("create_contour", (result = self->ptr->create_contour(level)));
return result;
}
const char* PyQuadContourGenerator_create_filled_contour__doc__ =
"create_filled_contour(lower_level, upper_level)\n"
"\n"
"Create and return a filled contour";
static PyObject* PyQuadContourGenerator_create_filled_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
{
double lower_level, upper_level;
if (!PyArg_ParseTuple(args, "dd:create_filled_contour",
&lower_level, &upper_level)) {
return NULL;
}
if (lower_level >= upper_level)
{
PyErr_SetString(PyExc_ValueError,
"filled contour levels must be increasing");
return NULL;
}
PyObject* result;
CALL_CPP("create_filled_contour",
(result = self->ptr->create_filled_contour(lower_level,
upper_level)));
return result;
}
static PyTypeObject* PyQuadContourGenerator_init_type(PyObject* m, PyTypeObject* type)
{
static PyMethodDef methods[] = {
{"create_contour", (PyCFunction)PyQuadContourGenerator_create_contour, METH_VARARGS, PyQuadContourGenerator_create_contour__doc__},
{"create_filled_contour", (PyCFunction)PyQuadContourGenerator_create_filled_contour, METH_VARARGS, PyQuadContourGenerator_create_filled_contour__doc__},
{NULL}
};
memset(type, 0, sizeof(PyTypeObject));
type->tp_name = "matplotlib.QuadContourGenerator";
type->tp_doc = PyQuadContourGenerator_init__doc__;
type->tp_basicsize = sizeof(PyQuadContourGenerator);
type->tp_dealloc = (destructor)PyQuadContourGenerator_dealloc;
type->tp_flags = Py_TPFLAGS_DEFAULT;
type->tp_methods = methods;
type->tp_new = PyQuadContourGenerator_new;
type->tp_init = (initproc)PyQuadContourGenerator_init;
if (PyType_Ready(type) < 0) {
return NULL;
}
if (PyModule_AddObject(m, "QuadContourGenerator", (PyObject*)type)) {
return NULL;
}
return type;
}
/* Module */
extern "C" {
#if PY3K
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"_contour",
NULL,
0,
NULL,
NULL,
NULL,
NULL,
NULL
};
#define INITERROR return NULL
PyMODINIT_FUNC PyInit__contour(void)
#else
#define INITERROR return
PyMODINIT_FUNC init_contour(void)
#endif
{
PyObject *m;
#if PY3K
m = PyModule_Create(&moduledef);
#else
m = Py_InitModule3("_contour", NULL, NULL);
#endif
if (m == NULL) {
INITERROR;
}
if (!PyQuadContourGenerator_init_type(m, &PyQuadContourGeneratorType)) {
INITERROR;
}
import_array();
#if PY3K
return m;
#endif
}
} // extern "C"