Added callback to colorExterior to also color 'interior'

This commit is contained in:
Markus Lampert
2020-09-07 23:49:24 -07:00
committed by sliptonic
parent 7e6975a154
commit 08e73632ec
3 changed files with 57 additions and 22 deletions

View File

@@ -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);
}
}
}

View File

@@ -122,6 +122,8 @@ namespace Path
private:
Base::Reference<diagram_type> vd;
friend class VoronoiPy;
void colorExterior(const Voronoi::diagram_type::edge_type *edge, std::size_t colorValue);
};
} //namespace Path

View File

@@ -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;