}
void set_base_value (int id, float value) {
- g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
+ assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
settings[id]->base_value = value;
settings_base_values_have_changed ();
}
void set_mapping_n (int id, int input, int n) {
- g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
+ assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
settings[id]->set_n (input, n);
}
void set_mapping_point (int id, int input, int index, float x, float y) {
- g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
+ assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
settings[id]->set_point (input, index, x, y);
}
+ float get_state (int i)
+ {
+ assert (i >= 0 && i < STATE_COUNT);
+ return states[i];
+ }
+
+ void set_state (int i, float value)
+ {
+ assert (i >= 0 && i < STATE_COUNT);
+ states[i] = value;
+ }
+
private:
// returns the fraction still left after t seconds
float exp_decay (float T_const, float t)
return false;
}
- PyObject * get_state ()
- {
- npy_intp dims = {STATE_COUNT};
- PyObject * data = PyArray_SimpleNew(1, &dims, NPY_FLOAT32);
- npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
- for (int i=0; i<STATE_COUNT; i++) {
- data_p[i] = states[i];
- }
- return data;
- }
-
- void set_state (PyObject * data)
- {
- assert(PyArray_NDIM(data) == 1);
- assert(PyArray_DIM(data, 0) == STATE_COUNT);
- assert(PyArray_ISCARRAY(data));
- npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
- for (int i=0; i<STATE_COUNT; i++) {
- states[i] = data_p[i];
- }
- }
-
};
return r
-class Brush(mypaintlib.Brush):
+class Brush(mypaintlib.PythonBrush):
"""
Low-level extension of the C brush class, propagating all changes of
a brushinfo instance down into the C code.
"""
def __init__(self, brushinfo):
- mypaintlib.Brush.__init__(self)
+ mypaintlib.PythonBrush.__init__(self)
self.brushinfo = brushinfo
brushinfo.observers.append(self.update_brushinfo)
self.update_brushinfo(all_settings)
+ # override some mypaintlib.Brush methods with special wrappers
+ # from python_brush.hpp
+ self.get_state = self.python_get_state
+ self.set_state = self.python_set_state
+ self.stroke_to = self.python_stroke_to
+
def update_brushinfo(self, settings):
"""Mirror changed settings into the BrushInfo tracking this Brush."""
#include "Python.h"
#include "numpy/arrayobject.h"
#include "../brushlib/brushlib.hpp"
+#include "python_brush.hpp"
#include "brushmodes.hpp"
#include "tiledsurface.hpp"
#include "pixops.hpp"
%include "../brushlib/surface.hpp"
%include "../brushlib/brush.hpp"
%include "../brushlib/mapping.hpp"
+%include "python_brush.hpp"
%include "brushmodes.hpp"
%include "tiledsurface.hpp"
%include "pixops.hpp"
--- /dev/null
+/* brushlib - The MyPaint Brush Library
+ * Copyright (C) 2011 Martin Renold <martinxyz@gmx.ch>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+class PythonBrush : public Brush {
+
+public:
+ // get state as numpy array
+ PyObject * python_get_state ()
+ {
+ npy_intp dims = {STATE_COUNT};
+ PyObject * data = PyArray_SimpleNew(1, &dims, NPY_FLOAT32);
+ npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
+ for (int i=0; i<STATE_COUNT; i++) {
+ data_p[i] = get_state(i);
+ }
+ return data;
+ }
+
+ // set state from numpy array
+ void python_set_state (PyObject * data)
+ {
+ assert(PyArray_NDIM(data) == 1);
+ assert(PyArray_DIM(data, 0) == STATE_COUNT);
+ assert(PyArray_ISCARRAY(data));
+ npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
+ for (int i=0; i<STATE_COUNT; i++) {
+ set_state(i, data_p[i]);
+ }
+ }
+
+ // same as stroke_to() but with exception handling, should an
+ // exception happen in the surface code (eg. out-of-memory)
+ PyObject* python_stroke_to (Surface * surface, float x, float y, float pressure, float xtilt, float ytilt, double dtime)
+ {
+ bool res = stroke_to (surface, x, y, pressure, xtilt, ytilt, dtime);
+ if (PyErr_Occurred()) {
+ return NULL;
+ } else if (res) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ }
+
+};
return tileMemory[i].rgba_p;
}
}
+ if (PyErr_Occurred()) return NULL;
PyObject* rgba = PyObject_CallMethod(self, "get_tile_memory", "(iii)", tx, ty, readonly);
if (rgba == NULL) {
- printf("Python exception during get_tile_memory()! The next traceback might be wrong.\n");
+ printf("Python exception during get_tile_memory()!\n");
return NULL;
}
#ifdef HEAVY_DEBUG