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 /** \file blender/freestyle/intern/stroke/Curve.cpp |
| 29 * \ingroup freestyle |
| 30 * \brief Class to define a container for curves |
| 31 * \author Stephane Grabli |
| 32 * \date 11/01/2003 |
| 33 */ |
| 34 |
| 35 #include "Curve.h" |
| 36 #include "CurveAdvancedIterators.h" |
| 37 #include "CurveIterators.h" |
| 38 |
| 39 #include "BKE_global.h" |
| 40 |
| 41 /**********************************/ |
| 42 /* */ |
| 43 /* */ |
| 44 /* CurvePoint */ |
| 45 /* */ |
| 46 /* */ |
| 47 /**********************************/ |
| 48 |
| 49 CurvePoint::CurvePoint() |
| 50 { |
| 51 __A = 0; |
| 52 __B = 0; |
| 53 _t2d = 0; |
| 54 } |
| 55 |
| 56 CurvePoint::CurvePoint(SVertex *iA, SVertex *iB, float t) |
| 57 { |
| 58 __A = iA; |
| 59 __B = iB; |
| 60 _t2d = t; |
| 61 if ((iA == 0) && (t == 1.0f)) { |
| 62 _Point2d = __B->point2d(); |
| 63 _Point3d = __B->point3d(); |
| 64 } |
| 65 else if ((iB == 0) && (t == 0.0f)) { |
| 66 _Point2d = __A->point2d(); |
| 67 _Point3d = __A->point3d(); |
| 68 } |
| 69 else { |
| 70 _Point2d = __A->point2d() + _t2d * (__B->point2d() - __A->point2
d()); |
| 71 _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3
d()); |
| 72 } |
| 73 } |
| 74 |
| 75 CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3) |
| 76 { |
| 77 __A = 0; |
| 78 __B = 0; |
| 79 float t1 = iA->t2d(); |
| 80 float t2 = iB->t2d(); |
| 81 if ((iA->A() == iB->A()) && (iA->B() == iB->B()) && |
| 82 (iA->A() != 0) && (iA->B() != 0) && (iB->A() != 0) && (iB->B() != 0)
) |
| 83 { |
| 84 __A = iA->A(); |
| 85 __B = iB->B(); |
| 86 _t2d = t1 + t2 * t3 - t1 * t3; |
| 87 } |
| 88 else if ((iA->B() == 0) && (iB->B() == 0)) { |
| 89 __A = iA->A(); |
| 90 __B = iB->A(); |
| 91 _t2d = t3; |
| 92 } |
| 93 else if ((iA->t2d() == 0) && (iB->t2d() == 0)) { |
| 94 __A = iA->A(); |
| 95 __B = iB->A(); |
| 96 _t2d = t3; |
| 97 } |
| 98 else if (iA->A() == iB->A()) { |
| 99 iA_A_eq_iB_A: |
| 100 if (iA->t2d() == 0) { |
| 101 __A = iB->A(); |
| 102 __B = iB->B(); |
| 103 _t2d = t3; |
| 104 } |
| 105 else if (iB->t2d() == 0) { |
| 106 __A = iA->A(); |
| 107 __B = iA->B(); |
| 108 _t2d = t3; |
| 109 } |
| 110 } |
| 111 else if (iA->B() == iB->B()) { |
| 112 iA_B_eq_iB_B: |
| 113 if (iA->t2d() == 1) { |
| 114 __A = iB->A(); |
| 115 __B = iB->B(); |
| 116 _t2d = t3; |
| 117 } |
| 118 else if (iB->t2d() == 1) { |
| 119 __A = iA->A(); |
| 120 __B = iA->B(); |
| 121 _t2d = t3; |
| 122 } |
| 123 } |
| 124 else if (iA->B() == iB->A()) { |
| 125 iA_B_eq_iB_A: |
| 126 if ((iA->t2d() != 1.0f) && (iB->t2d() == 0.0f)) { |
| 127 __A = iA->A(); |
| 128 __B = iA->B(); |
| 129 _t2d = t1 + t3 - t1 * t3; |
| 130 //_t2d = t3; |
| 131 } |
| 132 else if ((iA->t2d() == 1.0f) && (iB->t2d() != 0.0f)) { |
| 133 __A = iB->A(); |
| 134 __B = iB->B(); |
| 135 //_t2d = t3; |
| 136 _t2d = t2 * t3; |
| 137 } |
| 138 else if ((iA->getPoint2D() - iA->getPoint2D()).norm() < 1.0e-6)
{ |
| 139 __A = iB->A(); |
| 140 __B = iB->B(); |
| 141 //_t2d = t3; |
| 142 _t2d = t2 * t3; |
| 143 } |
| 144 } |
| 145 else if (iA->A() != 0 && iB->A() != 0 && (iA->A()->point3d() - iB->A()->
point3d()).norm() < 1.0e-6) { |
| 146 goto iA_A_eq_iB_A; |
| 147 } |
| 148 else if (iA->B() != 0 && iB->B() != 0 && (iA->B()->point3d() - iB->B()->
point3d()).norm() < 1.0e-6) { |
| 149 goto iA_B_eq_iB_B; |
| 150 } |
| 151 else if (iA->B() != 0 && iB->A() != 0 && (iA->B()->point3d() - iB->A()->
point3d()).norm() < 1.0e-6) { |
| 152 goto iA_B_eq_iB_A; |
| 153 } |
| 154 |
| 155 if (!__A || !__B) { |
| 156 if (G.debug & G_DEBUG_FREESTYLE) { |
| 157 printf("iA A 0x%p p (%f, %f)\n", iA->A(), iA->A()->getPo
int2D().x(), iA->A()->getPoint2D().y()); |
| 158 printf("iA B 0x%p p (%f, %f)\n", iA->B(), iA->B()->getPo
int2D().x(), iA->B()->getPoint2D().y()); |
| 159 printf("iB A 0x%p p (%f, %f)\n", iB->A(), iB->A()->getPo
int2D().x(), iB->A()->getPoint2D().y()); |
| 160 printf("iB B 0x%p p (%f, %f)\n", iB->B(), iB->B()->getPo
int2D().x(), iB->B()->getPoint2D().y()); |
| 161 printf("iA t2d %f p (%f, %f)\n", iA->t2d(), iA->getPoint
2D().x(), iA->getPoint2D().y()); |
| 162 printf("iB t2d %f p (%f, %f)\n", iB->t2d(), iB->getPoint
2D().x(), iB->getPoint2D().y()); |
| 163 } |
| 164 cerr << "Fatal error in CurvePoint::CurvePoint(CurvePoint *iA, C
urvePoint *iB, float t3)" << endl; |
| 165 } |
| 166 assert(__A != 0 && __B != 0); |
| 167 |
| 168 #if 0 |
| 169 _Point2d = __A->point2d() + _t2d * (__B->point2d() - __A->point2d()); |
| 170 _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3d()); |
| 171 #endif |
| 172 |
| 173 _Point2d = iA->point2d() + t3 * (iB->point2d() - iA->point2d()); |
| 174 _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3d()); |
| 175 } |
| 176 |
| 177 CurvePoint::CurvePoint(const CurvePoint& iBrother) |
| 178 { |
| 179 __A = iBrother.__A; |
| 180 __B = iBrother.__B; |
| 181 _t2d = iBrother._t2d; |
| 182 _Point2d = iBrother._Point2d; |
| 183 _Point3d = iBrother._Point3d; |
| 184 } |
| 185 |
| 186 CurvePoint& CurvePoint::operator=(const CurvePoint& iBrother) |
| 187 { |
| 188 __A = iBrother.__A; |
| 189 __B = iBrother.__B; |
| 190 _t2d = iBrother._t2d; |
| 191 _Point2d = iBrother._Point2d; |
| 192 _Point3d = iBrother._Point3d; |
| 193 return *this; |
| 194 } |
| 195 |
| 196 |
| 197 FEdge *CurvePoint::fedge() |
| 198 { |
| 199 if (getNature() & Nature::T_VERTEX) |
| 200 return 0; |
| 201 return __A->fedge(); |
| 202 } |
| 203 |
| 204 |
| 205 FEdge *CurvePoint::getFEdge(Interface0D& inter) |
| 206 { |
| 207 CurvePoint* iVertexB = dynamic_cast<CurvePoint*>(&inter); |
| 208 if (!iVertexB) { |
| 209 cerr << "Warning: CurvePoint::getFEdge() failed to cast the give
n 0D element to CurvePoint." << endl; |
| 210 return 0; |
| 211 } |
| 212 if (((__A == iVertexB->__A) && (__B == iVertexB->__B)) || |
| 213 ((__A == iVertexB->__B) && (__B == iVertexB->__A))) |
| 214 { |
| 215 return __A->getFEdge(*__B); |
| 216 } |
| 217 if (__B == 0) { |
| 218 if (iVertexB->__B == 0) |
| 219 return __A->getFEdge(*(iVertexB->__A)); |
| 220 else if (iVertexB->__A == __A) |
| 221 return __A->getFEdge(*(iVertexB->__B)); |
| 222 else if (iVertexB->__B == __A) |
| 223 return __A->getFEdge(*(iVertexB->__A)); |
| 224 } |
| 225 if (iVertexB->__B == 0) { |
| 226 if (iVertexB->__A == __A) |
| 227 return __B->getFEdge(*(iVertexB->__A)); |
| 228 else if (iVertexB->__A == __B) |
| 229 return __A->getFEdge(*(iVertexB->__A)); |
| 230 } |
| 231 if (__B == iVertexB->__A) { |
| 232 if ((_t2d != 1) && (iVertexB->_t2d == 0)) |
| 233 return __A->getFEdge(*__B); |
| 234 if ((_t2d == 1) && (iVertexB->_t2d != 0)) |
| 235 return iVertexB->__A->getFEdge(*(iVertexB->__B)); |
| 236 } |
| 237 if (__B == iVertexB->__B) { |
| 238 if ((_t2d != 1) && (iVertexB->_t2d == 1)) |
| 239 return __A->getFEdge(*__B); |
| 240 if ((_t2d == 1) && (iVertexB->_t2d != 1)) |
| 241 return iVertexB->__A->getFEdge(*(iVertexB->__B)); |
| 242 } |
| 243 if (__A == iVertexB->__A) { |
| 244 if ((_t2d == 0) && (iVertexB->_t2d != 0)) |
| 245 return iVertexB->__A->getFEdge(*(iVertexB->__B)); |
| 246 if ((_t2d != 0) && (iVertexB->_t2d == 0)) |
| 247 return __A->getFEdge(*__B); |
| 248 } |
| 249 if (__A == iVertexB->__B) { |
| 250 if ((_t2d == 0) && (iVertexB->_t2d != 1)) |
| 251 return iVertexB->__A->getFEdge(*(iVertexB->__B)); |
| 252 if ((_t2d != 0) && (iVertexB->_t2d == 1)) |
| 253 return __A->getFEdge(*__B); |
| 254 } |
| 255 #if 0 |
| 256 if (G.debug & G_DEBUG_FREESTYLE) { |
| 257 printf("__A 0x%p p (%f, %f)\n", __A, __A->getPoint2D()
.x(), __A->getPoint2D().y()); |
| 258 printf("__B 0x%p p (%f, %f)\n", __B, __B->getPoint2D()
.x(), __B->getPoint2D().y()); |
| 259 printf("iVertexB->A() 0x%p p (%f, %f)\n", iVertexB->A(), iVertex
B->A()->getPoint2D().x(), |
| 260 iVertexB->A()->getPoin
t2D().y()); |
| 261 printf("iVertexB->B() 0x%p p (%f, %f)\n", iVertexB->B(), iVertex
B->B()->getPoint2D().x(), |
| 262 iVertexB->B()->getPoin
t2D().y()); |
| 263 printf("_t2d %f p (%f, %f)\n", _t2d, getPoint2D().x()
, getPoint2D().y()); |
| 264 printf("iVertexB->t2d() %f p (%f, %f)\n", iVertexB->t2d(), iVert
exB->getPoint2D().x(), iVertexB->getPoint2D().y()); |
| 265 } |
| 266 #endif |
| 267 cerr << "Warning: CurvePoint::getFEdge() failed." << endl; |
| 268 |
| 269 return NULL; |
| 270 } |
| 271 |
| 272 |
| 273 Vec3r CurvePoint::normal() const |
| 274 { |
| 275 if (__B == 0) |
| 276 return __A->normal(); |
| 277 if (__A == 0) |
| 278 return __B->normal(); |
| 279 Vec3r Na = __A->normal(); |
| 280 if (Exception::getException()) |
| 281 Na = Vec3r(0, 0, 0); |
| 282 Vec3r Nb = __B->normal(); |
| 283 if (Exception::getException()) |
| 284 Nb = Vec3r(0, 0, 0); |
| 285 // compute t3d: |
| 286 real t3d = SilhouetteGeomEngine::ImageToWorldParameter(__A->getFEdge(*__
B), _t2d); |
| 287 return ((1 - t3d) * Na + t3d * Nb); |
| 288 } |
| 289 |
| 290 |
| 291 #if 0 |
| 292 Material CurvePoint::material() const |
| 293 { |
| 294 if (__A == 0) |
| 295 return __B->material(); |
| 296 return __A->material(); |
| 297 } |
| 298 |
| 299 Id CurvePoint::shape_id() const |
| 300 { |
| 301 if (__A == 0) |
| 302 return __B->shape_id(); |
| 303 return __A->shape_id(); |
| 304 } |
| 305 #endif |
| 306 |
| 307 |
| 308 const SShape *CurvePoint::shape() const |
| 309 { |
| 310 if (__A == 0) |
| 311 return __B->shape(); |
| 312 return __A->shape(); |
| 313 } |
| 314 |
| 315 #if 0 |
| 316 float CurvePoint::shape_importance() const |
| 317 { |
| 318 if (__A == 0) |
| 319 return __B->shape_importance(); |
| 320 return __A->shape_importance(); |
| 321 }· |
| 322 |
| 323 |
| 324 const unsigned CurvePoint::qi() const |
| 325 { |
| 326 if (__A == 0) |
| 327 return __B->qi(); |
| 328 if (__B == 0) |
| 329 return __A->qi(); |
| 330 return __A->getFEdge(*__B)->qi(); |
| 331 } |
| 332 #endif |
| 333 |
| 334 occluder_container::const_iterator CurvePoint::occluders_begin() const |
| 335 { |
| 336 if (__A == 0) |
| 337 return __B->occluders_begin(); |
| 338 if (__B == 0) |
| 339 return __A->occluders_begin(); |
| 340 return __A->getFEdge(*__B)->occluders_begin(); |
| 341 } |
| 342 |
| 343 occluder_container::const_iterator CurvePoint::occluders_end() const |
| 344 { |
| 345 if (__A == 0) |
| 346 return __B->occluders_end(); |
| 347 if (__B == 0) |
| 348 return __A->occluders_end(); |
| 349 return __A->getFEdge(*__B)->occluders_end(); |
| 350 } |
| 351 |
| 352 bool CurvePoint::occluders_empty() const |
| 353 { |
| 354 if (__A == 0) |
| 355 return __B->occluders_empty(); |
| 356 if (__B == 0) |
| 357 return __A->occluders_empty(); |
| 358 return __A->getFEdge(*__B)->occluders_empty(); |
| 359 } |
| 360 |
| 361 int CurvePoint::occluders_size() const |
| 362 { |
| 363 if (__A == 0) |
| 364 return __B->occluders_size(); |
| 365 if (__B == 0) |
| 366 return __A->occluders_size(); |
| 367 return __A->getFEdge(*__B)->occluders_size(); |
| 368 } |
| 369 |
| 370 const SShape *CurvePoint::occluded_shape() const |
| 371 { |
| 372 if (__A == 0) |
| 373 return __B->occluded_shape(); |
| 374 if (__B == 0) |
| 375 return __A->occluded_shape(); |
| 376 return __A->getFEdge(*__B)->occluded_shape(); |
| 377 } |
| 378 |
| 379 const Polygon3r& CurvePoint::occludee() const |
| 380 { |
| 381 if (__A == 0) |
| 382 return __B->occludee(); |
| 383 if (__B == 0) |
| 384 return __A->occludee(); |
| 385 return __A->getFEdge(*__B)->occludee(); |
| 386 } |
| 387 |
| 388 const bool CurvePoint::occludee_empty() const |
| 389 { |
| 390 if (__A == 0) |
| 391 return __B->occludee_empty(); |
| 392 if (__B == 0) |
| 393 return __A->occludee_empty(); |
| 394 return __A->getFEdge(*__B)->occludee_empty(); |
| 395 } |
| 396 |
| 397 real CurvePoint::z_discontinuity() const |
| 398 { |
| 399 if (__A == 0) |
| 400 return __B->z_discontinuity(); |
| 401 if (__B == 0) |
| 402 return __A->z_discontinuity(); |
| 403 if (__A->getFEdge(*__B) == 0) |
| 404 return 0.0; |
| 405 |
| 406 return __A->getFEdge(*__B)->z_discontinuity(); |
| 407 } |
| 408 |
| 409 #if 0 |
| 410 float CurvePoint::local_average_depth() const |
| 411 { |
| 412 return local_average_depth_function<CurvePoint >(this); |
| 413 } |
| 414 |
| 415 float CurvePoint::local_depth_variance() const |
| 416 { |
| 417 return local_depth_variance_function<CurvePoint >(this); |
| 418 } |
| 419 |
| 420 real CurvePoint::local_average_density(float sigma) const |
| 421 { |
| 422 //return local_average_density<CurvePoint >(this); |
| 423 return density_function<CurvePoint >(this); |
| 424 } |
| 425 |
| 426 Vec3r shaded_color() const; |
| 427 |
| 428 Vec3r CurvePoint::orientation2d() const |
| 429 { |
| 430 if (__A == 0) |
| 431 return __B->orientation2d(); |
| 432 if (__B == 0) |
| 433 return __A->orientation2d(); |
| 434 return __B->point2d() - __A->point2d(); |
| 435 } |
| 436 |
| 437 Vec3r CurvePoint::orientation3d() const |
| 438 { |
| 439 if (__A == 0) |
| 440 return __B->orientation3d(); |
| 441 if (__B == 0) |
| 442 return __A->orientation3d(); |
| 443 return __B->point3d() - __A->point3d(); |
| 444 } |
| 445 |
| 446 real curvature2d() const |
| 447 { |
| 448 return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d(
)) / 2.0); |
| 449 } |
| 450 |
| 451 Vec3r CurvePoint::curvature2d_as_vector() const |
| 452 { |
| 453 #if 0 |
| 454 Vec3r edgeA = (_FEdges[0])->orientation2d().normalize(); |
| 455 Vec3r edgeB = (_FEdges[1])->orientation2d().normalize(); |
| 456 return edgeA + edgeB; |
| 457 #endif |
| 458 if (__A == 0) |
| 459 return __B->curvature2d_as_vector(); |
| 460 if (__B == 0) |
| 461 return __A->curvature2d_as_vector(); |
| 462 return ((1 - _t2d) * __A->curvature2d_as_vector() + _t2d * __B->curvatur
e2d_as_vector()); |
| 463 } |
| 464 |
| 465 real CurvePoint::curvature2d_as_angle() const |
| 466 { |
| 467 #if 0 |
| 468 Vec3r edgeA = (_FEdges[0])->orientation2d(); |
| 469 Vec3r edgeB = (_FEdges[1])->orientation2d(); |
| 470 Vec2d N1(-edgeA.y(), edgeA.x()); |
| 471 N1.normalize(); |
| 472 Vec2d N2(-edgeB.y(), edgeB.x()); |
| 473 N2.normalize(); |
| 474 return acos((N1 * N2)); |
| 475 #endif |
| 476 if (__A == 0) |
| 477 return __B->curvature2d_as_angle(); |
| 478 if (__B == 0) |
| 479 return __A->curvature2d_as_angle(); |
| 480 return ((1 - _t2d) * __A->curvature2d_as_angle() + _t2d * __B->curvature
2d_as_angle()); |
| 481 } |
| 482 #endif |
| 483 |
| 484 real CurvePoint::curvatureFredo() const |
| 485 { |
| 486 if (__A == 0) |
| 487 return __B->curvatureFredo(); |
| 488 if (__B == 0) |
| 489 return __A->curvatureFredo(); |
| 490 return ((1 - _t2d) * __A->curvatureFredo() + _t2d * __B->curvatureFredo(
)); |
| 491 } |
| 492 |
| 493 Vec2d CurvePoint::directionFredo () const |
| 494 { |
| 495 if (__A == 0) |
| 496 return __B->directionFredo(); |
| 497 if (__B == 0) |
| 498 return __A->directionFredo(); |
| 499 return ((1 - _t2d) * __A->directionFredo() + _t2d * __B->directionFredo(
)); |
| 500 } |
| 501 |
| 502 /**********************************/ |
| 503 /* */ |
| 504 /* */ |
| 505 /* Curve */ |
| 506 /* */ |
| 507 /* */ |
| 508 /**********************************/ |
| 509 |
| 510 /* for functions */ |
| 511 |
| 512 Curve::~Curve() |
| 513 { |
| 514 if (!_Vertices.empty()) { |
| 515 for (vertex_container::iterator it = _Vertices.begin(), itend =
_Vertices.end(); it != itend; ++it) { |
| 516 delete (*it); |
| 517 } |
| 518 _Vertices.clear(); |
| 519 } |
| 520 } |
| 521 |
| 522 /*! iterators access */ |
| 523 Curve::point_iterator Curve::points_begin(float step) |
| 524 { |
| 525 vertex_container::iterator second = _Vertices.begin(); |
| 526 ++second; |
| 527 return point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Ver
tices.end(), _nSegments, step, 0.0f, 0.0f); |
| 528 //return point_iterator(_Vertices.begin(), second, _nSegments, step, 0.0
f, 0.0f); |
| 529 } |
| 530 |
| 531 Curve::const_point_iterator Curve::points_begin(float step) const |
| 532 { |
| 533 vertex_container::const_iterator second = _Vertices.begin(); |
| 534 ++second; |
| 535 return const_point_iterator(_Vertices.begin(), second, _Vertices.begin()
, _Vertices.end(), |
| 536 _nSegments, step, 0.0f, 0.0f); |
| 537 //return const_point_iterator(_Vertices.begin(), second, _nSegments, ste
p, 0.0f, 0.0f); |
| 538 } |
| 539 |
| 540 Curve::point_iterator Curve::points_end(float step) |
| 541 { |
| 542 return point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(
), _Vertices.end(), |
| 543 _nSegments, step, 1.0f, _Length); |
| 544 //return point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, st
ep, 1.0f, _Length); |
| 545 } |
| 546 |
| 547 Curve::const_point_iterator Curve::points_end(float step) const |
| 548 { |
| 549 return const_point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.
begin(), _Vertices.end(), |
| 550 _nSegments, step, 1.0f, _Length); |
| 551 //return const_point_iterator(_Vertices.end(), _Vertices.end(), _nSegmen
ts, step, 1.0f, _Length); |
| 552 } |
| 553 |
| 554 // Adavnced Iterators access |
| 555 Curve::point_iterator Curve::vertices_begin() |
| 556 { |
| 557 return points_begin(0); |
| 558 } |
| 559 |
| 560 Curve::const_point_iterator Curve::vertices_begin() const |
| 561 { |
| 562 return points_begin(0); |
| 563 } |
| 564 |
| 565 Curve::point_iterator Curve::vertices_end() |
| 566 { |
| 567 return points_end(0); |
| 568 } |
| 569 |
| 570 Curve::const_point_iterator Curve::vertices_end() const |
| 571 { |
| 572 return points_end(0); |
| 573 } |
| 574 |
| 575 // specialized iterators access |
| 576 CurveInternal::CurvePointIterator Curve::curvePointsBegin(float t) |
| 577 { |
| 578 vertex_container::iterator second = _Vertices.begin(); |
| 579 ++second; |
| 580 return CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Ver
tices.begin(), _Vertices.end(), |
| 581 0, _nSegments, _Length, t, 0.0f
, 0.0f); |
| 582 } |
| 583 |
| 584 CurveInternal::CurvePointIterator Curve::curvePointsEnd(float t) |
| 585 { |
| 586 vertex_container::iterator last = _Vertices.end(); |
| 587 --last; |
| 588 return CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertice
s.begin(), _Vertices.end(), |
| 589 _nSegments, _nSegments, _Length
, t, 0.0f, _Length); |
| 590 } |
| 591 |
| 592 CurveInternal::CurvePointIterator Curve::curveVerticesBegin() |
| 593 { |
| 594 return curvePointsBegin(0); |
| 595 } |
| 596 |
| 597 CurveInternal::CurvePointIterator Curve::curveVerticesEnd() |
| 598 { |
| 599 return curvePointsEnd(0); |
| 600 } |
| 601 |
| 602 Interface0DIterator Curve::pointsBegin(float t) |
| 603 { |
| 604 vertex_container::iterator second = _Vertices.begin(); |
| 605 ++second; |
| 606 Interface0DIterator ret(new CurveInternal::CurvePointIterator(_Vertices.
begin(), second, _Vertices.begin(), |
| 607 _Vertices.
end(), 0, _nSegments, _Length, |
| 608 t, 0.0f, 0
.0f)); |
| 609 return ret; |
| 610 } |
| 611 |
| 612 Interface0DIterator Curve::pointsEnd(float t) |
| 613 { |
| 614 vertex_container::iterator last = _Vertices.end(); |
| 615 --last; |
| 616 Interface0DIterator ret(new CurveInternal::CurvePointIterator(last, _Ver
tices.end(), _Vertices.begin(), |
| 617 _Vertices.
end(), _nSegments, _nSegments, |
| 618 _Length, t
, 0.0f, _Length)); |
| 619 return ret; |
| 620 } |
| 621 |
| 622 Interface0DIterator Curve::verticesBegin() |
| 623 { |
| 624 return pointsBegin(0); |
| 625 } |
| 626 |
| 627 Interface0DIterator Curve::verticesEnd() |
| 628 { |
| 629 return pointsEnd(0); |
| 630 } |
| 631 |
| 632 #if 0 |
| 633 Vec3r shaded_color(int iCombination = 0) const; |
| 634 |
| 635 Vec3r Curve::orientation2d(point_iterator it) const |
| 636 { |
| 637 return (*it)->orientation2d(); |
| 638 } |
| 639 |
| 640 template <class BaseVertex> |
| 641 Vec3r Curve::orientation2d(int iCombination) const |
| 642 { |
| 643 return edge_orientation2d_function<Curve >(this, iCombination); |
| 644 } |
| 645 |
| 646 Vec3r Curve::orientation3d(point_iterator it) const |
| 647 { |
| 648 return (*it)->orientation3d(); |
| 649 } |
| 650 |
| 651 Vec3r Curve::orientation3d(int iCombination) const |
| 652 { |
| 653 return edge_orientation3d_function<Curve >(this, iCombination); |
| 654 } |
| 655 |
| 656 real curvature2d(point_iterator it) const |
| 657 { |
| 658 return (*it)->curvature2d(); |
| 659 } |
| 660 |
| 661 real curvature2d(int iCombination = 0) const; |
| 662 |
| 663 Material Curve::material() const |
| 664 { |
| 665 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 666 const Material& mat = (*v)->material(); |
| 667 for (; v != vend; ++v) { |
| 668 if ((*v)->material() != mat) |
| 669 Exception::raiseException(); |
| 670 } |
| 671 return mat; |
| 672 } |
| 673 |
| 674 int Curve::qi() const |
| 675 { |
| 676 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 677 int qi_ = (*v)->qi(); |
| 678 for (; v != vend; ++v) { |
| 679 if ((*v)->qi() != qi_) |
| 680 Exception::raiseException(); |
| 681 } |
| 682 return qi_; |
| 683 } |
| 684 |
| 685 occluder_container::const_iterator occluders_begin() const |
| 686 { |
| 687 return _FEdgeA->occluders().begin(); |
| 688 } |
| 689 |
| 690 occluder_container::const_iterator occluders_end() const |
| 691 { |
| 692 return _FEdgeA->occluders().end(); |
| 693 } |
| 694 |
| 695 int Curve::occluders_size() const |
| 696 { |
| 697 return qi(); |
| 698 } |
| 699 |
| 700 bool Curve::occluders_empty() const |
| 701 { |
| 702 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 703 bool empty = (*v)->occluders_empty(); |
| 704 for (; v != vend; ++v) { |
| 705 if ((*v)->occluders_empty() != empty) |
| 706 Exception::raiseException(); |
| 707 } |
| 708 return empty; |
| 709 } |
| 710 |
| 711 const Polygon3r& occludee() const |
| 712 { |
| 713 return *(_FEdgeA->aFace()); |
| 714 } |
| 715 |
| 716 const SShape *Curve::occluded_shape() const |
| 717 { |
| 718 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 719 const SShape *sshape = (*v)->occluded_shape(); |
| 720 for (; v != vend; ++v) { |
| 721 if ((*v)->occluded_shape() != sshape) |
| 722 Exception::raiseException(); |
| 723 } |
| 724 return sshape; |
| 725 } |
| 726 |
| 727 const bool Curve::occludee_empty() const |
| 728 { |
| 729 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 730 bool empty = (*v)->occludee_empty(); |
| 731 for (; v != vend; ++v) { |
| 732 if ((*v)->occludee_empty() != empty) |
| 733 Exception::raiseException(); |
| 734 } |
| 735 return empty; |
| 736 } |
| 737 real Curve::z_discontinuity(int iCombination) const |
| 738 { |
| 739 return z_discontinuity_edge_function<Curve>(this, iCombination); |
| 740 } |
| 741 |
| 742 int Curve::shape_id() const |
| 743 { |
| 744 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 745 Id id = (*v)->shape_id(); |
| 746 for (; v != vend; ++v) { |
| 747 if ((*v)->shape_id() != id) |
| 748 Exception::raiseException(); |
| 749 } |
| 750 return id.first; |
| 751 } |
| 752 |
| 753 |
| 754 const SShape *Curve::shape() const |
| 755 { |
| 756 const_vertex_iterator v = vertices_begin(), vend = vertices_end(); |
| 757 const SShape *sshape = (*v)->shape(); |
| 758 for (; v != vend; ++v) { |
| 759 if ((*v)->shape() != sshape) |
| 760 Exception::raiseException(); |
| 761 } |
| 762 return sshape; |
| 763 } |
| 764 |
| 765 |
| 766 occluder_container::const_iterator Curve::occluders_begin() const |
| 767 { |
| 768 const_vertex_iterator v = vertices_begin(); |
| 769 return (*v)->occluders_begin(); |
| 770 } |
| 771 |
| 772 |
| 773 occluder_container::const_iterator Curve::occluders_end() const |
| 774 { |
| 775 const_vertex_iterator v = vertices_end(); |
| 776 return (*v)->occluders_end(); |
| 777 } |
| 778 |
| 779 Vec3r Curve::curvature2d_as_vector(int iCombination) const |
| 780 { |
| 781 return curvature2d_as_vector_edge_function<Curve>(this, iCombination); |
| 782 } |
| 783 |
| 784 real Curve::curvature2d_as_angle(int iCombination) const |
| 785 { |
| 786 return curvature2d_as_angle_edge_function<Curve>(this, iCombination); |
| 787 } |
| 788 |
| 789 float Curve::shape_importance(int iCombination) const |
| 790 { |
| 791 return shape_importance_edge_function<Curve>(this, iCombination); |
| 792 } |
| 793 |
| 794 float Curve::local_average_depth(int iCombination) const |
| 795 { |
| 796 return local_average_depth_edge_function<Curve>(this, iCombination); |
| 797 } |
| 798 |
| 799 float Curve::local_depth_variance(int iCombination ) const |
| 800 { |
| 801 return local_depth_variance_edge_function<Curve>(this, iCombination); |
| 802 #if 0 |
| 803 local_depth_variance_functor<Point> functor; |
| 804 float result; |
| 805 Evaluate<float, local_depth_variance_functor<Point> >(&functor, iCombina
tion, result); |
| 806 return result; |
| 807 #endif |
| 808 } |
| 809 |
| 810 real Curve::local_average_density(float sigma, int iCombination ) const |
| 811 { |
| 812 return density_edge_function<Curve>(this, iCombination); |
| 813 #if 0 |
| 814 density_functor<Point> functor; |
| 815 real result; |
| 816 Evaluate<real, density_functor<Point> >(&functor, iCombination, result); |
| 817 return result; |
| 818 #endif |
| 819 } |
| 820 #endif |
| 821 |
| 822 #define EPS_CURVA_DIR 0.01 |
| 823 |
| 824 void Curve::computeCurvatureAndOrientation () |
| 825 { |
| 826 #if 0 |
| 827 const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, p
revV, v0; |
| 828 Vec2d p0, p1, p2; |
| 829 Vec3r p; |
| 830 |
| 831 p = (*v)->point2d(); |
| 832 p0 = Vec2d(p[0], p[1]); |
| 833 prevV = v; |
| 834 ++v; |
| 835 p = (*v)->point2d(); |
| 836 p1 = Vec2d(p[0], p[1]); |
| 837 Vec2d prevDir(p1 - p0); |
| 838 |
| 839 for (; v! = vend; ++v) { |
| 840 v2 = v; |
| 841 ++v2; |
| 842 if (v2 == vend) |
| 843 break; |
| 844 Vec3r p2 = (*v2)->point2d(); |
| 845 |
| 846 Vec2d BA = p0 - p1; |
| 847 Vec2d BC = p2 - p1; |
| 848 real lba = BA.norm(), lbc = BC.norm(); |
| 849 BA.normalizeSafe(); |
| 850 BC.normalizeSafe(); |
| 851 Vec2d normalCurvature = BA + BC; |
| 852 Vec2d dir = Vec2d(BC - BA); |
| 853 Vec2d normal = Vec2d(-dir[1], dir[0]); |
| 854 |
| 855 normal.normalizeSafe(); |
| 856 real curvature = normalCurvature * normal; |
| 857 if (lba + lbc > MY_EPSILON) |
| 858 curvature /= (0.5 * lba + lbc); |
| 859 if (dir.norm() < MY_EPSILON) |
| 860 dir = 0.1 * prevDir; |
| 861 (*v)->setCurvatureFredo(curvature); |
| 862 (*v)->setDirectionFredo(dir); |
| 863 |
| 864 prevV = v; |
| 865 p0 = p1; |
| 866 p1 = p2; |
| 867 prevDir = dir; |
| 868 prevDir.normalize(); |
| 869 } |
| 870 (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); |
| 871 (*v)->setDirectionFredo((*v)->point2d() - (*prevV)->point2d()); |
| 872 v0 = vertices_begin(); |
| 873 v2 = v0; |
| 874 ++v2; |
| 875 (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); |
| 876 (*v0)->setDirectionFredo((*v2)->point2d() - (*v0)->point2d()); |
| 877 |
| 878 //closed curve case one day... |
| 879 |
| 880 // |
| 881 return; |
| 882 |
| 883 //numerical degeneracy verification... we'll see later |
| 884 const_vertex_iterator vLastReliable = vertices_begin(); |
| 885 |
| 886 v = vertices_begin(); |
| 887 p = (*v)->point2d(); |
| 888 p0 = Vec2d(p[0], p[1]); |
| 889 prevV = v; |
| 890 ++v; |
| 891 p = (*v)->point2d(); |
| 892 p1 = Vec2d(p[0], p[1]); |
| 893 bool isReliable = false; |
| 894 if ((p1 - p0).norm > EPS_CURVA) { |
| 895 vLastReliable = v; |
| 896 isReliable = true; |
| 897 } |
| 898 |
| 899 for (; v != vend; ++v) { |
| 900 v2 = v; |
| 901 ++v2; |
| 902 if (v2 == vend) |
| 903 break; |
| 904 Vec3r p2 = (*v2)->point2d(); |
| 905 |
| 906 Vec2d BA = p0 - p1; |
| 907 Vec2d BC = p2 - p1; |
| 908 real lba = BA.norm(), lbc = BC.norm(); |
| 909 |
| 910 if ((lba + lbc) < EPS_CURVA) { |
| 911 isReliable = false; |
| 912 cerr << "/"; |
| 913 } |
| 914 else { |
| 915 if (!isReliable) { //previous points were not reliable |
| 916 const_vertex_iterator vfix = vLastReliable; |
| 917 ++vfix; |
| 918 for (; vfix != v; ++vfix) { |
| 919 (*vfix)->setCurvatureFredo((*v)->curvatu
reFredo()); |
| 920 (*vfix)->setDirectionFredo((*v)->directi
onFredo()); |
| 921 } |
| 922 } |
| 923 isReliable = true; |
| 924 vLastReliable = v; |
| 925 } |
| 926 prevV = v; |
| 927 p0 = p1; |
| 928 p1 = p2; |
| 929 } |
| 930 #endif |
| 931 } |
OLD | NEW |