Blender  V2.93
BasicStrokeShaders.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 <fstream>
23 
24 #include "AdvancedFunctions0D.h"
25 #include "AdvancedFunctions1D.h"
26 #include "BasicStrokeShaders.h"
27 #include "StrokeIO.h"
28 #include "StrokeIterators.h"
29 #include "StrokeRenderer.h"
30 
31 #include "../system/PseudoNoise.h"
32 #include "../system/RandGen.h"
33 #include "../system/StringUtils.h"
34 
35 #include "../view_map/Functions0D.h"
36 #include "../view_map/Functions1D.h"
37 
38 #include "BKE_global.h"
39 
40 #include "IMB_imbuf.h"
41 #include "IMB_imbuf_types.h"
42 
44 
45 //
46 // Thickness modifiers
47 //
49 
51 {
53  int i = 0;
54  int size = stroke.strokeVerticesSize();
55  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
56  // XXX What's the use of i here? And is not the thickness always overridden by the last line of
57  // the loop?
58  if ((1 == i) || (size - 2 == i)) {
59  v->attribute().setThickness(_thickness / 4.0, _thickness / 4.0);
60  }
61  if ((0 == i) || (size - 1 == i)) {
62  v->attribute().setThickness(0, 0);
63  }
64 
65  v->attribute().setThickness(_thickness / 2.0, _thickness / 2.0);
66  }
67  return 0;
68 }
69 
71 {
73  int i = 0;
74  int size = stroke.strokeVerticesSize();
75  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
76  // XXX What's the use of i here? And is not the thickness always overridden by the last line of
77  // the loop?
78  if ((1 == i) || (size - 2 == i)) {
79  v->attribute().setThickness(_thickness / 2.0, 0);
80  }
81  if ((0 == i) || (size - 1 == i)) {
82  v->attribute().setThickness(0, 0);
83  }
84 
85  v->attribute().setThickness(_thickness, 0);
86  }
87  return 0;
88 }
89 
91 {
92  int n = stroke.strokeVerticesSize() - 1, i;
94  for (i = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend;
95  ++v, ++i) {
96  float t;
97  if (i < (float)n / 2.0f) {
98  t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * _ThicknessMax;
99  }
100  else {
101  t = (1.0 - (float)i / (float)n) * _ThicknessMax + (float)i / (float)n * _ThicknessMin;
102  }
103  v->attribute().setThickness(t / 2.0, t / 2.0);
104  }
105  return 0;
106 }
107 
109 {
110  float slength = stroke.getLength2D();
111  float maxT = min(_ratio * slength, _ThicknessMax);
112  int n = stroke.strokeVerticesSize() - 1, i;
114  for (i = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend;
115  ++v, ++i) {
116  // XXX Why not using an if/else here? Else, if last condition is true, everything else is
117  // computed for nothing!
118  float t;
119  if (i < (float)n / 2.0f) {
120  t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * maxT;
121  }
122  else {
123  t = (1.0 - (float)i / (float)n) * maxT + (float)i / (float)n * _ThicknessMin;
124  }
125  v->attribute().setThickness(t / 2.0, t / 2.0);
126  if (i == n - 1) {
127  v->attribute().setThickness(_ThicknessMin / 2.0, _ThicknessMin / 2.0);
128  }
129  }
130  return 0;
131 }
132 
134 {
135  float step = (_maxThickness - _minThickness) / 3.0f;
136  float l = stroke.getLength2D();
137  float thickness = 0.0f;
138  if (l > 300.0f) {
139  thickness = _minThickness + 3.0f * step;
140  }
141  else if ((l < 300.0f) && (l > 100.0f)) {
142  thickness = _minThickness + 2.0f * step;
143  }
144  else if ((l < 100.0f) && (l > 50.0f)) {
145  thickness = _minThickness + 1.0f * step;
146  }
147  else { // else if (l < 50.0f), tsst...
148  thickness = _minThickness;
149  }
150 
152  int i = 0;
153  int size = stroke.strokeVerticesSize();
154  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
155  // XXX What's the use of i here? And is not the thickness always overridden by the last line of
156  // the loop?
157  if ((1 == i) || (size - 2 == i)) {
158  v->attribute().setThickness(thickness / 4.0, thickness / 4.0);
159  }
160  if ((0 == i) || (size - 1 == i)) {
161  v->attribute().setThickness(0, 0);
162  }
163 
164  v->attribute().setThickness(thickness / 2.0, thickness / 2.0);
165  }
166  return 0;
167 }
168 
169 static const unsigned NB_VALUE_NOISE = 512;
170 
172 {
173  _amplitude = 1.0f;
174  _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE;
175 }
176 
177 ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod)
178 {
179  _amplitude = iAmplitude;
180  _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE;
181 }
182 
184 {
186  real initU1 = v->strokeLength() * real(NB_VALUE_NOISE) +
188  real initU2 = v->strokeLength() * real(NB_VALUE_NOISE) +
190 
191  real bruit, bruit2;
192  PseudoNoise mynoise, mynoise2;
193  for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
194  bruit = mynoise.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU1,
195  2); // 2 : nbOctaves
196  bruit2 = mynoise2.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU2,
197  2); // 2 : nbOctaves
198  const float *originalThickness = v->attribute().getThickness();
199  float r = bruit * _amplitude + originalThickness[0];
200  float l = bruit2 * _amplitude + originalThickness[1];
201  v->attribute().setThickness(r, l);
202  }
203 
204  return 0;
205 }
206 
207 //
208 // Color shaders
209 //
211 
213 {
215  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
216  v->attribute().setColor(_color[0], _color[1], _color[2]);
217  v->attribute().setAlpha(_color[3]);
218  }
219  return 0;
220 }
221 
223 {
225  int n = stroke.strokeVerticesSize() - 1, yo;
226  float newcolor[4];
227  for (yo = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend;
228  ++v, ++yo) {
229  for (int i = 0; i < 4; ++i) {
230  newcolor[i] = (1.0 - (float)yo / (float)n) * _colorMin[i] +
231  (float)yo / (float)n * _colorMax[i];
232  }
233  v->attribute().setColor(newcolor[0], newcolor[1], newcolor[2]);
234  v->attribute().setAlpha(newcolor[3]);
235  }
236  return 0;
237 }
238 
240 {
241  Interface0DIterator v, vend;
243  StrokeVertex *sv;
244  for (v = stroke.verticesBegin(), vend = stroke.verticesEnd(); v != vend; ++v) {
245  if (fun(v) < 0) {
246  return -1;
247  }
248  const float *diffuse = fun.result.diffuse();
249  sv = dynamic_cast<StrokeVertex *>(&(*v));
250  sv->attribute().setColor(
251  diffuse[0] * _coefficient, diffuse[1] * _coefficient, diffuse[2] * _coefficient);
252  sv->attribute().setAlpha(diffuse[3]);
253  }
254  return 0;
255 }
256 
258 {
259  _amplitude = 1.0f;
260  _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE;
261 }
262 
263 ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod)
264 {
265  _amplitude = iAmplitude;
266  _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE;
267 }
268 
269 int ColorNoiseShader::shade(Stroke &stroke) const
270 {
272  real initU = v->strokeLength() * real(NB_VALUE_NOISE) +
274 
275  real bruit;
276  PseudoNoise mynoise;
277  for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
278  bruit = mynoise.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU,
279  2); // 2 : nbOctaves
280  const float *originalColor = v->attribute().getColor();
281  float r = bruit * _amplitude + originalColor[0];
282  float g = bruit * _amplitude + originalColor[1];
283  float b = bruit * _amplitude + originalColor[2];
284  v->attribute().setColor(r, g, b);
285  }
286  return 0;
287 }
288 
289 //
290 // Texture Shaders
291 //
293 
295 {
296  if (_mtex) {
297  return stroke.setMTex(_mtex);
298  }
299  if (_nodeTree) {
300  stroke.setNodeTree(_nodeTree);
301  return 0;
302  }
303  return -1;
304 }
305 
307 {
308  stroke.setTextureStep(_step);
309  return 0;
310 }
311 
312 //
313 // Geometry Shaders
314 //
316 
318 {
319  float l = stroke.getLength2D();
320  if (l <= 1.0e-6) {
321  return 0;
322  }
323 
326  ++v1;
328  --vn;
330  --vn_1;
331 
332  Vec2d first((v0)->x(), (v0)->y());
333  Vec2d last((vn)->x(), (vn)->y());
334 
335  Vec2d d1(first - Vec2d((v1)->x(), (v1)->y()));
336  d1.normalize();
337  Vec2d dn(last - Vec2d((vn_1)->x(), (vn_1)->y()));
338  dn.normalize();
339 
340  Vec2d newFirst(first + _amount * d1);
341  (v0)->setPoint(newFirst[0], newFirst[1]);
342  Vec2d newLast(last + _amount * dn);
343  (vn)->setPoint(newLast[0], newLast[1]);
344 
345  stroke.UpdateLength();
346  return 0;
347 }
348 
349 int SamplingShader::shade(Stroke &stroke) const
350 {
351  stroke.Resample(_sampling);
352  stroke.UpdateLength();
353  return 0;
354 }
355 
357 {
358  // float l = stroke.getLength2D();
361  StrokeVertex *sv;
362  for (it = stroke.verticesBegin(); !it.isEnd(); ++it) {
363  if (fun(it) < 0) {
364  return -1;
365  }
366  Vec2f n(fun.result);
367  sv = dynamic_cast<StrokeVertex *>(&(*it));
368  Vec2d newPoint(sv->x() + _amount * n.x(), sv->y() + _amount * n.y());
369  sv->setPoint(newPoint[0], newPoint[1]);
370  }
371  stroke.UpdateLength();
372  return 0;
373 }
374 
377 {
378  if (stroke.strokeVerticesSize() < 4) {
379  return 0;
380  }
381 
382  // Build the Bezier curve from this set of data points:
383  vector<Vec2d> data;
385  data.emplace_back(v->x(), v->y()); // first one
387  ++v;
388  for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
389  if (!((fabs(v->x() - (previous)->x()) < M_EPSILON) &&
390  ((fabs(v->y() - (previous)->y()) < M_EPSILON)))) {
391  data.emplace_back(v->x(), v->y());
392  }
393  previous = v;
394  }
395 
396  // here we build the bezier curve
397  BezierCurve bcurve(data, _error);
398 
399  // bad performances are here !!! // FIXME
400  vector<Vec2d> CurveVertices;
401  vector<BezierCurveSegment *> &bsegments = bcurve.segments();
402  vector<BezierCurveSegment *>::iterator s = bsegments.begin(), send;
403  vector<Vec2d> &segmentsVertices = (*s)->vertices();
404  vector<Vec2d>::iterator p, pend;
405  // first point
406  CurveVertices.push_back(segmentsVertices[0]);
407  for (send = bsegments.end(); s != send; ++s) {
408  segmentsVertices = (*s)->vertices();
409  p = segmentsVertices.begin();
410  ++p;
411  for (pend = segmentsVertices.end(); p != pend; ++p) {
412  CurveVertices.push_back((*p));
413  }
414  }
415 
416  // Re-sample the Stroke depending on the number of vertices of the bezier curve:
417  int originalSize = CurveVertices.size();
418 #if 0
419  float sampling = stroke.ComputeSampling(originalSize);
420  stroke.Resample(sampling);
421 #endif
422  stroke.Resample(originalSize);
423  int newsize = stroke.strokeVerticesSize();
424  int nExtraVertex = 0;
425  if (newsize < originalSize) {
426  cerr << "Warning: insufficient resampling" << endl;
427  }
428  else {
429  nExtraVertex = newsize - originalSize;
430  if (nExtraVertex != 0) {
431  if (G.debug & G_DEBUG_FREESTYLE) {
432  cout << "Bezier Shader : Stroke " << stroke.getId() << " have not been resampled" << endl;
433  }
434  }
435  }
436 
437  // assigns the new coordinates:
438  p = CurveVertices.begin();
439  vector<Vec2d>::iterator last = p;
440  int n;
442  for (n = 0,
443  it = stroke.strokeVerticesBegin(),
444  itend = stroke.strokeVerticesEnd(),
445  pend = CurveVertices.end();
446  (it != itend) && (p != pend);
447  ++it, ++p, ++n) {
448  it->setX(p->x());
449  it->setY(p->y());
450  last = p;
451  }
452  stroke.UpdateLength();
453 
454  // Deal with extra vertices:
455  if (nExtraVertex == 0) {
456  return 0;
457  }
458 
459  // nExtraVertex should stay unassigned
460  vector<StrokeAttribute> attributes;
461  vector<StrokeVertex *> verticesToRemove;
462  for (int i = 0; i < nExtraVertex; ++i, ++it, ++n) {
463  verticesToRemove.push_back(&(*it));
464  if (it.isEnd()) {
465  // XXX Shocking! :P Shouldn't we break in this case???
466  if (G.debug & G_DEBUG_FREESTYLE) {
467  cout << "messed up!" << endl;
468  }
469  }
470  }
471  for (it = stroke.strokeVerticesBegin(); it != itend; ++it) {
472  attributes.push_back(it->attribute());
473  }
474 
475  for (vector<StrokeVertex *>::iterator vr = verticesToRemove.begin(),
476  vrend = verticesToRemove.end();
477  vr != vrend;
478  ++vr) {
479  stroke.RemoveVertex(*vr);
480  }
481 
482  vector<StrokeAttribute>::iterator a = attributes.begin(), aend = attributes.end();
483  int index = 0;
484  int index1 = (int)floor((float)originalSize / 2.0);
485  int index2 = index1 + nExtraVertex;
486  for (it = stroke.strokeVerticesBegin(), itend = stroke.strokeVerticesEnd();
487  (it != itend) && (a != aend);
488  ++it) {
489  (it)->setAttribute(*a);
490  if ((index <= index1) || (index > index2)) {
491  ++a;
492  }
493  ++index;
494  }
495  return 0;
496 }
497 
498 class CurvePiece {
499  public:
504  int size;
505  float _error;
506 
509  int iSize)
510  {
511  _error = 0.0f;
512  _begin = b;
513  _last = l;
514  A = Vec2d((_begin)->x(), (_begin)->y());
515  B = Vec2d((_last)->x(), (_last)->y());
516  size = iSize;
517  }
518 
519  float error()
520  {
521  float maxE = 0.0f;
522  for (StrokeInternal::StrokeVertexIterator it = _begin; it != _last; ++it) {
523  Vec2d P(it->x(), it->y());
524  float d = GeomUtils::distPointSegment(P, A, B);
525  if (d > maxE) {
526  maxE = d;
527  }
528  }
529  _error = maxE;
530  return maxE;
531  }
532 
534  // The first piece is this same object (modified)
535  // The second piece is returned by the method
537  {
539  int ns = size - 1; // number of segments (ns > 1)
540  int ns1 = ns / 2;
541  int ns2 = ns - ns1;
542  for (int i = 0; i < ns1; ++it, ++i) {
543  /* pass */
544  }
545 
546  CurvePiece *second = new CurvePiece(it, _last, ns2 + 1);
547  size = ns1 + 1;
548  _last = it;
549  B = Vec2d((_last)->x(), (_last)->y());
550  return second;
551  }
552 };
553 
555 {
556  vector<CurvePiece *> _pieces;
557  vector<CurvePiece *> _results;
558  vector<CurvePiece *>::iterator cp, cpend;
559 
560  // Compute first approx:
563  --b;
564  int size = stroke.strokeVerticesSize();
565 
566  CurvePiece *piece = new CurvePiece(a, b, size);
567  _pieces.push_back(piece);
568 
569  while (!_pieces.empty()) {
570  piece = _pieces.back();
571  _pieces.pop_back();
572  if (piece->size > 2 && piece->error() > _error) {
573  CurvePiece *second = piece->subdivide();
574  _pieces.push_back(second);
575  _pieces.push_back(piece);
576  }
577  else {
578  _results.push_back(piece);
579  }
580  }
581 
582  // actually modify the geometry for each piece:
583  for (cp = _results.begin(), cpend = _results.end(); cp != cpend; ++cp) {
584  a = (*cp)->_begin;
585  b = (*cp)->_last;
586  Vec2d u = (*cp)->B - (*cp)->A;
587  Vec2d n(u[1], -u[0]);
588  n.normalize();
589  // Vec2d n(0, 0);
590  float offset = ((*cp)->_error);
592  for (v = a; v != b; ++v) {
593  v->setPoint((*cp)->A.x() + v->u() * u.x() + n.x() * offset,
594  (*cp)->A.y() + v->u() * u.y() + n.y() * offset);
595  }
596 #if 0
597  u.normalize();
598  (*a)->setPoint((*a)->x() - u.x() * 10, (*a)->y() - u.y() * 10);
599 #endif
600  }
601  stroke.UpdateLength();
602 
603  // delete stuff
604  for (cp = _results.begin(), cpend = _results.end(); cp != cpend; ++cp) {
605  delete (*cp);
606  }
607  _results.clear();
608  return 0;
609 }
610 
612 {
613  Functions1D::Normal2DF1D norm_fun;
616  --b;
617  int size = stroke.strokeVerticesSize();
618  CurvePiece piece(a, b, size);
619 
620  Vec2d u = piece.B - piece.A;
621  Vec2f n(u[1], -u[0]);
622  n.normalize();
623  if (norm_fun(stroke) < 0) {
624  return -1;
625  }
626  Vec2f strokeN(norm_fun.result);
627  if (n * strokeN < 0) {
628  n[0] = -n[0];
629  n[1] = -n[1];
630  }
631  float offset = (piece.error()) / 2.0f * _offset;
633  for (v = a, vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
634  v->setPoint(piece.A.x() + v->u() * u.x() + n.x() * offset,
635  piece.A.y() + v->u() * u.y() + n.y() * offset);
636  }
637  stroke.UpdateLength();
638  return 0;
639 }
640 
642 //
643 // Tip Remover
644 //
646 
648 {
649  _tipLength = tipLength;
650 }
651 
652 int TipRemoverShader::shade(Stroke &stroke) const
653 {
654  int originalSize = stroke.strokeVerticesSize();
655 
656  if (originalSize < 4) {
657  return 0;
658  }
659 
661  vector<StrokeVertex *> verticesToRemove;
662  vector<StrokeAttribute> oldAttributes;
663  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) {
664  if ((v->curvilinearAbscissa() < _tipLength) ||
665  (v->strokeLength() - v->curvilinearAbscissa() < _tipLength)) {
666  verticesToRemove.push_back(&(*v));
667  }
668  oldAttributes.push_back(v->attribute());
669  }
670 
671  if (originalSize - verticesToRemove.size() < 2) {
672  return 0;
673  }
674 
675  vector<StrokeVertex *>::iterator sv, svend;
676  for (sv = verticesToRemove.begin(), svend = verticesToRemove.end(); sv != svend; ++sv) {
677  stroke.RemoveVertex((*sv));
678  }
679 
680  // Resample so that our new stroke have the same number of vertices than before
681  stroke.Resample(originalSize);
682 
683  if ((int)stroke.strokeVerticesSize() != originalSize) { // soc
684  cerr << "Warning: resampling problem" << endl;
685  }
686 
687  // assign old attributes to new stroke vertices:
688  vector<StrokeAttribute>::iterator a = oldAttributes.begin(), aend = oldAttributes.end();
689  for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd();
690  (v != vend) && (a != aend);
691  ++v, ++a) {
692  v->setAttribute(*a);
693  }
694  // we're done!
695  return 0;
696 }
697 
698 } // namespace Freestyle::StrokeShaders
Functions taking 0D input.
Functions taking 1D input.
typedef float(TangentPoint)[2]
@ G_DEBUG_FREESTYLE
Definition: BKE_global.h:140
Class gathering basic stroke shaders.
_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 GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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 GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint vn
_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 y
_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 GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_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 GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Contains defines and structs used throughout the imbuf module.
Functions to manage I/O for the stroke.
Iterators used to iterate over the elements of the Stroke.
Classes to render a stroke with OpenGL.
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
std::vector< BezierCurveSegment * > & segments()
Definition: Bezier.h:82
const float * diffuse() const
Definition: FrsMaterial.h:102
virtual bool isEnd() const
Definition: Interface0D.h:296
real turbulenceSmooth(real x, unsigned nbOctave=8)
Definition: PseudoNoise.cpp:96
static real drand48()
Definition: RandGen.cpp:104
void setColor(float r, float g, float b)
Definition: Stroke.h:214
void setAlpha(float alpha)
Definition: Stroke.h:236
virtual int shade(Stroke &stroke) const
! Bezier curve stroke shader
virtual int shade(Stroke &stroke) const
StrokeInternal::StrokeVertexIterator _begin
CurvePiece * subdivide()
Subdivides the curve into two pieces.
StrokeInternal::StrokeVertexIterator _last
CurvePiece(StrokeInternal::StrokeVertexIterator b, StrokeInternal::StrokeVertexIterator l, int iSize)
virtual int shade(Stroke &stroke) const
virtual int shade(Stroke &stroke) const
const StrokeAttribute & attribute() const
Definition: Stroke.h:388
void setY(real y)
Definition: Stroke.h:425
void setX(real x)
Definition: Stroke.h:419
void setPoint(real x, real y)
Definition: Stroke.h:431
real x() const
Definition: Stroke.h:364
real y() const
Definition: Stroke.h:370
virtual Id getId() const
Definition: Stroke.h:512
void setTextureStep(float step)
Definition: Stroke.h:767
virtual Interface0DIterator verticesBegin()
Definition: Stroke.cpp:779
void RemoveVertex(StrokeVertex *iVertex)
Definition: Stroke.cpp:711
virtual Interface0DIterator verticesEnd()
Definition: Stroke.cpp:786
void UpdateLength()
Definition: Stroke.cpp:731
int setMTex(MTex *mtex)
Definition: Stroke.h:773
float ComputeSampling(int iNVertices)
Definition: Stroke.cpp:501
StrokeInternal::StrokeVertexIterator strokeVerticesEnd()
Definition: Stroke.cpp:773
StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t=0.0f)
Definition: Stroke.cpp:764
void setNodeTree(bNodeTree *iNodeTree)
Definition: Stroke.h:785
real getLength2D() const
Definition: Stroke.h:635
int Resample(int iNPoints)
Definition: Stroke.cpp:535
unsigned int strokeVerticesSize() const
Definition: Stroke.h:851
value_type x() const
Definition: VecMat.h:319
value_type y() const
Definition: VecMat.h:329
Vec< T, N > & normalize()
Definition: VecMat.h:119
static float P(float k)
Definition: math_interp.c:41
real distPointSegment(const T &P, const T &A, const T &B)
Definition: GeomUtils.h:44
VecMat::Vec2< double > Vec2d
Definition: Geom.h:35
static const unsigned NB_VALUE_NOISE
static const real M_EPSILON
Definition: Precision.h:29
static unsigned x[3]
Definition: RandGen.cpp:87
static unsigned a[3]
Definition: RandGen.cpp:92
double real
Definition: Precision.h:26
#define min(a, b)
Definition: sort.c:51
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float2 fabs(const float2 &a)
#define G(x, y, z)