Blender  V2.93
sculpt_paint_color.c
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  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_hash.h"
28 #include "BLI_math.h"
29 #include "BLI_math_color_blend.h"
30 #include "BLI_task.h"
31 
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 
35 #include "BKE_brush.h"
36 #include "BKE_colortools.h"
37 #include "BKE_context.h"
38 #include "BKE_mesh.h"
39 #include "BKE_mesh_mapping.h"
40 #include "BKE_object.h"
41 #include "BKE_paint.h"
42 #include "BKE_pbvh.h"
43 #include "BKE_scene.h"
44 
45 #include "DEG_depsgraph.h"
46 
47 #include "IMB_colormanagement.h"
48 
49 #include "WM_api.h"
50 #include "WM_message.h"
51 #include "WM_toolsystem.h"
52 #include "WM_types.h"
53 
54 #include "ED_object.h"
55 #include "ED_screen.h"
56 #include "ED_sculpt.h"
57 #include "paint_intern.h"
58 #include "sculpt_intern.h"
59 
60 #include "RNA_access.h"
61 #include "RNA_define.h"
62 
63 #include "UI_interface.h"
64 
65 #include "IMB_imbuf.h"
66 
67 #include "bmesh.h"
68 
69 #include <math.h>
70 #include <stdlib.h>
71 
72 static void do_color_smooth_task_cb_exec(void *__restrict userdata,
73  const int n,
74  const TaskParallelTLS *__restrict tls)
75 {
76  SculptThreadedTaskData *data = userdata;
77  SculptSession *ss = data->ob->sculpt;
78  const Brush *brush = data->brush;
79  const float bstrength = ss->cache->bstrength;
80 
81  PBVHVertexIter vd;
82 
83  SculptBrushTest test;
85  ss, &test, data->brush->falloff_shape);
86  const int thread_id = BLI_task_parallel_thread_id(tls);
87 
89  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
90  continue;
91  }
92  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
93  brush,
94  vd.co,
95  sqrtf(test.dist),
96  vd.no,
97  vd.fno,
98  vd.mask ? *vd.mask : 0.0f,
99  vd.index,
100  thread_id);
101 
102  float smooth_color[4];
103  SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
104  blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
105 
106  if (vd.mvert) {
108  }
109  }
111 }
112 
113 static void do_paint_brush_task_cb_ex(void *__restrict userdata,
114  const int n,
115  const TaskParallelTLS *__restrict tls)
116 {
117  SculptThreadedTaskData *data = userdata;
118  SculptSession *ss = data->ob->sculpt;
119  const Brush *brush = data->brush;
120  const float bstrength = fabsf(ss->cache->bstrength);
121 
122  PBVHVertexIter vd;
123  PBVHColorBufferNode *color_buffer;
124 
125  SculptOrigVertData orig_data;
126  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
127 
128  color_buffer = BKE_pbvh_node_color_buffer_get(data->nodes[n]);
129 
130  SculptBrushTest test;
132  ss, &test, data->brush->falloff_shape);
133  const int thread_id = BLI_task_parallel_thread_id(tls);
134 
135  float brush_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
136  copy_v3_v3(brush_color,
137  ss->cache->invert ? BKE_brush_secondary_color_get(ss->scene, brush) :
138  BKE_brush_color_get(ss->scene, brush));
140 
141  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
142  SCULPT_orig_vert_data_update(&orig_data, &vd);
143 
144  bool affect_vertex = false;
145  float distance_to_stroke_location = 0.0f;
146  if (brush->tip_roundness < 1.0f) {
147  affect_vertex = SCULPT_brush_test_cube(&test, vd.co, data->mat, brush->tip_roundness);
148  distance_to_stroke_location = ss->cache->radius * test.dist;
149  }
150  else {
151  affect_vertex = sculpt_brush_test_sq_fn(&test, vd.co);
152  distance_to_stroke_location = sqrtf(test.dist);
153  }
154 
155  if (!affect_vertex) {
156  continue;
157  }
158 
159  float fade = bstrength * SCULPT_brush_strength_factor(ss,
160  brush,
161  vd.co,
162  distance_to_stroke_location,
163  vd.no,
164  vd.fno,
165  vd.mask ? *vd.mask : 0.0f,
166  vd.index,
167  thread_id);
168 
169  /* Density. */
170  float noise = 1.0f;
171  const float density = ss->cache->paint_brush.density;
172  if (density < 1.0f) {
173  const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
174  if (hash_noise > density) {
175  noise = density * hash_noise;
176  fade = fade * noise;
177  }
178  }
179 
180  /* Brush paint color, brush test falloff and flow. */
181  float paint_color[4];
182  float wet_mix_color[4];
183  float buffer_color[4];
184 
185  mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
186  mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
187 
188  /* Interpolate with the wet_mix color for wet paint mixing. */
190  paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
191  blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
192 
193  /* Final mix over the original color using brush alpha. */
194  mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
195 
196  IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
197 
198  CLAMP4(vd.col, 0.0f, 1.0f);
199 
200  if (vd.mvert) {
202  }
203  }
205 }
206 
207 typedef struct SampleWetPaintTLSData {
209  float color[4];
211 
212 static void do_sample_wet_paint_task_cb(void *__restrict userdata,
213  const int n,
214  const TaskParallelTLS *__restrict tls)
215 {
216  SculptThreadedTaskData *data = userdata;
217  SculptSession *ss = data->ob->sculpt;
218  SampleWetPaintTLSData *swptd = tls->userdata_chunk;
219  PBVHVertexIter vd;
220 
221  SculptBrushTest test;
223  ss, &test, data->brush->falloff_shape);
224 
225  test.radius *= data->brush->wet_paint_radius_factor;
226  test.radius_squared = test.radius * test.radius;
227 
228  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
229  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
230  continue;
231  }
232 
233  add_v4_v4(swptd->color, vd.col);
234  swptd->tot_samples++;
235  }
237 }
238 
239 static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata),
240  void *__restrict chunk_join,
241  void *__restrict chunk)
242 {
243  SampleWetPaintTLSData *join = chunk_join;
244  SampleWetPaintTLSData *swptd = chunk;
245 
246  join->tot_samples += swptd->tot_samples;
247  add_v4_v4(join->color, swptd->color);
248 }
249 
250 void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
251 {
252  Brush *brush = BKE_paint_brush(&sd->paint);
253  SculptSession *ss = ob->sculpt;
254 
255  if (!ss->vcol) {
256  return;
257  }
258 
261  ss->cache->density_seed = BLI_hash_int_01(ss->cache->location[0] * 1000);
262  }
263  return;
264  }
265 
267 
268  float area_no[3];
269  float mat[4][4];
270  float scale[4][4];
271  float tmat[4][4];
272 
273  /* If the brush is round the tip does not need to be aligned to the surface, so this saves a
274  * whole iteration over the affected nodes. */
275  if (brush->tip_roundness < 1.0f) {
276  SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
277 
278  cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
279  mat[0][3] = 0;
280  cross_v3_v3v3(mat[1], area_no, mat[0]);
281  mat[1][3] = 0;
282  copy_v3_v3(mat[2], area_no);
283  mat[2][3] = 0;
284  copy_v3_v3(mat[3], ss->cache->location);
285  mat[3][3] = 1;
286  normalize_m4(mat);
287 
288  scale_m4_fl(scale, ss->cache->radius);
289  mul_m4_m4m4(tmat, mat, scale);
290  mul_v3_fl(tmat[1], brush->tip_scale_x);
291  invert_m4_m4(mat, tmat);
292  if (is_zero_m4(mat)) {
293  return;
294  }
295  }
296 
297  /* Smooth colors mode. */
298  if (ss->cache->alt_smooth) {
300  .sd = sd,
301  .ob = ob,
302  .brush = brush,
303  .nodes = nodes,
304  .mat = mat,
305  };
306 
307  TaskParallelSettings settings;
308  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
310  return;
311  }
312 
313  /* Regular Paint mode. */
314 
315  /* Wet paint color sampling. */
316  float wet_color[4] = {0.0f};
317  if (ss->cache->paint_brush.wet_mix > 0.0f) {
318  SculptThreadedTaskData task_data = {
319  .sd = sd,
320  .ob = ob,
321  .nodes = nodes,
322  .brush = brush,
323  };
324 
325  SampleWetPaintTLSData swptd;
326  swptd.tot_samples = 0;
327  zero_v4(swptd.color);
328 
329  TaskParallelSettings settings_sample;
330  BKE_pbvh_parallel_range_settings(&settings_sample, true, totnode);
331  settings_sample.func_reduce = sample_wet_paint_reduce;
332  settings_sample.userdata_chunk = &swptd;
333  settings_sample.userdata_chunk_size = sizeof(SampleWetPaintTLSData);
334  BLI_task_parallel_range(0, totnode, &task_data, do_sample_wet_paint_task_cb, &settings_sample);
335 
336  if (swptd.tot_samples > 0 && is_finite_v4(swptd.color)) {
337  copy_v4_v4(wet_color, swptd.color);
338  mul_v4_fl(wet_color, 1.0f / swptd.tot_samples);
339  CLAMP4(wet_color, 0.0f, 1.0f);
340 
341  if (ss->cache->first_time) {
342  copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
343  }
345  wet_color,
348  copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
349  CLAMP4(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
350  }
351  }
352 
353  /* Threaded loop over nodes. */
355  .sd = sd,
356  .ob = ob,
357  .brush = brush,
358  .nodes = nodes,
359  .wet_mix_sampled_color = wet_color,
360  .mat = mat,
361  };
362 
363  TaskParallelSettings settings;
364  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
365  BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
366 }
367 
368 static void do_smear_brush_task_cb_exec(void *__restrict userdata,
369  const int n,
370  const TaskParallelTLS *__restrict tls)
371 {
372  SculptThreadedTaskData *data = userdata;
373  SculptSession *ss = data->ob->sculpt;
374  const Brush *brush = data->brush;
375  const float bstrength = ss->cache->bstrength;
376 
377  PBVHVertexIter vd;
378 
379  SculptBrushTest test;
381  ss, &test, data->brush->falloff_shape);
382  const int thread_id = BLI_task_parallel_thread_id(tls);
383 
384  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
385  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
386  continue;
387  }
388  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
389  brush,
390  vd.co,
391  sqrtf(test.dist),
392  vd.no,
393  vd.fno,
394  vd.mask ? *vd.mask : 0.0f,
395  vd.index,
396  thread_id);
397 
398  float current_disp[3];
399  float current_disp_norm[3];
400  float interp_color[4];
401  copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
402 
403  switch (brush->smear_deform_type) {
405  sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
406  break;
408  sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
409  break;
411  sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
412  break;
413  }
414  normalize_v3_v3(current_disp_norm, current_disp);
415  mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
416 
419  float vertex_disp[3];
420  float vertex_disp_norm[3];
421  sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
422  const float *neighbor_color = ss->cache->prev_colors[ni.index];
423  normalize_v3_v3(vertex_disp_norm, vertex_disp);
424  if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
425  continue;
426  }
427  const float color_interp = clamp_f(
428  -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
429  float color_mix[4];
430  copy_v4_v4(color_mix, neighbor_color);
431  mul_v4_fl(color_mix, color_interp * fade);
432  blend_color_mix_float(interp_color, interp_color, color_mix);
433  }
435 
436  blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
437 
438  if (vd.mvert) {
440  }
441  }
443 }
444 
445 static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
446  const int n,
447  const TaskParallelTLS *__restrict UNUSED(tls))
448 {
449  SculptThreadedTaskData *data = userdata;
450  SculptSession *ss = data->ob->sculpt;
451 
452  PBVHVertexIter vd;
453  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
455  }
457 }
458 
459 void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
460 {
461  Brush *brush = BKE_paint_brush(&sd->paint);
462  SculptSession *ss = ob->sculpt;
463 
464  if (!ss->vcol) {
465  return;
466  }
467 
468  const int totvert = SCULPT_vertex_count_get(ss);
469 
471  if (!ss->cache->prev_colors) {
472  ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors");
473  for (int i = 0; i < totvert; i++) {
475  }
476  }
477  }
478 
480 
482  .sd = sd,
483  .ob = ob,
484  .brush = brush,
485  .nodes = nodes,
486  };
487 
488  TaskParallelSettings settings;
489  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
490 
491  /* Smooth colors mode. */
492  if (ss->cache->alt_smooth) {
494  }
495  else {
496  /* Smear mode. */
498  BLI_task_parallel_range(0, totnode, &data, do_smear_brush_task_cb_exec, &settings);
499  }
500 }
const float * BKE_brush_secondary_color_get(const struct Scene *scene, const struct Brush *brush)
Definition: brush.c:2216
const float * BKE_brush_color_get(const struct Scene *scene, const struct Brush *brush)
Definition: brush.c:2210
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1200
General operations, lookup, etc. for blender objects.
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:604
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:384
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:457
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:335
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3042
PBVHColorBufferNode * BKE_pbvh_node_color_buffer_get(PBVHNode *node)
Definition: pbvh.c:2911
BLI_INLINE float BLI_hash_int_01(unsigned int k)
Definition: BLI_hash.h:108
MINLINE float clamp_f(float value, float min, float max)
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2309
bool is_zero_m4(const float mat[4][4])
Definition: math_matrix.c:2601
void normalize_m4(float R[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1952
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f)
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v4(float r[4])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
bool is_finite_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:403
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
#define UNUSED(x)
#define CLAMP4(vec, b, c)
@ BRUSH_SMEAR_DEFORM_PINCH
@ BRUSH_SMEAR_DEFORM_EXPAND
@ BRUSH_SMEAR_DEFORM_DRAG
@ ME_VERT_PBVH_UPDATE
void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3])
void IMB_blend_color_float(float dst[4], const float src1[4], const float src2[4], IMB_BlendMode mode)
Definition: rectop.c:129
Read Guarded memory(de)allocation.
#define fabsf(x)
#define sqrtf(x)
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static float noise(int n)
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:134
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:120
void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
Definition: sculpt.c:1310
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss, SculptBrushTest *test, char falloff_shape)
Definition: sculpt.c:1770
bool SCULPT_brush_test_cube(SculptBrushTest *test, const float co[3], const float local[4][4], const float roundness)
Definition: sculpt.c:1723
float SCULPT_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], const float len, const short vno[3], const float fno[3], const float mask, const int vertex_index, const int thread_id)
Definition: sculpt.c:2463
const float * SCULPT_vertex_color_get(SculptSession *ss, int index)
Definition: sculpt.c:157
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:935
void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
Definition: sculpt.c:2197
bool SCULPT_stroke_is_first_brush_step(StrokeCache *cache)
Definition: sculpt.c:926
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node)
Definition: sculpt.c:1300
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
bool(* SculptBrushTestFn)(SculptBrushTest *test, const float co[3])
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index)
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_color_smooth_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_smear_brush_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
struct SampleWetPaintTLSData SampleWetPaintTLSData
static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata), void *__restrict chunk_join, void *__restrict chunk)
static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
static void do_sample_wet_paint_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_paint_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
float alpha
struct CurveMapping * curve
float tip_scale_x
short blend
int smear_deform_type
float tip_roundness
struct SculptSession * sculpt
float(* color)[4]
Definition: BKE_pbvh.h:60
struct MVert * mvert
Definition: BKE_pbvh.h:372
short * no
Definition: BKE_pbvh.h:375
float * co
Definition: BKE_pbvh.h:374
float * fno
Definition: BKE_pbvh.h:376
float * col
Definition: BKE_pbvh.h:378
float * mask
Definition: BKE_pbvh.h:377
const float * col
struct MPropCol * vcol
Definition: BKE_paint.h:469
struct Scene * scene
Definition: BKE_paint.h:546
struct StrokeCache * cache
Definition: BKE_paint.h:518
struct PBVH * pbvh
Definition: BKE_paint.h:504
struct Sculpt * sd
Paint paint
float wet_mix_prev_color[4]
float last_location[3]
float density_seed
float grab_delta_symmetry[3]
float location[3]
struct StrokeCache::@489 paint_brush
float(* prev_colors)[4]
float wet_persistence
TaskParallelReduceFunc func_reduce
Definition: BLI_task.h:158
size_t userdata_chunk_size
Definition: BLI_task.h:150
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: svm_noise.h:37