diff --git a/src/Mod/Path/App/Voronoi.cpp b/src/Mod/Path/App/Voronoi.cpp index abd4ca6450..f06e06e6d7 100644 --- a/src/Mod/Path/App/Voronoi.cpp +++ b/src/Mod/Path/App/Voronoi.cpp @@ -43,25 +43,6 @@ TYPESYSTEM_SOURCE(Path::Voronoi , Base::BaseClass); // Helpers -static void colorExterior(const Voronoi::diagram_type::edge_type *edge, std::size_t colorValue) { - if (edge->color() == colorValue) { - // end recursion - return; - } - edge->color(colorValue); - edge->twin()->color(colorValue); - auto v = edge->vertex1(); - if (v == NULL || !edge->is_primary()) { - return; - } - v->color(colorValue); - auto e = v->incident_edge(); - do { - colorExterior(e, colorValue); - e = e->rot_next(); - } while (e != v->incident_edge()); -} - // Voronoi::diagram_type Voronoi::diagram_type::diagram_type() @@ -208,10 +189,29 @@ void Voronoi::construct() vd->reIndex(); } +void Voronoi::colorExterior(const Voronoi::diagram_type::edge_type *edge, std::size_t colorValue) { + if (edge->color() == colorValue) { + // end recursion + return; + } + edge->color(colorValue); + edge->twin()->color(colorValue); + auto v = edge->vertex1(); + if (v == NULL || !edge->is_primary()) { + return; + } + v->color(colorValue); + auto e = v->incident_edge(); + do { + colorExterior(e, colorValue); + e = e->rot_next(); + } while (e != v->incident_edge()); +} + void Voronoi::colorExterior(Voronoi::color_type color) { for (diagram_type::const_edge_iterator it = vd->edges().begin(); it != vd->edges().end(); ++it) { if (!it->is_finite()) { - ::colorExterior(&(*it), color); + colorExterior(&(*it), color); } } } diff --git a/src/Mod/Path/App/Voronoi.h b/src/Mod/Path/App/Voronoi.h index 272a81321b..0634ef3c91 100644 --- a/src/Mod/Path/App/Voronoi.h +++ b/src/Mod/Path/App/Voronoi.h @@ -122,6 +122,8 @@ namespace Path private: Base::Reference vd; + friend class VoronoiPy; + void colorExterior(const Voronoi::diagram_type::edge_type *edge, std::size_t colorValue); }; } //namespace Path diff --git a/src/Mod/Path/App/VoronoiPyImp.cpp b/src/Mod/Path/App/VoronoiPyImp.cpp index ed3724483f..64b736b0ac 100644 --- a/src/Mod/Path/App/VoronoiPyImp.cpp +++ b/src/Mod/Path/App/VoronoiPyImp.cpp @@ -172,12 +172,45 @@ Py::List VoronoiPy::getCells(void) const { return list; } +static bool callbackWithVertex(Voronoi::diagram_type *dia, PyObject *callback, const Voronoi::diagram_type::vertex_type *v, bool &isExterior) { + if (!isExterior) { + PyObject *vx = new VoronoiVertexPy(new VoronoiVertex(dia, v)); + PyObject *arglist = Py_BuildValue("(O)", vx); + PyObject *result = PyEval_CallObject(callback, arglist); + Py_DECREF(arglist); + Py_DECREF(vx); + if (result == NULL) { + return false; + } + isExterior = result == Py_True; + Py_DECREF(result); + } + return true; +} + PyObject* VoronoiPy::colorExterior(PyObject *args) { Voronoi::color_type color = 0; - if (!PyArg_ParseTuple(args, "k", &color)) { + PyObject *callback = 0; + if (!PyArg_ParseTuple(args, "k|O", &color, &callback)) { throw Py::RuntimeError("colorExterior requires an integer (color) argument"); } - getVoronoiPtr()->colorExterior(color); + Voronoi *vo = getVoronoiPtr(); + vo->colorExterior(color); + if (callback) { + for (auto e = vo->vd->edges().begin(); e != vo->vd->edges().end(); ++e) { + if (e->is_finite() && e->color() == 0) { + const Voronoi::diagram_type::vertex_type *v0 = e->vertex0(); + const Voronoi::diagram_type::vertex_type *v1 = e->vertex1(); + bool isExterior = false; + if (!callbackWithVertex(vo->vd, callback, v0, isExterior) || !callbackWithVertex(vo->vd, callback, v1, isExterior)) { + return NULL; + } + if (isExterior) { + vo->colorExterior(&(*e), color); + } + } + } + } Py_INCREF(Py_None); return Py_None;