diff --git a/shared/src/FloodFill.h b/shared/src/FloodFill.h new file mode 100644 index 0000000000..a63bcad936 --- /dev/null +++ b/shared/src/FloodFill.h @@ -0,0 +1,96 @@ +// +// FloodFill.h +// hifi +// +// Created by Tobias Schwinger 3/26/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__FloodFill__ +#define __hifi__FloodFill__ + +/** + * Line scanning, iterative flood fill algorithm. + */ +template< class Strategy, typename Cursor > +void floodFill(Cursor const& position, + Strategy const& strategy = Strategy()); + + +template< class Strategy, typename Cursor > +struct floodFill_impl : Strategy +{ + floodFill_impl(Strategy const& s) : Strategy(s) { } + + using Strategy::select; + using Strategy::process; + + using Strategy::left; + using Strategy::right; + using Strategy::up; + using Strategy::down; + + using Strategy::defer; + using Strategy::deferred; + + void go(Cursor position) + { + Cursor higher, lower, h,l, i; + bool higher_found, lower_found, hf, lf; + do + { + if (! select(position)) + continue; + + process(position); + + Cursor higher = position, lower = position; + bool higher_found = false; + bool lower_found = false; + up(higher); yTest(higher, higher_found); + down(lower); yTest(lower, lower_found); + + i = position, h = higher, l = lower; + hf = higher_found, lf = lower_found; + do { right(i), right(h), right(l); yTest(h,hf); yTest(l,lf); } + while (selectAndProcess(i)); + + i = position, h = higher, l = lower; + hf = higher_found, lf = lower_found; + do { left(i); left(h); left(l); yTest(h,hf); yTest(l,lf); } + while (selectAndProcess(i)); + } + while (deferred(position)); + } + + bool selectAndProcess(Cursor const& i) + { + if (select(i)) + { + process(i); + return true; + } + return false; + } + + void yTest(Cursor const& i, bool& state) + { + if (! select(i)) + state = false; + else if (! state) + { + state = true; + defer(i); + } + } +}; + +template< class Strategy, typename Cursor > +void floodFill(Cursor const& p, Strategy const& s) +{ + floodFill_impl(s).go(p); +} + + +#endif +