Blender  V2.93
Operators.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
22 #include <algorithm>
23 #include <stdexcept>
24 
25 #include "Canvas.h"
26 #include "CurveIterators.h"
27 #include "Operators.h"
28 #include "Stroke.h"
29 #include "StrokeIterators.h"
30 
31 #include "BKE_global.h"
32 
33 namespace Freestyle {
34 
35 Operators::I1DContainer Operators::_current_view_edges_set;
36 Operators::I1DContainer Operators::_current_chains_set;
37 Operators::I1DContainer *Operators::_current_set = nullptr;
38 Operators::StrokesContainer Operators::_current_strokes_set;
39 
41 {
42  if (!_current_set) {
43  return 0;
44  }
45  if (_current_set->empty()) {
46  return 0;
47  }
48  I1DContainer new_set;
49  I1DContainer rejected;
52  I1DContainer::iterator it = _current_set->begin();
53  I1DContainer::iterator itbegin = it;
54  while (it != _current_set->end()) {
55  Interface1D *i1d = *it;
56  cts(*i1d); // mark everyone's chaining time stamp anyway
57  if (pred(*i1d) < 0) {
58  new_set.clear();
59  rejected.clear();
60  return -1;
61  }
62  if (pred.result) {
63  new_set.push_back(i1d);
64  ts(*i1d);
65  }
66  else {
67  rejected.push_back(i1d);
68  }
69  ++it;
70  }
71  if ((*itbegin)->getExactTypeName() != "ViewEdge") {
72  for (it = rejected.begin(); it != rejected.end(); ++it) {
73  delete *it;
74  }
75  }
76  rejected.clear();
77  _current_set->clear();
78  *_current_set = new_set;
79  return 0;
80 }
81 
83  UnaryPredicate1D &pred,
84  UnaryFunction1D_void &modifier)
85 {
86  if (_current_view_edges_set.empty()) {
87  return 0;
88  }
89 
90  unsigned id = 0;
91  ViewEdge *edge;
92  I1DContainer new_chains_set;
93 
94  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
95  it_edge != _current_view_edges_set.end();
96  ++it_edge) {
97  if (pred(**it_edge) < 0) {
98  goto error;
99  }
100  if (pred.result) {
101  continue;
102  }
103 
104  edge = dynamic_cast<ViewEdge *>(*it_edge);
105  it.setBegin(edge);
106  it.setCurrentEdge(edge);
107 
108  Chain *new_chain = new Chain(id);
109  ++id;
110  while (true) {
111  new_chain->push_viewedge_back(*it, it.getOrientation());
112  if (modifier(**it) < 0) {
113  delete new_chain;
114  goto error;
115  }
116  ++it;
117  if (it.isEnd()) {
118  break;
119  }
120  if (pred(**it) < 0) {
121  delete new_chain;
122  goto error;
123  }
124  if (pred.result) {
125  break;
126  }
127  }
128  new_chains_set.push_back(new_chain);
129  }
130 
131  if (!new_chains_set.empty()) {
132  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
133  _current_chains_set.push_back(*it);
134  }
135  new_chains_set.clear();
136  _current_set = &_current_chains_set;
137  }
138  return 0;
139 
140 error:
141  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
142  delete (*it);
143  }
144  new_chains_set.clear();
145  return -1;
146 }
147 
149 {
150  if (_current_view_edges_set.empty()) {
151  return 0;
152  }
153 
154  unsigned id = 0;
157  ViewEdge *edge;
158  I1DContainer new_chains_set;
159 
160  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
161  it_edge != _current_view_edges_set.end();
162  ++it_edge) {
163  if (pred(**it_edge) < 0) {
164  goto error;
165  }
166  if (pred.result) {
167  continue;
168  }
169  if (pred_ts(**it_edge) < 0) {
170  goto error;
171  }
172  if (pred_ts.result) {
173  continue;
174  }
175 
176  edge = dynamic_cast<ViewEdge *>(*it_edge);
177  it.setBegin(edge);
178  it.setCurrentEdge(edge);
179 
180  Chain *new_chain = new Chain(id);
181  ++id;
182  while (true) {
183  new_chain->push_viewedge_back(*it, it.getOrientation());
184  ts(**it);
185  ++it;
186  if (it.isEnd()) {
187  break;
188  }
189  if (pred(**it) < 0) {
190  delete new_chain;
191  goto error;
192  }
193  if (pred.result) {
194  break;
195  }
196  if (pred_ts(**it) < 0) {
197  delete new_chain;
198  goto error;
199  }
200  if (pred_ts.result) {
201  break;
202  }
203  }
204  new_chains_set.push_back(new_chain);
205  }
206 
207  if (!new_chains_set.empty()) {
208  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
209  _current_chains_set.push_back(*it);
210  }
211  new_chains_set.clear();
212  _current_set = &_current_chains_set;
213  }
214  return 0;
215 
216 error:
217  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
218  delete (*it);
219  }
220  new_chains_set.clear();
221  return -1;
222 }
223 
224 #if 0
225 void Operators::bidirectionalChain(ViewEdgeIterator &it,
226  UnaryPredicate1D &pred,
227  UnaryFunction1D_void &modifier)
228 {
229  if (_current_view_edges_set.empty()) {
230  return;
231  }
232 
233  unsigned id = 0;
234  ViewEdge *edge;
235  Chain *new_chain;
236 
237  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
238  it_edge != _current_view_edges_set.end();
239  ++it_edge) {
240  if (pred(**it_edge)) {
241  continue;
242  }
243 
244  edge = dynamic_cast<ViewEdge *>(*it_edge);
245  it.setBegin(edge);
246  it.setCurrentEdge(edge);
247 
248  Chain *new_chain = new Chain(id);
249  ++id;
250 # if 0 // FIXME
251  ViewEdgeIterator it_back(it);
252  --it_back;
253 # endif
254  do {
255  new_chain->push_viewedge_back(*it, it.getOrientation());
256  modifier(**it);
257  ++it;
258  } while (!it.isEnd() && !pred(**it));
259  it.setBegin(edge);
260  it.setCurrentEdge(edge);
261  --it;
262  while (!it.isEnd() && !pred(**it)) {
263  new_chain->push_viewedge_front(*it, it.getOrientation());
264  modifier(**it);
265  --it;
266  }
267 
268  _current_chains_set.push_back(new_chain);
269  }
270 
271  if (!_current_chains_set.empty()) {
272  _current_set = &_current_chains_set;
273  }
274 }
275 
276 void Operators::bidirectionalChain(ViewEdgeIterator &it, UnaryPredicate1D &pred)
277 {
278  if (_current_view_edges_set.empty()) {
279  return;
280  }
281 
282  unsigned id = 0;
283  Functions1D::IncrementChainingTimeStampF1D ts;
284  Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1);
285 
286  ViewEdge *edge;
287  Chain *new_chain;
288 
289  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
290  it_edge != _current_view_edges_set.end();
291  ++it_edge) {
292  if (pred(**it_edge) || pred_ts(**it_edge)) {
293  continue;
294  }
295 
296  edge = dynamic_cast<ViewEdge *>(*it_edge);
297  it.setBegin(edge);
298  it.setCurrentEdge(edge);
299 
300  Chain *new_chain = new Chain(id);
301  ++id;
302 # if 0 // FIXME
303  ViewEdgeIterator it_back(it);
304  --it_back;
305 # endif
306  do {
307  new_chain->push_viewedge_back(*it, it.getOrientation());
308  ts(**it);
309  ++it;
310  } while (!it.isEnd() && !pred(**it) && !pred_ts(**it));
311  it.setBegin(edge);
312  it.setCurrentEdge(edge);
313  --it;
314  while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) {
315  new_chain->push_viewedge_front(*it, it.getOrientation());
316  ts(**it);
317  --it;
318  }
319 
320  _current_chains_set.push_back(new_chain);
321  }
322 
323  if (!_current_chains_set.empty()) {
324  _current_set = &_current_chains_set;
325  }
326 }
327 #endif
328 
330 {
331  if (_current_view_edges_set.empty()) {
332  return 0;
333  }
334 
335  unsigned id = 0;
338  ViewEdge *edge;
339  I1DContainer new_chains_set;
340 
341  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
342  it_edge != _current_view_edges_set.end();
343  ++it_edge) {
344  if (pred(**it_edge) < 0) {
345  goto error;
346  }
347  if (pred.result) {
348  continue;
349  }
350  if (pred_ts(**it_edge) < 0) {
351  goto error;
352  }
353  if (pred_ts.result) {
354  continue;
355  }
356 
357  edge = dynamic_cast<ViewEdge *>(*it_edge);
358  // re-init iterator
359  it.setBegin(edge);
360  it.setCurrentEdge(edge);
361  it.setOrientation(true);
362  if (it.init() < 0) {
363  goto error;
364  }
365 
366  Chain *new_chain = new Chain(id);
367  ++id;
368 #if 0 // FIXME
369  ViewEdgeIterator it_back(it);
370  --it_back;
371 #endif
372  while (true) {
373  new_chain->push_viewedge_back(*it, it.getOrientation());
374  ts(**it);
375  if (it.increment() < 0) {
376  delete new_chain;
377  goto error;
378  }
379  if (it.isEnd()) {
380  break;
381  }
382  if (pred(**it) < 0) {
383  delete new_chain;
384  goto error;
385  }
386  if (pred.result) {
387  break;
388  }
389  }
390  it.setBegin(edge);
391  it.setCurrentEdge(edge);
392  it.setOrientation(true);
393  if (it.decrement() < 0) {
394  delete new_chain;
395  goto error;
396  }
397  while (!it.isEnd()) {
398  if (pred(**it) < 0) {
399  delete new_chain;
400  goto error;
401  }
402  if (pred.result) {
403  break;
404  }
405  new_chain->push_viewedge_front(*it, it.getOrientation());
406  ts(**it);
407  if (it.decrement() < 0) {
408  delete new_chain;
409  goto error;
410  }
411  }
412  new_chains_set.push_back(new_chain);
413  }
414 
415  if (!new_chains_set.empty()) {
416  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
417  _current_chains_set.push_back(*it);
418  }
419  new_chains_set.clear();
420  _current_set = &_current_chains_set;
421  }
422  return 0;
423 
424 error:
425  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
426  delete (*it);
427  }
428  new_chains_set.clear();
429  return -1;
430 }
431 
433 {
434  if (_current_view_edges_set.empty()) {
435  return 0;
436  }
437 
438  unsigned id = 0;
441  ViewEdge *edge;
442  I1DContainer new_chains_set;
443 
444  for (I1DContainer::iterator it_edge = _current_view_edges_set.begin();
445  it_edge != _current_view_edges_set.end();
446  ++it_edge) {
447  if (pred_ts(**it_edge) < 0) {
448  goto error;
449  }
450  if (pred_ts.result) {
451  continue;
452  }
453 
454  edge = dynamic_cast<ViewEdge *>(*it_edge);
455  // re-init iterator
456  it.setBegin(edge);
457  it.setCurrentEdge(edge);
458  it.setOrientation(true);
459  if (it.init() < 0) {
460  goto error;
461  }
462 
463  Chain *new_chain = new Chain(id);
464  ++id;
465 #if 0 // FIXME
466  ViewEdgeIterator it_back(it);
467  --it_back;
468 #endif
469  do {
470  new_chain->push_viewedge_back(*it, it.getOrientation());
471  ts(**it);
472  if (it.increment() < 0) { // FIXME
473  delete new_chain;
474  goto error;
475  }
476  } while (!it.isEnd());
477  it.setBegin(edge);
478  it.setCurrentEdge(edge);
479  it.setOrientation(true);
480  if (it.decrement() < 0) { // FIXME
481  delete new_chain;
482  goto error;
483  }
484  while (!it.isEnd()) {
485  new_chain->push_viewedge_front(*it, it.getOrientation());
486  ts(**it);
487  if (it.decrement() < 0) { // FIXME
488  delete new_chain;
489  goto error;
490  }
491  }
492  new_chains_set.push_back(new_chain);
493  }
494 
495  if (!new_chains_set.empty()) {
496  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
497  _current_chains_set.push_back(*it);
498  }
499  new_chains_set.clear();
500  _current_set = &_current_chains_set;
501  }
502  return 0;
503 
504 error:
505  for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) {
506  delete (*it);
507  }
508  new_chains_set.clear();
509  return -1;
510 }
511 
513 {
514  if (_current_chains_set.empty()) {
515  cerr << "Warning: current set empty" << endl;
516  return 0;
517  }
518  CurvePoint *point;
519  Chain *new_curve;
520  I1DContainer splitted_chains;
521  Interface0DIterator first;
523  Interface0DIterator last;
525  I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end();
526  for (; cit != citend; ++cit) {
527  Id currentId = (*cit)->getId();
528  new_curve = new Chain(currentId);
529  first = (*cit)->pointsBegin(sampling);
530  end = (*cit)->pointsEnd(sampling);
531  last = end;
532  --last;
533  it = first;
534 
535  point = dynamic_cast<CurvePoint *>(&(*it));
536  new_curve->push_vertex_back(point);
537  ++it;
538  for (; it != end; ++it) {
539  point = dynamic_cast<CurvePoint *>(&(*it));
540  new_curve->push_vertex_back(point);
541  if (pred(it) < 0) {
542  delete new_curve;
543  goto error;
544  }
545  if (pred.result && (it != last)) {
546  splitted_chains.push_back(new_curve);
547  currentId.setSecond(currentId.getSecond() + 1);
548  new_curve = new Chain(currentId);
549  new_curve->push_vertex_back(point);
550  }
551  }
552  if (new_curve->nSegments() == 0) {
553  delete new_curve;
554  return 0;
555  }
556 
557  splitted_chains.push_back(new_curve);
558  }
559 
560  // Update the current set of chains:
561  cit = _current_chains_set.begin();
562  for (; cit != citend; ++cit) {
563  delete (*cit);
564  }
565  _current_chains_set.clear();
566 #if 0
567  _current_chains_set = splitted_chains;
568 #else
569  for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) {
570  if ((*cit)->getLength2D() < M_EPSILON) {
571  delete (*cit);
572  continue;
573  }
574  _current_chains_set.push_back(*cit);
575  }
576 #endif
577  splitted_chains.clear();
578 
579  if (!_current_chains_set.empty()) {
580  _current_set = &_current_chains_set;
581  }
582  return 0;
583 
584 error:
585  cit = splitted_chains.begin();
586  citend = splitted_chains.end();
587  for (; cit != citend; ++cit) {
588  delete (*cit);
589  }
590  splitted_chains.clear();
591  return -1;
592 }
593 
595  UnaryPredicate0D &stoppingPred,
596  float sampling)
597 {
598  if (_current_chains_set.empty()) {
599  cerr << "Warning: current set empty" << endl;
600  return 0;
601  }
602  CurvePoint *point;
603  Chain *new_curve;
604  I1DContainer splitted_chains;
605  Interface0DIterator first;
607  Interface0DIterator last;
608  Interface0DIterator itStart;
609  Interface0DIterator itStop;
610  I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end();
611  for (; cit != citend; ++cit) {
612  Id currentId = (*cit)->getId();
613  first = (*cit)->pointsBegin(sampling);
614  end = (*cit)->pointsEnd(sampling);
615  last = end;
616  --last;
617  itStart = first;
618  do {
619  itStop = itStart;
620  ++itStop;
621 
622  new_curve = new Chain(currentId);
623  currentId.setSecond(currentId.getSecond() + 1);
624 
625  point = dynamic_cast<CurvePoint *>(&(*itStart));
626  new_curve->push_vertex_back(point);
627  do {
628  point = dynamic_cast<CurvePoint *>(&(*itStop));
629  new_curve->push_vertex_back(point);
630  ++itStop;
631  if (itStop == end) {
632  break;
633  }
634  if (stoppingPred(itStop) < 0) {
635  delete new_curve;
636  goto error;
637  }
638  } while (!stoppingPred.result);
639  if (itStop != end) {
640  point = dynamic_cast<CurvePoint *>(&(*itStop));
641  new_curve->push_vertex_back(point);
642  }
643  if (new_curve->nSegments() == 0) {
644  delete new_curve;
645  }
646  else {
647  splitted_chains.push_back(new_curve);
648  }
649  // find next start
650  do {
651  ++itStart;
652  if (itStart == end) {
653  break;
654  }
655  if (startingPred(itStart) < 0) {
656  goto error;
657  }
658  } while (!startingPred.result);
659  } while (!ELEM(itStart, end, last));
660  }
661 
662  // Update the current set of chains:
663  cit = _current_chains_set.begin();
664  for (; cit != citend; ++cit) {
665  delete (*cit);
666  }
667  _current_chains_set.clear();
668 #if 0
669  _current_chains_set = splitted_chains;
670 #else
671  for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) {
672  if ((*cit)->getLength2D() < M_EPSILON) {
673  delete (*cit);
674  continue;
675  }
676  _current_chains_set.push_back(*cit);
677  }
678 #endif
679  splitted_chains.clear();
680 
681  if (!_current_chains_set.empty()) {
682  _current_set = &_current_chains_set;
683  }
684  return 0;
685 
686 error:
687  cit = splitted_chains.begin();
688  citend = splitted_chains.end();
689  for (; cit != citend; ++cit) {
690  delete (*cit);
691  }
692  splitted_chains.clear();
693  return -1;
694 }
695 
696 // Internal function
697 static int __recursiveSplit(Chain *_curve,
699  UnaryPredicate1D &pred,
700  float sampling,
701  Operators::I1DContainer &newChains,
702  Operators::I1DContainer &splitted_chains)
703 {
704  if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) {
705  newChains.push_back(_curve);
706  return 0;
707  }
708 
709  CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling);
710  CurveInternal::CurvePointIterator second = first;
711  ++second;
712  CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling);
716  real _min = FLT_MAX; // func(it0d);
717  ++it;
719  ++next;
720 
721  bool bsplit = false;
722  for (; ((it != end) && (next != end)); ++it, ++next) {
723  it0d = it.castToInterface0DIterator();
724  if (func(it0d) < 0) {
725  return -1;
726  }
727  if (func.result < _min) {
728  _min = func.result;
729  split = it;
730  bsplit = true;
731  }
732  }
733 
734  if (!bsplit) { // we didn't find any minimum
735  newChains.push_back(_curve);
736  return 0;
737  }
738 
739  // retrieves the current splitting id
740  Id *newId = _curve->getSplittingId();
741  if (newId == nullptr) {
742  newId = new Id(_curve->getId());
743  _curve->setSplittingId(newId);
744  }
745 
746  Chain *new_curve_a = new Chain(*newId);
747  newId->setSecond(newId->getSecond() + 1);
748  new_curve_a->setSplittingId(newId);
749  Chain *new_curve_b = new Chain(*newId);
750  newId->setSecond(newId->getSecond() + 1);
751  new_curve_b->setSplittingId(newId);
752 
754  vitend = _curve->curveVerticesEnd();
756  ++vnext;
757 
758  for (; (vit != vitend) && (vnext != vitend) &&
759  (vnext._CurvilinearLength < split._CurvilinearLength);
760  ++vit, ++vnext) {
761  new_curve_a->push_vertex_back(&(*vit));
762  }
763  if ((vit == vitend) || (vnext == vitend)) {
764  if (G.debug & G_DEBUG_FREESTYLE) {
765  cout << "The split takes place in bad location" << endl;
766  }
767  newChains.push_back(_curve);
768  delete new_curve_a;
769  delete new_curve_b;
770  return 0;
771  }
772 
773  // build the two resulting chains
774  new_curve_a->push_vertex_back(&(*vit));
775  new_curve_a->push_vertex_back(&(*split));
776  new_curve_b->push_vertex_back(&(*split));
777 
778  for (vit = vnext; vit != vitend; ++vit) {
779  new_curve_b->push_vertex_back(&(*vit));
780  }
781 
782  // let's check whether one or two of the two new curves satisfy the stopping condition or not.
783  // (if one of them satisfies it, we don't split)
784  if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) {
785  delete new_curve_a;
786  delete new_curve_b;
787  return -1;
788  }
789  if (pred.result) {
790  // we don't actually create these two chains
791  newChains.push_back(_curve);
792  delete new_curve_a;
793  delete new_curve_b;
794  return 0;
795  }
796  // here we know we'll split _curve:
797  splitted_chains.push_back(_curve);
798 
799  __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains);
800  __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains);
801  return 0;
802 }
803 
805  UnaryPredicate1D &pred,
806  float sampling)
807 {
808  if (_current_chains_set.empty()) {
809  cerr << "Warning: current set empty" << endl;
810  return 0;
811  }
812 
813  Chain *currentChain = nullptr;
814  I1DContainer splitted_chains;
815  I1DContainer newChains;
816  I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end();
817  for (; cit != citend; ++cit) {
818  currentChain = dynamic_cast<Chain *>(*cit);
819  if (!currentChain) {
820  continue;
821  }
822  // let's check the first one:
823  if (pred(*currentChain) < 0) {
824  return -1;
825  }
826  if (!pred.result) {
827  __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains);
828  }
829  else {
830  newChains.push_back(currentChain);
831  }
832  }
833  // Update the current set of chains:
834  if (!splitted_chains.empty()) {
835  for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) {
836  delete (*cit);
837  }
838  splitted_chains.clear();
839  }
840 
841  _current_chains_set.clear();
842 #if 0
843  _current_chains_set = newChains;
844 #else
845  for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) {
846  if ((*cit)->getLength2D() < M_EPSILON) {
847  delete (*cit);
848  continue;
849  }
850  _current_chains_set.push_back(*cit);
851  }
852 #endif
853  newChains.clear();
854 
855  if (!_current_chains_set.empty()) {
856  _current_set = &_current_chains_set;
857  }
858  return 0;
859 }
860 
861 // recursive split with pred 0D
862 static int __recursiveSplit(Chain *_curve,
864  UnaryPredicate0D &pred0d,
865  UnaryPredicate1D &pred,
866  float sampling,
867  Operators::I1DContainer &newChains,
868  Operators::I1DContainer &splitted_chains)
869 {
870  if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) {
871  newChains.push_back(_curve);
872  return 0;
873  }
874 
875  CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling);
876  CurveInternal::CurvePointIterator second = first;
877  ++second;
878  CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling);
882 #if 0
883  real _min = func(it0d);
884  ++it;
885 #endif
886  real _min = FLT_MAX;
887  ++it;
888  real mean = 0.0f;
889  // soc unused - real variance = 0.0f;
890  unsigned count = 0;
892  ++next;
893 
894  bool bsplit = false;
895  for (; ((it != end) && (next != end)); ++it, ++next) {
896  ++count;
897  it0d = it.castToInterface0DIterator();
898  if (pred0d(it0d) < 0) {
899  return -1;
900  }
901  if (!pred0d.result) {
902  continue;
903  }
904  if (func(it0d) < 0) {
905  return -1;
906  }
907  mean += func.result;
908  if (func.result < _min) {
909  _min = func.result;
910  split = it;
911  bsplit = true;
912  }
913  }
914  mean /= (float)count;
915 
916  // if ((!bsplit) || (mean - _min > mean)) { // we didn't find any minimum
917  if (!bsplit) { // we didn't find any minimum
918  newChains.push_back(_curve);
919  return 0;
920  }
921 
922  // retrieves the current splitting id
923  Id *newId = _curve->getSplittingId();
924  if (newId == nullptr) {
925  newId = new Id(_curve->getId());
926  _curve->setSplittingId(newId);
927  }
928 
929  Chain *new_curve_a = new Chain(*newId);
930  newId->setSecond(newId->getSecond() + 1);
931  new_curve_a->setSplittingId(newId);
932  Chain *new_curve_b = new Chain(*newId);
933  newId->setSecond(newId->getSecond() + 1);
934  new_curve_b->setSplittingId(newId);
935 
937  vitend = _curve->curveVerticesEnd();
939  ++vnext;
940 
941  for (; (vit != vitend) && (vnext != vitend) &&
942  (vnext._CurvilinearLength < split._CurvilinearLength);
943  ++vit, ++vnext) {
944  new_curve_a->push_vertex_back(&(*vit));
945  }
946  if ((vit == vitend) || (vnext == vitend)) {
947  if (G.debug & G_DEBUG_FREESTYLE) {
948  cout << "The split takes place in bad location" << endl;
949  }
950  newChains.push_back(_curve);
951  delete new_curve_a;
952  delete new_curve_b;
953  return 0;
954  }
955 
956  // build the two resulting chains
957  new_curve_a->push_vertex_back(&(*vit));
958  new_curve_a->push_vertex_back(&(*split));
959  new_curve_b->push_vertex_back(&(*split));
960 
961  for (vit = vnext; vit != vitend; ++vit) {
962  new_curve_b->push_vertex_back(&(*vit));
963  }
964 
965  // let's check whether one or two of the two new curves satisfy the stopping condition or not.
966  // (if one of them satisfies it, we don't split)
967  if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) {
968  delete new_curve_a;
969  delete new_curve_b;
970  return -1;
971  }
972  if (pred.result) {
973  // we don't actually create these two chains
974  newChains.push_back(_curve);
975  delete new_curve_a;
976  delete new_curve_b;
977  return 0;
978  }
979  // here we know we'll split _curve:
980  splitted_chains.push_back(_curve);
981 
982  __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains);
983  __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains);
984  return 0;
985 }
986 
988  UnaryPredicate0D &pred0d,
989  UnaryPredicate1D &pred,
990  float sampling)
991 {
992  if (_current_chains_set.empty()) {
993  cerr << "Warning: current set empty" << endl;
994  return 0;
995  }
996 
997  Chain *currentChain = nullptr;
998  I1DContainer splitted_chains;
999  I1DContainer newChains;
1000  I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end();
1001  for (; cit != citend; ++cit) {
1002  currentChain = dynamic_cast<Chain *>(*cit);
1003  if (!currentChain) {
1004  continue;
1005  }
1006  // let's check the first one:
1007  if (pred(*currentChain) < 0) {
1008  return -1;
1009  }
1010  if (!pred.result) {
1011  __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains);
1012  }
1013  else {
1014  newChains.push_back(currentChain);
1015  }
1016  }
1017  // Update the current set of chains:
1018  if (!splitted_chains.empty()) {
1019  for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) {
1020  delete (*cit);
1021  }
1022  splitted_chains.clear();
1023  }
1024 
1025  _current_chains_set.clear();
1026 #if 0
1027  _current_chains_set = newChains;
1028 #else
1029  for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) {
1030  if ((*cit)->getLength2D() < M_EPSILON) {
1031  delete (*cit);
1032  continue;
1033  }
1034  _current_chains_set.push_back(*cit);
1035  }
1036 #endif
1037  newChains.clear();
1038 
1039  if (!_current_chains_set.empty()) {
1040  _current_set = &_current_chains_set;
1041  }
1042  return 0;
1043 }
1044 
1045 // Internal class
1047  public:
1049  {
1050  _pred = &pred;
1051  }
1052 
1054  {
1055  if (i1 == i2) {
1056  return false;
1057  }
1058  if ((*_pred)(*i1, *i2) < 0) {
1059  throw std::runtime_error("comparison failed");
1060  }
1061  return _pred->result;
1062  }
1063 
1064  private:
1065  BinaryPredicate1D *_pred;
1066 };
1067 
1069 {
1070  if (!_current_set) {
1071  return 0;
1072  }
1073  PredicateWrapper wrapper(pred);
1074  try {
1075  std::sort(_current_set->begin(), _current_set->end(), wrapper);
1076  }
1077  catch (std::runtime_error &e) {
1078  cerr << "Warning: Operator.sort(): " << e.what() << endl;
1079  return -1;
1080  }
1081  return 0;
1082 }
1083 
1085 {
1086  Stroke *stroke = new Stroke;
1087  stroke->setId(inter.getId());
1088 
1089  float currentCurvilignAbscissa = 0.0f;
1090 
1091  Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
1092  Interface0DIterator itfirst = it;
1093 
1094  Vec2r current(it->getPoint2D());
1095  Vec2r previous = current;
1096  SVertex *sv;
1097  CurvePoint *cp;
1098  StrokeVertex *stroke_vertex = nullptr;
1099  bool hasSingularity = false;
1100 
1101  do {
1102  cp = dynamic_cast<CurvePoint *>(&(*it));
1103  if (!cp) {
1104  sv = dynamic_cast<SVertex *>(&(*it));
1105  if (!sv) {
1106  cerr << "Warning: unexpected Vertex type" << endl;
1107  continue;
1108  }
1109  stroke_vertex = new StrokeVertex(sv);
1110  }
1111  else {
1112  stroke_vertex = new StrokeVertex(cp);
1113  }
1114  current = stroke_vertex->getPoint2D();
1115  Vec2r vec_tmp(current - previous);
1116  real dist = vec_tmp.norm();
1117  if (dist < 1.0e-6) {
1118  hasSingularity = true;
1119  }
1120  currentCurvilignAbscissa += dist;
1121  stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa);
1122  stroke->push_back(stroke_vertex);
1123  previous = current;
1124  ++it;
1125  } while (!ELEM(it, itend, itfirst));
1126 
1127  if (it == itfirst) {
1128  // Add last vertex:
1129  cp = dynamic_cast<CurvePoint *>(&(*it));
1130  if (!cp) {
1131  sv = dynamic_cast<SVertex *>(&(*it));
1132  if (!sv) {
1133  cerr << "Warning: unexpected Vertex type" << endl;
1134  }
1135  else {
1136  stroke_vertex = new StrokeVertex(sv);
1137  }
1138  }
1139  else {
1140  stroke_vertex = new StrokeVertex(cp);
1141  }
1142  current = stroke_vertex->getPoint2D();
1143  Vec2r vec_tmp(current - previous);
1144  real dist = vec_tmp.norm();
1145  if (dist < 1.0e-6) {
1146  hasSingularity = true;
1147  }
1148  currentCurvilignAbscissa += dist;
1149  stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa);
1150  stroke->push_back(stroke_vertex);
1151  }
1152  // Discard the stroke if the number of stroke vertices is less than two
1153  if (stroke->strokeVerticesSize() < 2) {
1154  delete stroke;
1155  return nullptr;
1156  }
1157  stroke->setLength(currentCurvilignAbscissa);
1158  if (hasSingularity) {
1159  // Try to address singular points such that the distance between two subsequent vertices
1160  // are smaller than epsilon.
1163  ++vnext;
1164  Vec2r next((*v).getPoint());
1165  while (!vnext.isEnd()) {
1166  current = next;
1167  next = (*vnext).getPoint();
1168  if ((next - current).norm() < 1.0e-6) {
1170  if (!vprevious.isBegin()) {
1171  --vprevious;
1172  }
1173 
1174  // collect a set of overlapping vertices
1175  std::vector<StrokeVertex *> overlapping_vertices;
1176  overlapping_vertices.push_back(&(*v));
1177  do {
1178  overlapping_vertices.push_back(&(*vnext));
1179  current = next;
1180  ++v;
1181  ++vnext;
1182  if (vnext.isEnd()) {
1183  break;
1184  }
1185  next = (*vnext).getPoint();
1186  } while ((next - current).norm() < 1.0e-6);
1187 
1188  Vec2r target;
1189  bool reverse;
1190  if (!vnext.isEnd()) {
1191  target = (*vnext).getPoint();
1192  reverse = false;
1193  }
1194  else if (!vprevious.isBegin()) {
1195  target = (*vprevious).getPoint();
1196  reverse = true;
1197  }
1198  else {
1199  // Discard the stroke because all stroke vertices are overlapping
1200  delete stroke;
1201  return nullptr;
1202  }
1203  current = overlapping_vertices.front()->getPoint();
1204  Vec2r dir(target - current);
1205  real dist = dir.norm();
1206  real len = 1.0e-3; // default offset length
1207  int nvert = overlapping_vertices.size();
1208  if (dist < len * nvert) {
1209  len = dist / nvert;
1210  }
1211  dir.normalize();
1212  Vec2r offset(dir * len);
1213  // add the offset to the overlapping vertices
1214  StrokeVertex *sv;
1215  std::vector<StrokeVertex *>::iterator it = overlapping_vertices.begin();
1216  if (!reverse) {
1217  for (int n = 0; n < nvert; n++) {
1218  sv = (*it);
1219  sv->setPoint(sv->getPoint() + offset * (n + 1));
1220  ++it;
1221  }
1222  }
1223  else {
1224  for (int n = 0; n < nvert; n++) {
1225  sv = (*it);
1226  sv->setPoint(sv->getPoint() + offset * (nvert - n));
1227  ++it;
1228  }
1229  }
1230 
1231  if (vnext.isEnd()) {
1232  break;
1233  }
1234  }
1235  ++v;
1236  ++vnext;
1237  }
1238  }
1239  {
1240  // Check if the stroke no longer contains singular points
1241  Interface0DIterator v = stroke->verticesBegin();
1242  Interface0DIterator vnext = v;
1243  ++vnext;
1244  Vec2r next((*v).getPoint2D());
1245  bool warning = false;
1246  while (!vnext.isEnd()) {
1247  current = next;
1248  next = (*vnext).getPoint2D();
1249  if ((next - current).norm() < 1.0e-6) {
1250  warning = true;
1251  break;
1252  }
1253  ++v;
1254  ++vnext;
1255  }
1256  if (warning && G.debug & G_DEBUG_FREESTYLE) {
1257  printf("Warning: stroke contains singular points.\n");
1258  }
1259  }
1260  return stroke;
1261 }
1262 
1263 inline int applyShading(Stroke &stroke, vector<StrokeShader *> &shaders)
1264 {
1265  for (vector<StrokeShader *>::iterator it = shaders.begin(); it != shaders.end(); ++it) {
1266  if ((*it)->shade(stroke) < 0) {
1267  return -1;
1268  }
1269  }
1270  return 0;
1271 }
1272 
1273 int Operators::create(UnaryPredicate1D &pred, vector<StrokeShader *> shaders)
1274 {
1275  // Canvas* canvas = Canvas::getInstance();
1276  if (!_current_set) {
1277  cerr << "Warning: current set empty" << endl;
1278  return 0;
1279  }
1280  StrokesContainer new_strokes_set;
1281  for (Operators::I1DContainer::iterator it = _current_set->begin(); it != _current_set->end();
1282  ++it) {
1283  if (pred(**it) < 0) {
1284  goto error;
1285  }
1286  if (!pred.result) {
1287  continue;
1288  }
1289 
1290  Stroke *stroke = createStroke(**it);
1291  if (stroke) {
1292  if (applyShading(*stroke, shaders) < 0) {
1293  delete stroke;
1294  goto error;
1295  }
1296  // canvas->RenderStroke(stroke);
1297  new_strokes_set.push_back(stroke);
1298  }
1299  }
1300 
1301  for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end();
1302  ++it) {
1303  _current_strokes_set.push_back(*it);
1304  }
1305  new_strokes_set.clear();
1306  return 0;
1307 
1308 error:
1309  for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end();
1310  ++it) {
1311  delete (*it);
1312  }
1313  new_strokes_set.clear();
1314  return -1;
1315 }
1316 
1317 void Operators::reset(bool removeStrokes)
1318 {
1319  ViewMap *vm = ViewMap::getInstance();
1320  if (!vm) {
1321  cerr << "Error: no ViewMap computed yet" << endl;
1322  return;
1323  }
1324  _current_view_edges_set.clear();
1325  for (I1DContainer::iterator it = _current_chains_set.begin(); it != _current_chains_set.end();
1326  ++it) {
1327  delete *it;
1328  }
1329  _current_chains_set.clear();
1330 
1331  ViewMap::viewedges_container &vedges = vm->ViewEdges();
1332  ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end();
1333  for (; ve != veend; ++ve) {
1334  if ((*ve)->getLength2D() < M_EPSILON) {
1335  continue;
1336  }
1337  _current_view_edges_set.push_back(*ve);
1338  }
1339  _current_set = &_current_view_edges_set;
1340  if (removeStrokes) {
1341  _current_strokes_set.clear();
1342  }
1343 }
1344 
1345 } /* namespace Freestyle */
typedef float(TangentPoint)[2]
@ G_DEBUG_FREESTYLE
Definition: BKE_global.h:140
#define ELEM(...)
Class to define a canvas designed to draw style modules.
Iterators used to iterate over the elements of the Curve.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
Class gathering stroke creation algorithms.
Iterators used to iterate over the elements of the Stroke.
Classes to define a stroke.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
Id * getSplittingId()
Definition: Chain.h:100
void push_viewedge_front(ViewEdge *iViewEdge, bool orientation)
Definition: Chain.cpp:92
void push_viewedge_back(ViewEdge *iViewEdge, bool orientation)
Definition: Chain.cpp:29
void setSplittingId(Id *sid)
Definition: Chain.h:95
Interface0DIterator castToInterface0DIterator() const
virtual Vec2r getPoint2D() const
Definition: Curve.h:114
unsigned int nSegments() const
Definition: Curve.h:505
void push_vertex_back(Vertex *iVertex)
Definition: Curve.h:439
real getLength2D() const
Definition: Curve.h:493
virtual Id getId() const
Definition: Curve.h:499
CurveInternal::CurvePointIterator curvePointsBegin(float t=0.0f)
Definition: Curve.cpp:644
CurveInternal::CurvePointIterator curveVerticesBegin()
Definition: Curve.cpp:676
CurveInternal::CurvePointIterator curveVerticesEnd()
Definition: Curve.cpp:681
CurveInternal::CurvePointIterator curvePointsEnd(float t=0.0f)
Definition: Curve.cpp:660
id_type getSecond() const
Definition: Id.h:82
void setSecond(id_type second)
Definition: Id.h:94
virtual bool isEnd() const
Definition: Interface0D.h:296
virtual Geometry::Vec2r getPoint2D() const
Definition: Interface0D.cpp:73
virtual Interface0DIterator verticesEnd()
Definition: Interface1D.cpp:35
virtual Interface0DIterator verticesBegin()
Definition: Interface1D.cpp:29
virtual Id getId() const
Definition: Interface1D.cpp:59
static int sort(BinaryPredicate1D &pred)
Definition: Operators.cpp:1068
static int select(UnaryPredicate1D &pred)
Definition: Operators.cpp:40
static int chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &pred, UnaryFunction1D_void &modifier)
Definition: Operators.cpp:82
static void reset(bool removeStrokes=true)
Definition: Operators.cpp:1317
vector< Interface1D * > I1DContainer
Definition: Operators.h:52
static int sequentialSplit(UnaryPredicate0D &startingPred, UnaryPredicate0D &stoppingPred, float sampling=0.0f)
Definition: Operators.cpp:594
static int recursiveSplit(UnaryFunction0D< double > &func, UnaryPredicate1D &pred, float sampling=0)
Definition: Operators.cpp:804
static int bidirectionalChain(ChainingIterator &it, UnaryPredicate1D &pred)
Definition: Operators.cpp:329
static int create(UnaryPredicate1D &pred, vector< StrokeShader * > shaders)
Definition: Operators.cpp:1273
vector< Stroke * > StrokesContainer
Definition: Operators.h:53
bool operator()(Interface1D *i1, Interface1D *i2)
Definition: Operators.cpp:1053
PredicateWrapper(BinaryPredicate1D &pred)
Definition: Operators.cpp:1048
Vec2r getPoint() const
Definition: Stroke.h:376
void setCurvilinearAbscissa(float iAbscissa)
Definition: Stroke.h:457
void setPoint(real x, real y)
Definition: Stroke.h:431
void push_back(StrokeVertex *iVertex)
Definition: Stroke.h:796
void setId(const Id &id)
Definition: Stroke.h:746
virtual Interface0DIterator verticesBegin()
Definition: Stroke.cpp:779
void setLength(float iLength)
Definition: Stroke.cpp:493
StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t=0.0f)
Definition: Stroke.cpp:764
unsigned int strokeVerticesSize() const
Definition: Stroke.h:851
static TimeStamp * instance()
Definition: TimeStamp.h:32
value_type norm() const
Definition: VecMat.h:109
Vec< T, N > & normalize()
Definition: VecMat.h:119
vector< ViewEdge * > viewedges_container
Definition: ViewMap.h:62
static ViewMap * getInstance()
Definition: ViewMap.h:105
viewedges_container & ViewEdges()
Definition: ViewMap.h:117
IMAGE_Shaders shaders
Definition: image_shader.c:44
int count
static ulong * next
static void error(const char *str)
Definition: meshlaplacian.c:65
inherits from class Rep
Definition: AppCanvas.cpp:32
static const real M_EPSILON
Definition: Precision.h:29
static int __recursiveSplit(Chain *_curve, UnaryFunction0D< double > &func, UnaryPredicate1D &pred, float sampling, Operators::I1DContainer &newChains, Operators::I1DContainer &splitted_chains)
Definition: Operators.cpp:697
static Stroke * createStroke(Interface1D &inter)
Definition: Operators.cpp:1084
int applyShading(Stroke &stroke, vector< StrokeShader * > &shaders)
Definition: Operators.cpp:1263
double real
Definition: Precision.h:26
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:115
#define G(x, y, z)
uint len