static void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola) { float mx; if (parabola->is_leaf) { MEM_freeN(parabola); return; } if (parabola->edge->direction[0] > 0.0f) mx = max_ff(process->width, parabola->edge->start[0] + 10); else mx = min_ff(0.0f, parabola->edge->start[0] - 10.0f); parabola->edge->end[0] = mx; parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g; voronoi_finishEdge(process, parabola->left); voronoi_finishEdge(process, parabola->right); MEM_freeN(parabola); }
void BLI_voronoi_compute( const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges) { VoronoiProcess process; VoronoiEdge *edge; int i; memset(&process, 0, sizeof(VoronoiProcess)); process.width = width; process.height = height; for (i = 0; i < sites_total; i++) { VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event"); event->type = voronoiEventType_Site; copy_v2_v2(event->site, sites[i].co); voronoi_insertEvent(&process, event); } while (process.queue.first) { VoronoiEvent *event = process.queue.first; process.current_y = event->site[1]; if (event->type == voronoiEventType_Site) { voronoi_addParabola(&process, event->site); } else { voronoi_removeParabola(&process, event); } BLI_freelinkN(&process.queue, event); } voronoi_finishEdge(&process, process.root); edge = process.edges.first; while (edge) { if (edge->neighbor) { copy_v2_v2(edge->start, edge->neighbor->end); MEM_freeN(edge->neighbor); } edge = edge->next; } BLI_movelisttolist(edges, &process.edges); }