00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00028 # define MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00029
00033
00034 # include <vector>
00035 # include <mln/core/concept/browsing.hh>
00036
00037
00038 namespace mln
00039 {
00040
00041 namespace canvas
00042 {
00043
00044 namespace browsing
00045 {
00046
00048
00076 struct snake_generic_t : public Browsing< snake_generic_t >
00077 {
00078
00079 template <typename F>
00080 void operator()(F& f) const;
00081
00082 };
00083
00084 extern const snake_generic_t snake_generic;
00085
00086 # ifndef MLN_INCLUDE_ONLY
00087
00088 # ifndef MLN_WO_GLOBAL_VARS
00089
00090 const snake_generic_t snake_generic;
00091
00092 # endif // ! MLN_WO_GLOBAL_VARS
00093
00094
00095 template <typename F>
00096 inline
00097 void
00098 snake_generic_t::operator()(F& f) const
00099 {
00100 trace::entering("canvas::browsing::snake_generic");
00101 mln_precondition(f.input.is_valid());
00102
00103
00104 f.p = f.input.bbox().pmin();
00105
00106 std::vector< int > directions(f.moves.size(), 0);
00107 unsigned deph = 0;
00108 unsigned total_deph = f.moves.size() / 2 + 1;
00109
00110
00111 f.init();
00112
00113 bool first = true;
00114 directions[deph] = 1;
00115 deph = total_deph - 1;
00116
00117
00118 (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00119 while (deph > 0)
00120 {
00121 mln_assertion(deph <= total_deph);
00122 mln_assertion(deph > 0);
00123
00124 if (!f.input.domain().has(f.p +
00125 f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]]))
00126 {
00127
00128 deph--;
00129 if (deph >= 1)
00130
00131 directions[deph] = directions[deph] == 1 ? 0 : 1;
00132 continue;
00133 }
00134
00135 if (!first)
00136 {
00137
00138 f.p += f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]];
00139
00140 (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00141 }
00142 else
00143 first = false;
00144
00145 if (deph != total_deph)
00146 {
00147
00148 deph++;
00149 first = true;
00150 }
00151 }
00152
00153 trace::exiting("canvas::browsing::snake_generic");
00154 }
00155
00156 # endif // ! MLN_INCLUDE_ONLY
00157
00158 }
00159
00160 }
00161
00162 }
00163
00164
00165 #endif // ! MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH