Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_SCAN_CONVERSION_SCAN_CONVERSION_FRAGMENT_ITERATOR_H
00002 #define OPENTISSUE_CORE_GEOMETRY_SCAN_CONVERSION_SCAN_CONVERSION_FRAGMENT_ITERATOR_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/scan_conversion/scan_conversion_ridge_iterator.h>
00013
00014 namespace OpenTissue
00015 {
00016 namespace scan_conversion
00017 {
00018
00047 template<typename vector3_type>
00048 class FragmentIterator
00049 {
00050 protected:
00051
00052 typedef typename OpenTissue::scan_conversion::detail::RigdeIterator< vector3_type > ridge_iterator;
00053
00054 vector3_type m_vertex[3];
00055 vector3_type m_normal[3];
00056
00057 int m_lower_left_idx;
00058 int m_upper_left_idx;
00059 int m_the_other_idx;
00060
00061 ridge_iterator m_left_ridge_iterator;
00062 ridge_iterator m_right_ridge_iterator;
00063
00064
00065 typedef enum {
00066 find_nonempty_scanline_state
00067 , in_scanline_state
00068 , scanline_found_state
00069 , finished_state
00070 } state_type;
00071
00072 state_type m_state;
00073
00074 int m_start_x;
00075 int m_start_y;
00076 int m_end_x;
00077 int m_end_y;
00078 int m_current_x;
00079 int m_current_y;
00080
00081 protected:
00082
00088 int find_lower_left_vertex_index()
00089 {
00090 int ll = 0;
00091 for (int i = ll + 1; i < 3; ++i)
00092 {
00093 if (
00094 (this->m_vertex[i][1] < this->m_vertex[ll][1])
00095 ||
00096 (
00097 (this->m_vertex[i][1] == this->m_vertex[ll][1])
00098 &&
00099 (this->m_vertex[i][0] < this->m_vertex[ll][0])
00100 )
00101 )
00102 {
00103 ll = i;
00104 }
00105 }
00106 return ll;
00107 }
00108
00114 int find_upper_left_vertex_index()
00115 {
00116 int ul = 0;
00117 for (int i = ul + 1; i < 3; ++i)
00118 {
00119 if (
00120 (this->m_vertex[i][1] > this->m_vertex[ul][1])
00121 ||
00122 (
00123 (this->m_vertex[i][1] == this->m_vertex[ul][1])
00124 &&
00125 (this->m_vertex[i][0] < this->m_vertex[ul][0])
00126 )
00127 )
00128 {
00129 ul = i;
00130 }
00131 }
00132 return ul;
00133 }
00134
00135 ridge_iterator get_left_ridge_iterator() const
00136 {
00137 typedef typename vector3_type::value_type real_type;
00138
00139
00140
00141
00142 vector3_type u = this->m_vertex[this->m_upper_left_idx] - this->m_vertex[this->m_lower_left_idx];
00143 vector3_type v = this->m_vertex[this->m_the_other_idx] - this->m_vertex[this->m_lower_left_idx];
00144
00145 real_type cross_product = u(0) * v(1) - u(1) * v(0);
00146
00147 if (cross_product >= 0)
00148 {
00149
00150
00151
00152 return ridge_iterator(
00153 this->m_vertex[this->m_lower_left_idx]
00154 , this->m_normal[this->m_lower_left_idx]
00155 , this->m_vertex[this->m_the_other_idx]
00156 , this->m_normal[this->m_the_other_idx]
00157 , this->m_vertex[this->m_upper_left_idx]
00158 , this->m_normal[this->m_upper_left_idx]
00159 );
00160 }
00161 else
00162 {
00163
00164 return ridge_iterator(
00165 this->m_vertex[this->m_lower_left_idx]
00166 , this->m_normal[this->m_lower_left_idx]
00167 , this->m_vertex[this->m_upper_left_idx]
00168 , this->m_normal[this->m_upper_left_idx]
00169 );
00170 }
00171 }
00172
00173 ridge_iterator get_right_ridge_iterator() const
00174 {
00175 typedef typename vector3_type::value_type real_type;
00176
00177
00178
00179
00180
00181 vector3_type u = this->m_vertex[this->m_upper_left_idx] - this->m_vertex[this->m_lower_left_idx];
00182 vector3_type v = this->m_vertex[this->m_the_other_idx] - this->m_vertex[this->m_lower_left_idx];
00183
00184 real_type cross_product = u(0) * v(1) - u(1) * v(0);
00185
00186 if (cross_product < 0)
00187 {
00188
00189
00190 if (this->m_vertex[this->m_lower_left_idx](1) != this->m_vertex[this->m_the_other_idx](1) )
00191 {
00192 return ridge_iterator(
00193 this->m_vertex[this->m_lower_left_idx]
00194 , this->m_normal[this->m_lower_left_idx]
00195 , this->m_vertex[this->m_the_other_idx]
00196 , this->m_normal[this->m_the_other_idx]
00197 , this->m_vertex[this->m_upper_left_idx]
00198 , this->m_normal[this->m_upper_left_idx]
00199 );
00200 }
00201 else
00202 {
00203
00204 return ridge_iterator(
00205 this->m_vertex[this->m_the_other_idx]
00206 , this->m_normal[this->m_the_other_idx]
00207 , this->m_vertex[this->m_upper_left_idx]
00208 , this->m_normal[this->m_upper_left_idx]
00209 );
00210 }
00211 }
00212 else
00213 {
00214
00215 return ridge_iterator(
00216 this->m_vertex[this->m_lower_left_idx]
00217 , this->m_normal[this->m_lower_left_idx]
00218 , this->m_vertex[this->m_upper_left_idx]
00219 , this->m_normal[this->m_upper_left_idx]
00220 );
00221 }
00222 }
00223
00224 bool find_nonempty_scanline()
00225 {
00226 while (m_left_ridge_iterator())
00227 {
00228 this->m_start_x = this->m_left_ridge_iterator.x();
00229 this->m_end_x = this->m_right_ridge_iterator.x();
00230
00231 this->m_current_x = this->m_left_ridge_iterator.x();
00232 this->m_current_y = this->m_left_ridge_iterator.y();
00233
00234 if (this->m_current_x < this->m_end_x)
00235 {
00236 this->m_state = in_scanline_state;
00237 return this->valid();
00238 }
00239 else
00240 {
00241 ++(this->m_left_ridge_iterator);
00242 ++(this->m_right_ridge_iterator);
00243 this->m_state = find_nonempty_scanline_state;
00244 }
00245 }
00246
00247 return this->valid();
00248 }
00249
00250 public:
00251
00252 bool valid() const { return this->m_left_ridge_iterator.valid(); }
00253
00254 int x() const { return this->m_current_x; }
00255
00256 int y() const { return this->m_current_y; }
00257
00258 vector3_type normal() const
00259 {
00260 vector3_type left_normal = this->m_left_ridge_iterator.normal();
00261 vector3_type right_normal = this->m_right_ridge_iterator.normal();
00262
00263 int numerator = this->m_current_x - this->m_start_x;
00264 int denominator = this->m_end_x - this->m_start_x;
00265 return vector3_type( unit( left_normal * (denominator - numerator) + right_normal * numerator ) );
00266 }
00267
00268 public:
00269
00270 virtual ~FragmentIterator(){}
00271
00280 FragmentIterator(
00281 vector3_type const & v1
00282 , vector3_type const & n1
00283 , vector3_type const & v2
00284 , vector3_type const & n2
00285 , vector3_type const & v3
00286 , vector3_type const & n3
00287 )
00288 {
00289 this->initialize(v1,n1,v2,n2,v3,n3);
00290 }
00291
00298 FragmentIterator(
00299 vector3_type const & v1
00300 , vector3_type const & v2
00301 , vector3_type const & v3
00302 )
00303 {
00304 vector3_type n;
00305 n.clear();
00306 this->initialize(v1,n,v2,n,v3,n);
00307 }
00308
00309 FragmentIterator(FragmentIterator const & iter) { (*this) = iter; }
00310
00311 FragmentIterator const & operator=(FragmentIterator const & iter)
00312 {
00313 this->m_vertex[0] = iter.m_vertex[0];
00314 this->m_normal[0] = iter.m_normal[0];
00315 this->m_vertex[1] = iter.m_vertex[1];
00316 this->m_normal[1] = iter.m_normal[1];
00317 this->m_vertex[2] = iter.m_vertex[2];
00318 this->m_normal[2] = iter.m_normal[2];
00319
00320 this->m_lower_left_idx = iter.m_lower_left_idx;
00321 this->m_upper_left_idx = iter.m_upper_left_idx;
00322 this->m_the_other_idx = iter.m_the_other_idx;
00323
00324 this->m_left_ridge_iterator = iter.m_left_ridge_iterator;
00325 this->m_right_ridge_iterator = iter.m_right_ridge_iterator;
00326
00327 this->m_state = iter.m_state;
00328
00329 this->m_start_x = iter.m_start_x;
00330 this->m_start_y = iter.m_start_y;
00331 this->m_end_x = iter.m_end_x;
00332 this->m_end_y = iter.m_end_y;
00333 this->m_current_x = iter.m_current_x;
00334 this->m_current_y = iter.m_current_y;
00335
00336 return *this;
00337 }
00338
00345 bool operator()() const { return this->m_left_ridge_iterator.valid(); }
00346
00352 bool operator++()
00353 {
00354 if (this->m_state == find_nonempty_scanline_state)
00355 {
00356 if (this->find_nonempty_scanline())
00357 {
00358 this->m_state = scanline_found_state;
00359 }
00360 }
00361 if (this->m_state == in_scanline_state)
00362 {
00363 if (this->m_current_x < this->m_end_x - 1)
00364 {
00365 ++(this->m_current_x);
00366 }
00367 else
00368 {
00369 ++(this->m_left_ridge_iterator);
00370 ++(this->m_right_ridge_iterator);
00371 if (this->find_nonempty_scanline())
00372 {
00373 this->m_state = in_scanline_state;
00374 }
00375 }
00376 }
00377 if (this->m_state == scanline_found_state)
00378 {
00379 this->m_state = in_scanline_state;
00380 }
00381 return this->valid();
00382 }
00383
00384 public:
00385
00394 void initialize(
00395 vector3_type const & v1
00396 , vector3_type const & n1
00397 , vector3_type const & v2
00398 , vector3_type const & n2
00399 , vector3_type const & v3
00400 , vector3_type const & n3
00401 )
00402 {
00403 this->m_vertex[0] = round( v1 );
00404 this->m_normal[0] = n1;
00405 this->m_vertex[1] = round( v2 );
00406 this->m_normal[1] = n2;
00407 this->m_vertex[2] = round( v3 );
00408 this->m_normal[2] = n3;
00409
00410 this->m_lower_left_idx = this->find_lower_left_vertex_index();
00411 this->m_upper_left_idx = this->find_upper_left_vertex_index();
00412
00413 if(this->m_lower_left_idx == this->m_upper_left_idx)
00414 {
00415
00416 int a = (this->m_lower_left_idx + 1) % 3;
00417 int b = (a + 1) % 3;
00418 this->m_upper_left_idx = (this->m_vertex[a][0] < this->m_vertex[b][0]) ? a : b;
00419 }
00420
00421 this->m_the_other_idx = 3 - (this->m_lower_left_idx + this->m_upper_left_idx);
00422 assert( this->m_lower_left_idx != this->m_upper_left_idx || !"FragmentIterator::initialize() Invalid indices");
00423 assert( this->m_lower_left_idx != this->m_the_other_idx || !"FragmentIterator::initialize() Invalid indices");
00424 assert( this->m_upper_left_idx != this->m_the_other_idx || !"FragmentIterator::initialize() Invalid indices");
00425
00426 this->m_left_ridge_iterator = this->get_left_ridge_iterator();
00427 this->m_right_ridge_iterator = this->get_right_ridge_iterator();
00428
00429 this->m_state = find_nonempty_scanline_state;
00430 this->find_nonempty_scanline();
00431 }
00432
00433 };
00434
00435 }
00436 }
00437
00438
00439 #endif