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