OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
| 3 * |
| 4 * This program is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU General Public License |
| 6 * as published by the Free Software Foundation; either version 2 |
| 7 * of the License, or (at your option) any later version. |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software Foundation, |
| 16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 * |
| 18 * The Original Code is Copyright (C) 2010 Blender Foundation. |
| 19 * All rights reserved. |
| 20 * |
| 21 * The Original Code is: all of this file. |
| 22 * |
| 23 * Contributor(s): none yet. |
| 24 * |
| 25 * ***** END GPL LICENSE BLOCK ***** |
| 26 */ |
| 27 |
| 28 #ifndef __FREESTYLE_CURVE_ITERATORS_H__ |
| 29 #define __FREESTYLE_CURVE_ITERATORS_H__ |
| 30 |
| 31 /** \file blender/freestyle/intern/stroke/CurveIterators.h |
| 32 * \ingroup freestyle |
| 33 * \brief Iterators used to iterate over the elements of the Curve |
| 34 * \author Stephane Grabli |
| 35 * \date 01/08/2003 |
| 36 */ |
| 37 |
| 38 #include "Curve.h" |
| 39 #include "Stroke.h" |
| 40 |
| 41 namespace CurveInternal { |
| 42 |
| 43 /*! iterator on a curve. Allows an iterating outside· |
| 44 * initial vertices. A CurvePoint is instanciated an returned· |
| 45 * when the iterator is dereferenced. |
| 46 */ |
| 47 |
| 48 class CurvePointIterator : public Interface0DIteratorNested |
| 49 {· |
| 50 public: |
| 51 friend class ::Curve; |
| 52 |
| 53 public: |
| 54 float _CurvilinearLength; |
| 55 float _step; |
| 56 ::Curve::vertex_container::iterator __A; |
| 57 ::Curve::vertex_container::iterator __B; |
| 58 ::Curve::vertex_container::iterator _begin; |
| 59 ::Curve::vertex_container::iterator _end; |
| 60 int _n; |
| 61 int _currentn; |
| 62 float _t; |
| 63 mutable CurvePoint _Point; |
| 64 float _CurveLength; |
| 65 |
| 66 public: |
| 67 inline CurvePointIterator(float step = 0.0f) : Interface0DIteratorNested
() |
| 68 { |
| 69 _step = step; |
| 70 _CurvilinearLength = 0.0f; |
| 71 _t = 0.0f; |
| 72 //_Point = 0; |
| 73 _n = 0; |
| 74 _currentn = 0; |
| 75 _CurveLength = 0; |
| 76 } |
| 77 |
| 78 inline CurvePointIterator(const CurvePointIterator& iBrother) : Interfac
e0DIteratorNested() |
| 79 { |
| 80 __A = iBrother.__A; |
| 81 __B = iBrother.__B; |
| 82 _begin = iBrother._begin; |
| 83 _end = iBrother._end; |
| 84 _CurvilinearLength = iBrother._CurvilinearLength; |
| 85 _step = iBrother._step; |
| 86 _t = iBrother._t; |
| 87 _Point = iBrother._Point; |
| 88 _n = iBrother._n; |
| 89 _currentn = iBrother._currentn; |
| 90 _CurveLength = iBrother._CurveLength; |
| 91 } |
| 92 |
| 93 inline CurvePointIterator& operator=(const CurvePointIterator& iBrother) |
| 94 { |
| 95 __A = iBrother.__A; |
| 96 __B = iBrother.__B; |
| 97 _begin = iBrother._begin; |
| 98 _end = iBrother._end; |
| 99 _CurvilinearLength = iBrother._CurvilinearLength; |
| 100 _step = iBrother._step; |
| 101 _t = iBrother._t; |
| 102 _Point = iBrother._Point; |
| 103 _n = iBrother._n; |
| 104 _currentn = iBrother._currentn; |
| 105 _CurveLength = iBrother._CurveLength; |
| 106 return *this; |
| 107 } |
| 108 |
| 109 virtual ~CurvePointIterator() {} |
| 110 |
| 111 protected: |
| 112 inline CurvePointIterator(::Curve::vertex_container::iterator iA, ::Curv
e::vertex_container::iterator iB, |
| 113 ::Curve::vertex_container::iterator ibegin, ::
Curve::vertex_container::iterator iend, |
| 114 int currentn, int n, float iCurveLength, float
step, float t = 0.0f, |
| 115 float iCurvilinearLength = 0.0f) |
| 116 : Interface0DIteratorNested() |
| 117 { |
| 118 __A = iA; |
| 119 __B = iB; |
| 120 _begin = ibegin; |
| 121 _end = iend; |
| 122 _CurvilinearLength = iCurvilinearLength; |
| 123 _step = step; |
| 124 _t = t; |
| 125 _n = n; |
| 126 _currentn = currentn; |
| 127 _CurveLength = iCurveLength; |
| 128 } |
| 129 |
| 130 public: |
| 131 virtual CurvePointIterator* copy() const |
| 132 { |
| 133 return new CurvePointIterator(*this); |
| 134 } |
| 135 |
| 136 inline Interface0DIterator castToInterface0DIterator() const |
| 137 { |
| 138 Interface0DIterator ret(new CurveInternal::CurvePointIterator(*t
his)); |
| 139 return ret; |
| 140 } |
| 141 |
| 142 virtual string getExactTypeName() const |
| 143 { |
| 144 return "CurvePointIterator"; |
| 145 } |
| 146 |
| 147 // operators |
| 148 inline CurvePointIterator& operator++() // operator corresponding to ++
i |
| 149 { |
| 150 increment(); |
| 151 return *this; |
| 152 } |
| 153 |
| 154 inline CurvePointIterator& operator--() // operator corresponding to --
i |
| 155 { |
| 156 decrement(); |
| 157 return *this; |
| 158 } |
| 159 |
| 160 // comparibility |
| 161 virtual bool operator==(const Interface0DIteratorNested& b) const |
| 162 { |
| 163 const CurvePointIterator* it_exact = dynamic_cast<const CurvePoi
ntIterator*>(&b); |
| 164 if (!it_exact) |
| 165 return false; |
| 166 return ((__A == it_exact->__A) && (__B == it_exact->__B) && (_t
== it_exact->_t)); |
| 167 } |
| 168 |
| 169 // dereferencing |
| 170 virtual CurvePoint& operator*() |
| 171 { |
| 172 return (_Point = CurvePoint(*__A, *__B, _t)); |
| 173 } |
| 174 |
| 175 virtual CurvePoint* operator->() |
| 176 { |
| 177 return &(operator*()); |
| 178 } |
| 179 |
| 180 virtual bool isBegin() const |
| 181 { |
| 182 if ((__A == _begin) && (_t < (float)M_EPSILON)) |
| 183 return true; |
| 184 return false; |
| 185 } |
| 186 |
| 187 virtual bool isEnd() const |
| 188 { |
| 189 if (__B == _end) |
| 190 return true; |
| 191 return false; |
| 192 } |
| 193 |
| 194 //protected: |
| 195 virtual int increment() |
| 196 { |
| 197 if ((_currentn == _n - 1) && (_t == 1.0f)) { |
| 198 // we're setting the iterator to end |
| 199 ++__A; |
| 200 ++__B; |
| 201 ++_currentn; |
| 202 _t = 0.0f; |
| 203 return 0; |
| 204 } |
| 205 |
| 206 if (0 == _step) { // means we iterate over initial vertices |
| 207 Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); |
| 208 _CurvilinearLength += (float)vec_tmp.norm(); |
| 209 if (_currentn == _n - 1) { |
| 210 _t = 1.0f; |
| 211 return 0; |
| 212 } |
| 213 ++__B; |
| 214 ++__A; |
| 215 ++_currentn; |
| 216 return 0; |
| 217 } |
| 218 |
| 219 // compute the new position: |
| 220 Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); |
| 221 float normAB = (float)vec_tmp2.norm(); |
| 222 |
| 223 if (normAB > M_EPSILON) { |
| 224 _CurvilinearLength += _step; |
| 225 _t = _t + _step / normAB; |
| 226 } |
| 227 else { |
| 228 _t = 1.0f; // AB is a null segment, we're directly at it
s end |
| 229 } |
| 230 //if normAB ~= 0, we don't change these values |
| 231 if (_t >= 1) { |
| 232 _CurvilinearLength -= normAB * (_t - 1); |
| 233 if (_currentn == _n - 1) { |
| 234 _t = 1.0f; |
| 235 } |
| 236 else { |
| 237 _t = 0.0f; |
| 238 ++_currentn; |
| 239 ++__A; |
| 240 ++__B; |
| 241 } |
| 242 } |
| 243 return 0; |
| 244 } |
| 245 |
| 246 virtual int decrement() |
| 247 { |
| 248 if (_t == 0.0f) { //we're at the beginning of the edge |
| 249 _t = 1.0f; |
| 250 --_currentn; |
| 251 --__A; |
| 252 --__B; |
| 253 if (_currentn == _n - 1) |
| 254 return 0; |
| 255 } |
| 256 |
| 257 if (0 == _step) { // means we iterate over initial vertices |
| 258 Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); |
| 259 _CurvilinearLength -= (float)vec_tmp.norm(); |
| 260 _t = 0; |
| 261 return 0; |
| 262 } |
| 263 |
| 264 // compute the new position: |
| 265 Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); |
| 266 float normAB = (float)vec_tmp2.norm(); |
| 267 |
| 268 if (normAB > M_EPSILON) { |
| 269 _CurvilinearLength -= _step; |
| 270 _t = _t - _step / normAB; |
| 271 } |
| 272 else { |
| 273 _t = -1.0f; // We just need a negative value here |
| 274 } |
| 275 |
| 276 // round value |
| 277 if (fabs(_t) < (float)M_EPSILON) |
| 278 _t = 0.0f; |
| 279 if (_t < 0) { |
| 280 if (_currentn == 0) |
| 281 _CurvilinearLength = 0.0f; |
| 282 else |
| 283 _CurvilinearLength += normAB * (-_t); |
| 284 _t = 0.0f; |
| 285 } |
| 286 return 0; |
| 287 } |
| 288 |
| 289 virtual float t() const |
| 290 { |
| 291 return _CurvilinearLength; |
| 292 } |
| 293 |
| 294 virtual float u() const |
| 295 { |
| 296 return _CurvilinearLength / _CurveLength; |
| 297 } |
| 298 }; |
| 299 |
| 300 } // end of namespace CurveInternal |
| 301 |
| 302 #endif // __FREESTYLE_CURVE_ITERATORS_H__ |
OLD | NEW |