Blender V5.0
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
9
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
570/* Iterators access. */
571
572Curve::point_iterator Curve::points_begin(float step)
573{
574 vertex_container::iterator second = _Vertices.begin();
575 ++second;
576 return point_iterator(
577 _Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.0f, 0.0f);
578 // return point_iterator(_Vertices.begin(), second, _nSegments, step, 0.0f, 0.0f);
579}
580
581Curve::const_point_iterator Curve::points_begin(float step) const
582{
583 vertex_container::const_iterator second = _Vertices.begin();
584 ++second;
586 _Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.0f, 0.0f);
587 // return const_point_iterator(_Vertices.begin(), second, _nSegments, step, 0.0f, 0.0f);
588}
589
590Curve::point_iterator Curve::points_end(float step)
591{
592 return point_iterator(_Vertices.end(),
593 _Vertices.end(),
594 _Vertices.begin(),
595 _Vertices.end(),
597 step,
598 1.0f,
599 _Length);
600 // return point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.0f, _Length);
601}
602
603Curve::const_point_iterator Curve::points_end(float step) const
604{
605 return const_point_iterator(_Vertices.end(),
606 _Vertices.end(),
607 _Vertices.begin(),
608 _Vertices.end(),
610 step,
611 1.0f,
612 _Length);
613 // return const_point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.0f,
614 // _Length);
615}
616
617// Adavnced Iterators access
618Curve::point_iterator Curve::vertices_begin()
619{
620 return points_begin(0);
621}
622
623Curve::const_point_iterator Curve::vertices_begin() const
624{
625 return points_begin(0);
626}
627
628Curve::point_iterator Curve::vertices_end()
629{
630 return points_end(0);
631}
632
633Curve::const_point_iterator Curve::vertices_end() const
634{
635 return points_end(0);
636}
637
638// specialized iterators access
639CurveInternal::CurvePointIterator Curve::curvePointsBegin(float t)
640{
641 vertex_container::iterator second = _Vertices.begin();
642 ++second;
644 second,
645 _Vertices.begin(),
646 _Vertices.end(),
647 0,
649 _Length,
650 t,
651 0.0f,
652 0.0f);
653}
654
655CurveInternal::CurvePointIterator Curve::curvePointsEnd(float t)
656{
657 vertex_container::iterator last = _Vertices.end();
658 --last;
660 _Vertices.end(),
661 _Vertices.begin(),
662 _Vertices.end(),
665 _Length,
666 t,
667 0.0f,
668 _Length);
669}
670
671CurveInternal::CurvePointIterator Curve::curveVerticesBegin()
672{
673 return curvePointsBegin(0);
674}
675
676CurveInternal::CurvePointIterator Curve::curveVerticesEnd()
677{
678 return curvePointsEnd(0);
679}
680
681Interface0DIterator Curve::pointsBegin(float t)
682{
683 vertex_container::iterator second = _Vertices.begin();
684 ++second;
686 second,
687 _Vertices.begin(),
688 _Vertices.end(),
689 0,
691 _Length,
692 t,
693 0.0f,
694 0.0f));
695 return ret;
696}
697
698Interface0DIterator Curve::pointsEnd(float t)
699{
700 vertex_container::iterator last = _Vertices.end();
701 --last;
703 _Vertices.end(),
704 _Vertices.begin(),
705 _Vertices.end(),
708 _Length,
709 t,
710 0.0f,
711 _Length));
712 return ret;
713}
714
715Interface0DIterator Curve::verticesBegin()
716{
717 return pointsBegin(0);
718}
719
720Interface0DIterator Curve::verticesEnd()
721{
722 return pointsEnd(0);
723}
724
725#if 0
726Vec3r shaded_color(int iCombination = 0) const;
727
728Vec3r Curve::orientation2d(point_iterator it) const
729{
730 return (*it)->orientation2d();
731}
732
733template<class BaseVertex> Vec3r Curve::orientation2d(int iCombination) const
734{
735 return edge_orientation2d_function<Curve>(this, iCombination);
736}
737
738Vec3r Curve::orientation3d(point_iterator it) const
739{
740 return (*it)->orientation3d();
741}
742
743Vec3r Curve::orientation3d(int iCombination) const
744{
745 return edge_orientation3d_function<Curve>(this, iCombination);
746}
747
748real curvature2d(point_iterator it) const
749{
750 return (*it)->curvature2d();
751}
752
753real curvature2d(int iCombination = 0) const;
754
755Material Curve::material() const
756{
758 const Material &mat = (*v)->material();
759 for (; v != vend; ++v) {
760 if ((*v)->material() != mat) {
762 }
763 }
764 return mat;
765}
766
767int Curve::qi() const
768{
770 int qi_ = (*v)->qi();
771 for (; v != vend; ++v) {
772 if ((*v)->qi() != qi_) {
774 }
775 }
776 return qi_;
777}
778
779occluder_container::const_iterator occluders_begin() const
780{
781 return _FEdgeA->occluders().begin();
782}
783
784occluder_container::const_iterator occluders_end() const
785{
786 return _FEdgeA->occluders().end();
787}
788
789int Curve::occluders_size() const
790{
791 return qi();
792}
793
794bool Curve::occluders_empty() const
795{
797 bool empty = (*v)->occluders_empty();
798 for (; v != vend; ++v) {
799 if ((*v)->occluders_empty() != empty) {
801 }
802 }
803 return empty;
804}
805
806const Polygon3r &occludee() const
807{
808 return *(_FEdgeA->aFace());
809}
810
811const SShape *Curve::occluded_shape() const
812{
814 const SShape *sshape = (*v)->occluded_shape();
815 for (; v != vend; ++v) {
816 if ((*v)->occluded_shape() != sshape) {
818 }
819 }
820 return sshape;
821}
822
823const bool Curve::occludee_empty() const
824{
826 bool empty = (*v)->occludee_empty();
827 for (; v != vend; ++v) {
828 if ((*v)->occludee_empty() != empty) {
830 }
831 }
832 return empty;
833}
834real Curve::z_discontinuity(int iCombination) const
835{
836 return z_discontinuity_edge_function<Curve>(this, iCombination);
837}
838
839int Curve::shape_id() const
840{
842 Id id = (*v)->shape_id();
843 for (; v != vend; ++v) {
844 if ((*v)->shape_id() != id) {
846 }
847 }
848 return id.first;
849}
850
851const SShape *Curve::shape() const
852{
854 const SShape *sshape = (*v)->shape();
855 for (; v != vend; ++v) {
856 if ((*v)->shape() != sshape) {
858 }
859 }
860 return sshape;
861}
862
863occluder_container::const_iterator Curve::occluders_begin() const
864{
866 return (*v)->occluders_begin();
867}
868
869occluder_container::const_iterator Curve::occluders_end() const
870{
872 return (*v)->occluders_end();
873}
874
875Vec3r Curve::curvature2d_as_vector(int iCombination) const
876{
877 return curvature2d_as_vector_edge_function<Curve>(this, iCombination);
878}
879
880real Curve::curvature2d_as_angle(int iCombination) const
881{
882 return curvature2d_as_angle_edge_function<Curve>(this, iCombination);
883}
884
885float Curve::shape_importance(int iCombination) const
886{
887 return shape_importance_edge_function<Curve>(this, iCombination);
888}
889
890float Curve::local_average_depth(int iCombination) const
891{
892 return local_average_depth_edge_function<Curve>(this, iCombination);
893}
894
895float Curve::local_depth_variance(int iCombination) const
896{
897 return local_depth_variance_edge_function<Curve>(this, iCombination);
898# if 0
899 local_depth_variance_functor<Point> functor;
900 float result;
901 Evaluate<float, local_depth_variance_functor<Point>>(&functor, iCombination, result);
902 return result;
903# endif
904}
905
906real Curve::local_average_density(float sigma, int iCombination) const
907{
908 return density_edge_function<Curve>(this, iCombination);
909# if 0
910 density_functor<Point> functor;
911 real result;
912 Evaluate<real, density_functor<Point>>(&functor, iCombination, result);
913 return result;
914# endif
915}
916
917/* UNUSED */
918// #define EPS_CURVA_DIR 0.01
919
920void Curve::computeCurvatureAndOrientation()
921{
922 const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, prevV, v0;
923 Vec2d p0, p1, p2;
924 Vec3r p;
925
926 p = (*v)->point2d();
927 p0 = Vec2d(p[0], p[1]);
928 prevV = v;
929 ++v;
930 p = (*v)->point2d();
931 p1 = Vec2d(p[0], p[1]);
932 Vec2d prevDir(p1 - p0);
933
934 for (; v ! = vend; ++v) {
935 v2 = v;
936 ++v2;
937 if (v2 == vend) {
938 break;
939 }
940 Vec3r p2 = (*v2)->point2d();
941
942 Vec2d BA = p0 - p1;
943 Vec2d BC = p2 - p1;
944 real lba = BA.norm(), lbc = BC.norm();
945 BA.normalizeSafe();
946 BC.normalizeSafe();
947 Vec2d normalCurvature = BA + BC;
948 Vec2d dir = Vec2d(BC - BA);
949 Vec2d normal = Vec2d(-dir[1], dir[0]);
950
951 normal.normalizeSafe();
952 real curvature = normalCurvature * normal;
953 if (lba + lbc > MY_EPSILON) {
954 curvature /= (0.5 * lba + lbc);
955 }
956 if (dir.norm() < MY_EPSILON) {
957 dir = 0.1 * prevDir;
958 }
959 (*v)->setCurvatureFredo(curvature);
960 (*v)->setDirectionFredo(dir);
961
962 prevV = v;
963 p0 = p1;
964 p1 = p2;
965 prevDir = dir;
966 prevDir.normalize();
967 }
968 (*v)->setCurvatureFredo((*prevV)->curvatureFredo());
969 (*v)->setDirectionFredo((*v)->point2d() - (*prevV)->point2d());
970 v0 = vertices_begin();
971 v2 = v0;
972 ++v2;
973 (*v0)->setCurvatureFredo((*v2)->curvatureFredo());
974 (*v0)->setDirectionFredo((*v2)->point2d() - (*v0)->point2d());
975
976 // closed curve case one day...
977
978 //
979 return;
980
981 // numerical degeneracy verification... we'll see later
982 const_vertex_iterator vLastReliable = vertices_begin();
983
984 v = vertices_begin();
985 p = (*v)->point2d();
986 p0 = Vec2d(p[0], p[1]);
987 prevV = v;
988 ++v;
989 p = (*v)->point2d();
990 p1 = Vec2d(p[0], p[1]);
991 bool isReliable = false;
992 if ((p1 - p0).norm > EPS_CURVA) {
993 vLastReliable = v;
994 isReliable = true;
995 }
996
997 for (; v != vend; ++v) {
998 v2 = v;
999 ++v2;
1000 if (v2 == vend) {
1001 break;
1002 }
1003 Vec3r p2 = (*v2)->point2d();
1004
1005 Vec2d BA = p0 - p1;
1006 Vec2d BC = p2 - p1;
1007 real lba = BA.norm(), lbc = BC.norm();
1008
1009 if ((lba + lbc) < EPS_CURVA) {
1010 isReliable = false;
1011 cerr << "/";
1012 }
1013 else {
1014 if (!isReliable) { // previous points were not reliable
1015 const_vertex_iterator vfix = vLastReliable;
1016 ++vfix;
1017 for (; vfix != v; ++vfix) {
1018 (*vfix)->setCurvatureFredo((*v)->curvatureFredo());
1019 (*vfix)->setDirectionFredo((*v)->directionFredo());
1020 }
1021 }
1022 isReliable = true;
1023 vLastReliable = v;
1024 }
1025 prevV = v;
1026 p0 = p1;
1027 p1 = p2;
1028 }
1029}
1030#endif
1031
1032} /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
#define BLI_assert(a)
Definition BLI_assert.h:46
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.
struct Material Material
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:247
virtual Nature::VertexNature getNature() const
Definition Curve.h:121
const Vec3r & point2d() const
Definition Curve.h:289
SVertex * A()
Definition Curve.h:235
Vec3r normal() const
Definition Curve.cpp:283
bool occludee_empty() const
Definition Curve.cpp:417
virtual Vec2r getPoint2D() const
Definition Curve.h:100
occluder_container::const_iterator occluders_end() const
Definition Curve.cpp:362
SVertex * B()
Definition Curve.h:241
const Polygon3r & occludee() const
Definition Curve.cpp:406
const SShape * shape() const
Definition Curve.cpp:322
point_iterator vertices_end()
Definition Curve.cpp:628
vertex_container _Vertices
Definition Curve.h:377
CurveInternal::__point_iterator< CurveInternal::CurvePoint_nonconst_traits > point_iterator
Definition Curve.h:370
uint _nSegments
Definition Curve.h:380
point_iterator points_end(float step=0)
Definition Curve.cpp:590
CurveInternal::__point_iterator< CurveInternal::CurvePoint_const_traits > const_point_iterator
Definition Curve.h:372
virtual Interface0DIterator pointsBegin(float t=0.0f)
Definition Curve.cpp:681
CurveInternal::CurvePointIterator curvePointsBegin(float t=0.0f)
Definition Curve.cpp:639
bool empty() const
Definition Curve.h:471
virtual Interface0DIterator pointsEnd(float t=0.0f)
Definition Curve.cpp:698
double _Length
Definition Curve.h:378
point_iterator vertices_begin()
Definition Curve.cpp:618
point_iterator points_begin(float step=0)
Definition Curve.cpp:572
const_point_iterator const_vertex_iterator
Definition Curve.h:374
CurveInternal::CurvePointIterator curvePointsEnd(float t=0.0f)
Definition Curve.cpp:655
static int getException()
Definition Exception.h:23
static int raiseException(exception_type exception=UNDEFINED)
Definition Exception.h:30
virtual FEdge * getFEdge(Interface0D &)
const Vec3r & point3d() const
Definition Silhouette.h:400
virtual Vec2r getPoint2D() const
Definition Silhouette.h:108
float shape_importance() const
static real ImageToWorldParameter(FEdge *fe, real t)
value_type x() const
Definition VecMat.h:292
value_type y() const
Definition VecMat.h:302
Vec< T, N > & normalize()
Definition VecMat.h:102
value_type norm() const
Definition VecMat.h:92
#define printf(...)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
#define acos
#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
return ret
struct Material ** mat