diff options
5 files changed, 181 insertions, 22 deletions
diff --git a/release/scripts/freestyle/style_modules/parameter_editor.py b/release/scripts/freestyle/style_modules/parameter_editor.py index 9b94a2e3f20..e817771732a 100644 --- a/release/scripts/freestyle/style_modules/parameter_editor.py +++ b/release/scripts/freestyle/style_modules/parameter_editor.py @@ -697,27 +697,6 @@ class ObjectNamesUP1D(UnaryPredicate1D): return not found return found -class WithinImageBorderUP1D(UnaryPredicate1D): - def __init__(self, xmin, xmax, ymin, ymax): - UnaryPredicate1D.__init__(self) - self._xmin = xmin - self._xmax = xmax - self._ymin = ymin - self._ymax = ymax - def getName(self): - return "WithinImageBorderUP1D" - def __call__(self, inter): - it = inter.verticesBegin() - while not it.isEnd(): - if self.withinBorder(it.getObject()): - return True - it.increment() - return False - def withinBorder(self, vert): - x = vert.getProjectedX() - y = vert.getProjectedY() - return self._xmin <= x <= self._xmax and self._ymin <= y <= self._ymax - # Stroke caps def iter_stroke_vertices(stroke): @@ -1108,7 +1087,7 @@ def process(layer_name, lineset_name): else: xmin, xmax = 0.0, float(w) ymin, ymax = 0.0, float(h) - upred = WithinImageBorderUP1D(xmin, xmax, ymin, ymax) + upred = WithinImageBoundaryUP1D(xmin, ymin, xmax, ymax) selection_criteria.append(upred) # select feature edges upred = join_unary_predicates(selection_criteria, AndUP1D) diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp index 095963fb3af..a0c59484486 100644 --- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp +++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp @@ -12,6 +12,7 @@ #include "UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h" #include "UnaryPredicate1D/BPy_ShapeUP1D.h" #include "UnaryPredicate1D/BPy_TrueUP1D.h" +#include "UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h" #ifdef __cplusplus extern "C" { @@ -75,6 +76,11 @@ int UnaryPredicate1D_Init( PyObject *module ) Py_INCREF( &TrueUP1D_Type ); PyModule_AddObject(module, "TrueUP1D", (PyObject *)&TrueUP1D_Type); + if( PyType_Ready( &WithinImageBoundaryUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &WithinImageBoundaryUP1D_Type ); + PyModule_AddObject(module, "WithinImageBoundaryUP1D", (PyObject *)&WithinImageBoundaryUP1D_Type); + return 0; } diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp new file mode 100644 index 00000000000..9beae103113 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp @@ -0,0 +1,88 @@ +#include "BPy_WithinImageBoundaryUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +//------------------------INSTANCE METHODS ---------------------------------- + +static char WithinImageBoundaryUP1D___doc__[] = +"Class hierarchy: :class:`UnaryPredicate1D` > :class:`WithinImageBoundaryUP1D`\n" +"\n" +".. method:: __init__(xmin, ymin, xmax, ymax)\n" +"\n" +" Builds an WithinImageBoundaryUP1D object.\n" +"\n" +" :arg xmin: X lower bound of the image boundary.\n" +" :type xmin: float\n" +" :arg ymin: Y lower bound of the image boundary.\n" +" :type ymin: float\n" +" :arg xmax: X upper bound of the image boundary.\n" +" :type xmax: float\n" +" :arg ymax: Y upper bound of the image boundary.\n" +" :type ymax: float\n" +"\n" +".. method:: __call__(inter)\n" +"\n" +" Returns true if the Interface1D intersects with image boundary.\n"; + +static int WithinImageBoundaryUP1D___init__( BPy_WithinImageBoundaryUP1D* self, PyObject *args ) +{ + double xmin, ymin, xmax, ymax; + + if(!( PyArg_ParseTuple(args, "dddd", &xmin, &ymin, &xmax, &ymax) )) + return -1; + self->py_up1D.up1D = new Predicates1D::WithinImageBoundaryUP1D(xmin, ymin, xmax, ymax); + return 0; +} + +/*-----------------------BPy_TrueUP1D type definition ------------------------------*/ + +PyTypeObject WithinImageBoundaryUP1D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "WithinImageBoundaryUP1D", /* tp_name */ + sizeof(BPy_WithinImageBoundaryUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + WithinImageBoundaryUP1D___doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)WithinImageBoundaryUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h new file mode 100644 index 00000000000..2bd3e698a21 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H +#define FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject WithinImageBoundaryUP1D_Type; + +#define BPy_WithinImageBoundaryUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &WithinImageBoundaryUP1D_Type) ) + +/*---------------------------Python BPy_WithinImageBoundaryUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_WithinImageBoundaryUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H */ diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h index 6461f6428ab..b1159a8332e 100755 --- a/source/blender/freestyle/intern/stroke/Predicates1D.h +++ b/source/blender/freestyle/intern/stroke/Predicates1D.h @@ -358,6 +358,63 @@ namespace Predicates1D { } }; + // WithinImageBoundaryUP1D + /*! Returns true if the Interface1D is (partly) within the image boundary. + */ + class WithinImageBoundaryUP1D: public UnaryPredicate1D + { + private: + real _xmin, _ymin, _xmax, _ymax; + public: + /*! Builds the Predicate. + * \param xmin + * The X lower bound of the image boundary. + * \param ymin + * The Y lower bound of the image boundary. + * \param xmax + * The X upper bound of the image boundary. + * \param ymax + * The Y upper bound of the image boundary. + */ + WithinImageBoundaryUP1D(const real xmin, const real ymin, const real xmax, const real ymax) : + _xmin(xmin), _ymin(ymin), _xmax(xmax), _ymax(ymax) {} + /*! Returns the string "WithinImageBoundaryUP1D"*/ + string getName() const { + return "WithinImageBoundaryUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + // 1st pass: check if a point is within the image boundary. + Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); + for (; it != itend; ++it) { + real x = (*it).getProjectedX(); + real y = (*it).getProjectedY(); + if (_xmin <= x && x <= _xmax && _ymin <= y && y <= _ymax) { + result = true; + return 0; + } + } + // 2nd pass: check if a line segment intersects with the image boundary. + it = inter.verticesBegin(); + if (it != itend) { + Vec2r pmin(_xmin, _ymin); + Vec2r pmax(_xmax, _ymax); + Vec2r prev((*it).getPoint2D()); + ++it; + for (; it != itend; ++it) { + Vec2r p((*it).getPoint2D()); + if (GeomUtils::intersect2dSeg2dArea (pmin, pmax, prev, p)) { + result = true; + return 0; + } + prev = p; + } + } + result = false; + return 0; + } + }; + // // Binary Predicates definitions // |