Blender  V3.3
AdvancedStrokeShaders.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include "StrokeIterators.h"
10 
11 #include "../system/PseudoNoise.h"
12 #include "../system/RandGen.h"
13 
14 namespace Freestyle {
15 
17 //
18 // CALLIGRAPHICS SHADER
19 //
21 
23  real iMaxThickness,
24  const Vec2f &iOrientation,
25  bool clamp)
26 {
27  _minThickness = iMinThickness;
28  _maxThickness = iMaxThickness;
29  _orientation = iOrientation;
31  _clamp = clamp;
32 }
33 
34 int CalligraphicShader::shade(Stroke &ioStroke) const
35 {
38  StrokeVertex *sv;
39  for (v = ioStroke.verticesBegin(); !v.isEnd(); ++v) {
40  real thickness;
41  if (fun(v) < 0) {
42  return -1;
43  }
44 
45  Vec2f vertexOri(fun.result);
46  Vec2r ori2d(-vertexOri[1], vertexOri[0]);
47  ori2d.normalizeSafe();
48  real scal = ori2d * _orientation;
49  sv = dynamic_cast<StrokeVertex *>(&(*v));
50  if (_clamp && (scal < 0)) {
51  scal = 0.0;
52  sv->attribute().setColor(1, 1, 1);
53  }
54  else {
55  scal = fabs(scal);
56  sv->attribute().setColor(0, 0, 0);
57  }
58  thickness = _minThickness + scal * (_maxThickness - _minThickness);
59  if (thickness < 0.0) {
60  thickness = 0.0;
61  }
62  sv->attribute().setThickness(thickness / 2.0, thickness / 2.0);
63  }
64 
65  return 0;
66 }
67 
69 //
70 // SPATIAL NOISE SHADER
71 //
73 
74 static const unsigned NB_VALUE_NOISE = 512;
75 
77  float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom)
78 {
79  _amount = iAmount;
80  if (ixScale == 0) {
81  _xScale = 0;
82  }
83  else {
84  _xScale = 1.0 / ixScale / real(NB_VALUE_NOISE);
85  }
86  _nbOctave = nbOctave;
87  _smooth = smooth;
88  _pureRandom = pureRandom;
89 }
90 
91 int SpatialNoiseShader::shade(Stroke &ioStroke) const
92 {
94  v = ioStroke.verticesBegin();
95  Vec2r p(v->getProjectedX(), v->getProjectedY());
96  v2 = v;
97  ++v2;
98  Vec2r p0(v2->getProjectedX(), v2->getProjectedY());
99  p0 = p + 2 * (p - p0);
100  StrokeVertex *sv;
101  sv = dynamic_cast<StrokeVertex *>(&(*v));
102  real initU = sv->strokeLength() * real(NB_VALUE_NOISE);
103  if (_pureRandom) {
104  initU += RandGen::drand48() * real(NB_VALUE_NOISE);
105  }
106 
108  while (!v.isEnd()) {
109  sv = dynamic_cast<StrokeVertex *>(&(*v));
110  Vec2r p(sv->getPoint());
111  if (fun(v) < 0) {
112  return -1;
113  }
114  Vec2r vertexOri(fun.result);
115  Vec2r ori2d(vertexOri[0], vertexOri[1]);
116  ori2d = Vec2r(p - p0);
117  ori2d.normalizeSafe();
118 
119  PseudoNoise mynoise;
120  real bruit;
121 
122  if (_smooth) {
123  bruit = mynoise.turbulenceSmooth(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave);
124  }
125  else {
126  bruit = mynoise.turbulenceLinear(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave);
127  }
128 
129  Vec2r noise(-ori2d[1] * _amount * bruit, ori2d[0] * _amount * bruit);
130 
131  sv->setPoint(p[0] + noise[0], p[1] + noise[1]);
132  p0 = p;
133 
134  ++v;
135  }
136 
137  ioStroke.UpdateLength();
138 
139  return 0;
140 }
141 
143 //
144 // SMOOTHING SHADER
145 //
147 
149  real iFactorPoint,
150  real ifactorCurvature,
151  real iFactorCurvatureDifference,
152  real iAnisoPoint,
153  real iAnisoNormal,
154  real iAnisoCurvature,
155  real iCarricatureFactor)
156 {
157  _nbIterations = iNbIteration;
158  _factorCurvature = ifactorCurvature;
159  _factorCurvatureDifference = iFactorCurvatureDifference;
160  _anisoNormal = iAnisoNormal;
161  _anisoCurvature = iAnisoCurvature;
162  _carricatureFactor = iCarricatureFactor;
163  _factorPoint = iFactorPoint;
164  _anisoPoint = iAnisoPoint;
165 }
166 
167 int SmoothingShader::shade(Stroke &ioStroke) const
168 {
169  // cerr << " Smoothing a stroke " << endl;
170 
171  Smoother smoother(ioStroke);
172  smoother.smooth(_nbIterations,
173  _factorPoint,
176  _anisoPoint,
177  _anisoNormal,
180  return 0;
181 }
182 
183 // SMOOTHER
185 
187 {
188  _stroke = &ioStroke;
189 
190  _nbVertices = ioStroke.vertices_size();
191  _vertex = new Vec2r[_nbVertices];
192  _curvature = new real[_nbVertices];
193  _normal = new Vec2r[_nbVertices];
195  int i = 0;
196  for (v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); v != vend;
197  ++v, ++i) {
198  _vertex[i] = (v)->getPoint();
199  }
200  Vec2r vec_tmp(_vertex[0] - _vertex[_nbVertices - 1]);
201  _isClosedCurve = (vec_tmp.norm() < M_EPSILON);
202 
203  _safeTest = (_nbVertices > 4);
204 }
205 
207 {
208  delete[] _vertex;
209  delete[] _curvature;
210  delete[] _normal;
211 }
212 
213 void Smoother::smooth(int nbIteration,
214  real iFactorPoint,
215  real ifactorCurvature,
216  real iFactorCurvatureDifference,
217  real iAnisoPoint,
218  real iAnisoNormal,
219  real iAnisoCurvature,
220  real iCarricatureFactor)
221 {
222  _factorCurvature = ifactorCurvature;
223  _factorCurvatureDifference = iFactorCurvatureDifference;
224  _anisoNormal = iAnisoNormal;
225  _anisoCurvature = iAnisoCurvature;
226  _carricatureFactor = iCarricatureFactor;
227  _factorPoint = iFactorPoint;
228  _anisoPoint = iAnisoPoint;
229 
230  for (int i = 0; i < nbIteration; ++i) {
231  iteration();
232  }
233  copyVertices();
234 }
235 
236 static real edgeStopping(real x, real sigma)
237 {
238  if (sigma == 0.0) {
239  return 1.0;
240  }
241  return exp(-x * x / (sigma * sigma));
242 }
243 
245 {
247  for (int i = 1; i < (_nbVertices - 1); ++i) {
248  real motionNormal = _factorCurvature * _curvature[i] *
250 
251  real diffC1 = _curvature[i] - _curvature[i - 1];
252  real diffC2 = _curvature[i] - _curvature[i + 1];
253  real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 +
254  edgeStopping(diffC2, _anisoCurvature) *
255  diffC2; //_factorCurvatureDifference;
256  motionCurvature *= _factorCurvatureDifference;
257  // motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2);
258  if (_safeTest) {
259  _vertex[i] = Vec2r(_vertex[i] + (motionNormal + motionCurvature) * _normal[i]);
260  }
261  Vec2r v1(_vertex[i - 1] - _vertex[i]);
262  Vec2r v2(_vertex[i + 1] - _vertex[i]);
263  real d1 = v1.norm();
264  real d2 = v2.norm();
265  _vertex[i] = Vec2r(
266  _vertex[i] + _factorPoint * edgeStopping(d2, _anisoPoint) * (_vertex[i - 1] - _vertex[i]) +
267  _factorPoint * edgeStopping(d1, _anisoPoint) * (_vertex[i + 1] - _vertex[i]));
268  }
269 
270  if (_isClosedCurve) {
271  real motionNormal = _factorCurvature * _curvature[0] *
273 
274  real diffC1 = _curvature[0] - _curvature[_nbVertices - 2];
275  real diffC2 = _curvature[0] - _curvature[1];
276  real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 +
277  edgeStopping(diffC2, _anisoCurvature) *
278  diffC2; //_factorCurvatureDifference;
279  motionCurvature *= _factorCurvatureDifference;
280  // motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2);
281  _vertex[0] = Vec2r(_vertex[0] + (motionNormal + motionCurvature) * _normal[0]);
282  _vertex[_nbVertices - 1] = _vertex[0];
283  }
284 }
285 
287 {
288  int i;
289  Vec2r BA, BC, normalCurvature;
290  for (i = 1; i < (_nbVertices - 1); ++i) {
291  BA = _vertex[i - 1] - _vertex[i];
292  BC = _vertex[i + 1] - _vertex[i];
293  real lba = BA.norm(), lbc = BC.norm();
294  BA.normalizeSafe();
295  BC.normalizeSafe();
296  normalCurvature = BA + BC;
297 
298  _normal[i] = Vec2r(-(BC - BA)[1], (BC - BA)[0]);
299  _normal[i].normalizeSafe();
300 
301  _curvature[i] = normalCurvature * _normal[i];
302  if (lba + lbc > M_EPSILON) {
303  _curvature[i] /= (0.5 * lba + lbc);
304  }
305  }
306  _curvature[0] = _curvature[1];
308  Vec2r di(_vertex[1] - _vertex[0]);
309  _normal[0] = Vec2r(-di[1], di[0]);
310  _normal[0].normalizeSafe();
311  di = _vertex[_nbVertices - 1] - _vertex[_nbVertices - 2];
312  _normal[_nbVertices - 1] = Vec2r(-di[1], di[0]);
314 
315  if (_isClosedCurve) {
316  BA = _vertex[_nbVertices - 2] - _vertex[0];
317  BC = _vertex[1] - _vertex[0];
318  real lba = BA.norm(), lbc = BC.norm();
319  BA.normalizeSafe();
320  BC.normalizeSafe();
321  normalCurvature = BA + BC;
322 
323  _normal[i] = Vec2r(-(BC - BA)[1], (BC - BA)[0]);
324  _normal[i].normalizeSafe();
325 
326  _curvature[i] = normalCurvature * _normal[i];
327  if (lba + lbc > M_EPSILON) {
328  _curvature[i] /= (0.5 * lba + lbc);
329  }
330 
331  _normal[_nbVertices - 1] = _normal[0];
333  }
334 }
335 
337 {
338  int i = 0;
340  for (v = _stroke->strokeVerticesBegin(), vend = _stroke->strokeVerticesEnd(); v != vend; ++v) {
341  const Vec2r p0((v)->getPoint());
342  const Vec2r p1(_vertex[i]);
343  Vec2r p(p0 + _carricatureFactor * (p1 - p0));
344 
345  (v)->setPoint(p[0], p[1]);
346  ++i;
347  }
349 }
350 
351 } /* namespace Freestyle */
Fredo's 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 v1
Iterators used to iterate over the elements of the Stroke.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
CalligraphicShader(real iMinThickness, real iMaxThickness, const Vec2f &iOrientation, bool clamp)
virtual int shade(Stroke &ioStroke) const
real turbulenceSmooth(real x, unsigned nbOctave=8)
Definition: PseudoNoise.cpp:82
real turbulenceLinear(real x, unsigned nbOctave=8)
Definition: PseudoNoise.cpp:93
static real drand48()
Definition: RandGen.cpp:90
void smooth(int nbIterations, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor)
virtual int shade(Stroke &ioStroke) const
SmoothingShader(int iNbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor)
virtual int shade(Stroke &ioStroke) const
SpatialNoiseShader(float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom)
void setThickness(float tr, float tl)
Definition: Stroke.h:233
void setColor(float r, float g, float b)
Definition: Stroke.h:200
const StrokeAttribute & attribute() const
Definition: Stroke.h:374
float strokeLength() const
Definition: Stroke.h:392
virtual Interface0DIterator verticesBegin()
Definition: Stroke.cpp:765
int vertices_size() const
Definition: Stroke.h:670
void UpdateLength()
Definition: Stroke.cpp:717
StrokeInternal::StrokeVertexIterator strokeVerticesEnd()
Definition: Stroke.cpp:759
StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t=0.0f)
Definition: Stroke.cpp:750
Vec< T, N > & normalizeSafe()
Definition: VecMat.h:114
value_type norm() const
Definition: VecMat.h:95
Vec< T, N > & normalize()
Definition: VecMat.h:105
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
VecMat::Vec2< real > Vec2r
Definition: Geom.h:22
inherits from class Rep
Definition: AppCanvas.cpp:18
static const unsigned NB_VALUE_NOISE
static const real M_EPSILON
Definition: Precision.h:15
static unsigned x[3]
Definition: RandGen.cpp:73
static real edgeStopping(real x, real sigma)
double real
Definition: Precision.h:12
T clamp(const T &a, const T &min, const T &max)
static float noise(int n)
smooth(Type::FLOAT, "mask_weight")