Blender  V3.3
sculpt_brush_types.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2006 by Nicholas Bishop. All rights reserved. */
3 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_blenlib.h"
12 #include "BLI_dial_2d.h"
13 #include "BLI_ghash.h"
14 #include "BLI_gsqueue.h"
15 #include "BLI_hash.h"
16 #include "BLI_math.h"
17 #include "BLI_math_color.h"
18 #include "BLI_math_color_blend.h"
19 #include "BLI_task.h"
20 #include "BLI_utildefines.h"
21 
22 #include "BLT_translation.h"
23 
24 #include "PIL_time.h"
25 
26 #include "DNA_brush_types.h"
27 #include "DNA_customdata_types.h"
28 #include "DNA_mesh_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_node_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_scene_types.h"
33 
34 #include "BKE_brush.h"
35 #include "BKE_ccg.h"
36 #include "BKE_colortools.h"
37 #include "BKE_context.h"
38 #include "BKE_image.h"
39 #include "BKE_kelvinlet.h"
40 #include "BKE_key.h"
41 #include "BKE_lib_id.h"
42 #include "BKE_main.h"
43 #include "BKE_mesh.h"
44 #include "BKE_mesh_mapping.h"
45 #include "BKE_mesh_mirror.h"
46 #include "BKE_modifier.h"
47 #include "BKE_multires.h"
48 #include "BKE_node.h"
49 #include "BKE_object.h"
50 #include "BKE_paint.h"
51 #include "BKE_particle.h"
52 #include "BKE_pbvh.h"
53 #include "BKE_pointcache.h"
54 #include "BKE_report.h"
55 #include "BKE_scene.h"
56 #include "BKE_screen.h"
57 #include "BKE_subdiv_ccg.h"
58 #include "BKE_subsurf.h"
59 
60 #include "DEG_depsgraph.h"
61 
62 #include "IMB_colormanagement.h"
63 
64 #include "WM_api.h"
65 #include "WM_message.h"
66 #include "WM_toolsystem.h"
67 #include "WM_types.h"
68 
69 #include "ED_object.h"
70 #include "ED_screen.h"
71 #include "ED_sculpt.h"
72 #include "ED_view3d.h"
73 
74 #include "paint_intern.h"
75 #include "sculpt_intern.h"
76 
77 #include "RNA_access.h"
78 #include "RNA_define.h"
79 
80 #include "UI_interface.h"
81 #include "UI_resources.h"
82 
83 #include "bmesh.h"
84 #include "bmesh_tools.h"
85 
86 #include <math.h>
87 #include <stdlib.h>
88 #include <string.h>
89 
90 /* -------------------------------------------------------------------- */
96 typedef struct SculptProjectVector {
97  float plane[3];
98  float len_sq;
100  bool is_valid;
101 
103 
104 static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip)
105 {
106  float d = plane_point_side_v3(plane, co);
107  if (flip) {
108  d = -d;
109  }
110  return d <= 0.0f;
111 }
112 
116 static void sculpt_project_v3_cache_init(SculptProjectVector *spvc, const float plane[3])
117 {
118  copy_v3_v3(spvc->plane, plane);
119  spvc->len_sq = len_squared_v3(spvc->plane);
120  spvc->is_valid = (spvc->len_sq > FLT_EPSILON);
121  spvc->len_sq_inv_neg = (spvc->is_valid) ? -1.0f / spvc->len_sq : 0.0f;
122 }
123 
127 static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3], float r_vec[3])
128 {
129 #if 0
130  project_plane_v3_v3v3(r_vec, vec, spvc->plane);
131 #else
132  /* inline the projection, cache `-1.0 / dot_v3_v3(v_proj, v_proj)` */
133  madd_v3_v3fl(r_vec, spvc->plane, dot_v3v3(vec, spvc->plane) * spvc->len_sq_inv_neg);
134 #endif
135 }
136 
137 static void calc_sculpt_plane(
138  Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
139 {
140  SculptSession *ss = ob->sculpt;
141  Brush *brush = BKE_paint_brush(&sd->paint);
142 
145  !(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
146  switch (brush->sculpt_plane) {
148  copy_v3_v3(r_area_no, ss->cache->true_view_normal);
149  break;
150 
151  case SCULPT_DISP_DIR_X:
152  ARRAY_SET_ITEMS(r_area_no, 1.0f, 0.0f, 0.0f);
153  break;
154 
155  case SCULPT_DISP_DIR_Y:
156  ARRAY_SET_ITEMS(r_area_no, 0.0f, 1.0f, 0.0f);
157  break;
158 
159  case SCULPT_DISP_DIR_Z:
160  ARRAY_SET_ITEMS(r_area_no, 0.0f, 0.0f, 1.0f);
161  break;
162 
164  SCULPT_calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co);
165  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
166  project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
167  normalize_v3(r_area_no);
168  }
169  break;
170 
171  default:
172  break;
173  }
174 
175  /* For flatten center. */
176  /* Flatten center has not been calculated yet if we are not using the area normal. */
177  if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
178  SCULPT_calc_area_center(sd, ob, nodes, totnode, r_area_co);
179  }
180 
181  /* For area normal. */
183  (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
184  copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
185  }
186  else {
187  copy_v3_v3(ss->cache->sculpt_normal, r_area_no);
188  }
189 
190  /* For flatten center. */
192  (brush->flag & BRUSH_ORIGINAL_PLANE)) {
193  copy_v3_v3(r_area_co, ss->cache->last_center);
194  }
195  else {
196  copy_v3_v3(ss->cache->last_center, r_area_co);
197  }
198  }
199  else {
200  /* For area normal. */
201  copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
202 
203  /* For flatten center. */
204  copy_v3_v3(r_area_co, ss->cache->last_center);
205 
206  /* For area normal. */
207  flip_v3(r_area_no, ss->cache->mirror_symmetry_pass);
208 
209  /* For flatten center. */
210  flip_v3(r_area_co, ss->cache->mirror_symmetry_pass);
211 
212  /* For area normal. */
213  mul_m4_v3(ss->cache->symm_rot_mat, r_area_no);
214 
215  /* For flatten center. */
216  mul_m4_v3(ss->cache->symm_rot_mat, r_area_co);
217 
218  /* Shift the plane for the current tile. */
219  add_v3_v3(r_area_co, ss->cache->plane_offset);
220  }
221 }
222 
223 static void sculpt_rake_rotate(const SculptSession *ss,
224  const float sculpt_co[3],
225  const float v_co[3],
226  float factor,
227  float r_delta[3])
228 {
229  float vec_rot[3];
230 
231 #if 0
232  /* lerp */
233  sub_v3_v3v3(vec_rot, v_co, sculpt_co);
234  mul_qt_v3(ss->cache->rake_rotation_symmetry, vec_rot);
235  add_v3_v3(vec_rot, sculpt_co);
236  sub_v3_v3v3(r_delta, vec_rot, v_co);
237  mul_v3_fl(r_delta, factor);
238 #else
239  /* slerp */
240  float q_interp[4];
241  sub_v3_v3v3(vec_rot, v_co, sculpt_co);
242 
243  copy_qt_qt(q_interp, ss->cache->rake_rotation_symmetry);
244  pow_qt_fl_normalized(q_interp, factor);
245  mul_qt_v3(q_interp, vec_rot);
246 
247  add_v3_v3(vec_rot, sculpt_co);
248  sub_v3_v3v3(r_delta, vec_rot, v_co);
249 #endif
250 }
251 
258  const float normal_weight,
259  float grab_delta[3])
260 {
261  /* Signed to support grabbing in (to make a hole) as well as out. */
262  const float len_signed = dot_v3v3(ss->cache->sculpt_normal_symm, grab_delta);
263 
264  /* This scale effectively projects the offset so dragging follows the cursor,
265  * as the normal points towards the view, the scale increases. */
266  float len_view_scale;
267  {
268  float view_aligned_normal[3];
270  view_aligned_normal, ss->cache->sculpt_normal_symm, ss->cache->view_normal);
271  len_view_scale = fabsf(dot_v3v3(view_aligned_normal, ss->cache->sculpt_normal_symm));
272  len_view_scale = (len_view_scale > FLT_EPSILON) ? 1.0f / len_view_scale : 1.0f;
273  }
274 
275  mul_v3_fl(grab_delta, 1.0f - normal_weight);
276  madd_v3_v3fl(
277  grab_delta, ss->cache->sculpt_normal_symm, (len_signed * normal_weight) * len_view_scale);
278 }
279 
282 /* -------------------------------------------------------------------- */
286 static void do_draw_brush_task_cb_ex(void *__restrict userdata,
287  const int n,
288  const TaskParallelTLS *__restrict tls)
289 {
290  SculptThreadedTaskData *data = userdata;
291  SculptSession *ss = data->ob->sculpt;
292  const Brush *brush = data->brush;
293  const float *offset = data->offset;
294 
295  PBVHVertexIter vd;
296  float(*proxy)[3];
297 
298  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
299 
300  SculptBrushTest test;
302  ss, &test, data->brush->falloff_shape);
303  const int thread_id = BLI_task_parallel_thread_id(tls);
304 
305  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
306  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
307  continue;
308  }
309  /* Offset vertex. */
310  const float fade = SCULPT_brush_strength_factor(ss,
311  brush,
312  vd.co,
313  sqrtf(test.dist),
314  vd.no,
315  vd.fno,
316  vd.mask ? *vd.mask : 0.0f,
317  vd.index,
318  thread_id);
319 
320  mul_v3_v3fl(proxy[vd.i], offset, fade);
321 
322  if (vd.mvert) {
324  }
325  }
327 }
328 
329 void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
330 {
331  SculptSession *ss = ob->sculpt;
332  Brush *brush = BKE_paint_brush(&sd->paint);
333  float offset[3];
334  const float bstrength = ss->cache->bstrength;
335 
336  /* Offset with as much as possible factored in already. */
337  float effective_normal[3];
338  SCULPT_tilt_effective_normal_get(ss, brush, effective_normal);
339  mul_v3_v3fl(offset, effective_normal, ss->cache->radius);
340  mul_v3_v3(offset, ss->cache->scale);
341  mul_v3_fl(offset, bstrength);
342 
343  /* XXX: this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
344  * initialize before threads so they can do curve mapping. */
346 
347  /* Threaded loop over nodes. */
349  .sd = sd,
350  .ob = ob,
351  .brush = brush,
352  .nodes = nodes,
353  .offset = offset,
354  };
355 
356  TaskParallelSettings settings;
357  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
358  BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
359 }
360 
363 /* -------------------------------------------------------------------- */
367 static void do_fill_brush_task_cb_ex(void *__restrict userdata,
368  const int n,
369  const TaskParallelTLS *__restrict tls)
370 {
371  SculptThreadedTaskData *data = userdata;
372  SculptSession *ss = data->ob->sculpt;
373  const Brush *brush = data->brush;
374  const float *area_no = data->area_no;
375  const float *area_co = data->area_co;
376 
377  PBVHVertexIter vd;
378  float(*proxy)[3];
379  const float bstrength = ss->cache->bstrength;
380 
381  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
382 
383  SculptBrushTest test;
385  ss, &test, data->brush->falloff_shape);
386  const int thread_id = BLI_task_parallel_thread_id(tls);
387 
388  plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
389 
390  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
391  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
392  continue;
393  }
394 
395  if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
396  continue;
397  }
398 
399  float intr[3];
400  float val[3];
402  sub_v3_v3v3(val, intr, vd.co);
403 
404  if (!SCULPT_plane_trim(ss->cache, brush, val)) {
405  continue;
406  }
407 
408  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
409  brush,
410  vd.co,
411  sqrtf(test.dist),
412  vd.no,
413  vd.fno,
414  vd.mask ? *vd.mask : 0.0f,
415  vd.index,
416  thread_id);
417 
418  mul_v3_v3fl(proxy[vd.i], val, fade);
419 
420  if (vd.mvert) {
422  }
423  }
425 }
426 
427 void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
428 {
429  SculptSession *ss = ob->sculpt;
430  Brush *brush = BKE_paint_brush(&sd->paint);
431 
432  const float radius = ss->cache->radius;
433 
434  float area_no[3];
435  float area_co[3];
436  float offset = SCULPT_brush_plane_offset_get(sd, ss);
437 
438  float displace;
439 
440  float temp[3];
441 
442  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
443 
445 
446  displace = radius * offset;
447 
448  mul_v3_v3v3(temp, area_no, ss->cache->scale);
449  mul_v3_fl(temp, displace);
450  add_v3_v3(area_co, temp);
451 
453  .sd = sd,
454  .ob = ob,
455  .brush = brush,
456  .nodes = nodes,
457  .area_no = area_no,
458  .area_co = area_co,
459  };
460 
461  TaskParallelSettings settings;
462  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
463  BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings);
464 }
465 
466 static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
467  const int n,
468  const TaskParallelTLS *__restrict tls)
469 {
470  SculptThreadedTaskData *data = userdata;
471  SculptSession *ss = data->ob->sculpt;
472  const Brush *brush = data->brush;
473  const float *area_no = data->area_no;
474  const float *area_co = data->area_co;
475 
476  PBVHVertexIter vd;
477  float(*proxy)[3];
478  const float bstrength = ss->cache->bstrength;
479 
480  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
481 
482  SculptBrushTest test;
484  ss, &test, data->brush->falloff_shape);
485  const int thread_id = BLI_task_parallel_thread_id(tls);
486  plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
487 
488  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
489  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
490  continue;
491  }
492 
493  if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
494  continue;
495  }
496 
497  float intr[3];
498  float val[3];
500  sub_v3_v3v3(val, intr, vd.co);
501 
502  if (!SCULPT_plane_trim(ss->cache, brush, val)) {
503  continue;
504  }
505 
506  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
507  brush,
508  vd.co,
509  sqrtf(test.dist),
510  vd.no,
511  vd.fno,
512  vd.mask ? *vd.mask : 0.0f,
513  vd.index,
514  thread_id);
515 
516  mul_v3_v3fl(proxy[vd.i], val, fade);
517 
518  if (vd.mvert) {
520  }
521  }
523 }
524 
525 void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
526 {
527  SculptSession *ss = ob->sculpt;
528  Brush *brush = BKE_paint_brush(&sd->paint);
529 
530  const float radius = ss->cache->radius;
531 
532  float area_no[3];
533  float area_co[3];
534  float offset = SCULPT_brush_plane_offset_get(sd, ss);
535 
536  float displace;
537 
538  float temp[3];
539 
540  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
541 
543 
544  displace = -radius * offset;
545 
546  mul_v3_v3v3(temp, area_no, ss->cache->scale);
547  mul_v3_fl(temp, displace);
548  add_v3_v3(area_co, temp);
549 
551  .sd = sd,
552  .ob = ob,
553  .brush = brush,
554  .nodes = nodes,
555  .area_no = area_no,
556  .area_co = area_co,
557  };
558 
559  TaskParallelSettings settings;
560  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
561  BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings);
562 }
563 
566 /* -------------------------------------------------------------------- */
570 static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
571  const int n,
572  const TaskParallelTLS *__restrict tls)
573 {
574  SculptThreadedTaskData *data = userdata;
575  SculptSession *ss = data->ob->sculpt;
576  const Brush *brush = data->brush;
577  float(*mat)[4] = data->mat;
578  const float *area_no_sp = data->area_no_sp;
579  const float *area_co = data->area_co;
580 
581  PBVHVertexIter vd;
582  float(*proxy)[3];
583  const float bstrength = data->clay_strength;
584 
585  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
586 
587  SculptBrushTest test;
589  ss, &test, data->brush->falloff_shape);
590  const int thread_id = BLI_task_parallel_thread_id(tls);
591 
592  float plane_tilt[4];
593  float normal_tilt[3];
594  float imat[4][4];
595 
596  invert_m4_m4(imat, mat);
597  rotate_v3_v3v3fl(normal_tilt, area_no_sp, imat[0], DEG2RADF(-ss->cache->clay_thumb_front_angle));
598 
599  /* Plane aligned to the geometry normal (back part of the brush). */
600  plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp);
601  /* Tilted plane (front part of the brush). */
602  plane_from_point_normal_v3(plane_tilt, area_co, normal_tilt);
603 
604  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
605  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
606  continue;
607  }
608  float local_co[3];
609  mul_v3_m4v3(local_co, mat, vd.co);
610  float intr[3], intr_tilt[3];
611  float val[3];
612 
614  closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
615 
616  /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
617  * coordinates. */
618  /* We can also control the mix with a curve if it produces noticeable artifacts in the center
619  * of the brush. */
620  const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
621  interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
622  sub_v3_v3v3(val, intr_tilt, vd.co);
623 
624  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
625  brush,
626  vd.co,
627  sqrtf(test.dist),
628  vd.no,
629  vd.fno,
630  vd.mask ? *vd.mask : 0.0f,
631  vd.index,
632  thread_id);
633 
634  mul_v3_v3fl(proxy[vd.i], val, fade);
635 
636  if (vd.mvert) {
638  }
639  }
641 }
642 
644 {
645  float final_pressure = 0.0f;
646  for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
647  final_pressure += cache->clay_pressure_stabilizer[i];
648  }
649  return final_pressure / SCULPT_CLAY_STABILIZER_LEN;
650 }
651 
652 void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
653 {
654  SculptSession *ss = ob->sculpt;
655  Brush *brush = BKE_paint_brush(&sd->paint);
656 
657  const float radius = ss->cache->radius;
658  const float offset = SCULPT_brush_plane_offset_get(sd, ss);
659  const float displace = radius * (0.25f + offset);
660 
661  /* Sampled geometry normal and area center. */
662  float area_no_sp[3];
663  float area_no[3];
664  float area_co[3];
665 
666  float temp[3];
667  float mat[4][4];
668  float scale[4][4];
669  float tmat[4][4];
670 
671  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
672 
673  if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
674  SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
675  }
676  else {
677  copy_v3_v3(area_no, area_no_sp);
678  }
679 
680  /* Delay the first daub because grab delta is not setup. */
682  ss->cache->clay_thumb_front_angle = 0.0f;
683  return;
684  }
685 
686  /* Simulate the clay accumulation by increasing the plane angle as more samples are added to the
687  * stroke. */
689  ss->cache->clay_thumb_front_angle += 0.8f;
691  }
692 
694  return;
695  }
696 
697  /* Displace the brush planes. */
698  copy_v3_v3(area_co, ss->cache->location);
699  mul_v3_v3v3(temp, area_no_sp, ss->cache->scale);
700  mul_v3_fl(temp, displace);
701  add_v3_v3(area_co, temp);
702 
703  /* Initialize brush local-space matrix. */
704  cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
705  mat[0][3] = 0.0f;
706  cross_v3_v3v3(mat[1], area_no, mat[0]);
707  mat[1][3] = 0.0f;
708  copy_v3_v3(mat[2], area_no);
709  mat[2][3] = 0.0f;
710  copy_v3_v3(mat[3], ss->cache->location);
711  mat[3][3] = 1.0f;
712  normalize_m4(mat);
713 
714  /* Scale brush local space matrix. */
715  scale_m4_fl(scale, ss->cache->radius);
716  mul_m4_m4m4(tmat, mat, scale);
717  invert_m4_m4(mat, tmat);
718 
719  float clay_strength = ss->cache->bstrength *
721 
723  .sd = sd,
724  .ob = ob,
725  .brush = brush,
726  .nodes = nodes,
727  .area_no_sp = area_no_sp,
728  .area_co = ss->cache->location,
729  .mat = mat,
730  .clay_strength = clay_strength,
731  };
732 
733  TaskParallelSettings settings;
734  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
736 }
737 
740 /* -------------------------------------------------------------------- */
744 static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
745  const int n,
746  const TaskParallelTLS *__restrict tls)
747 {
748  SculptThreadedTaskData *data = userdata;
749  SculptSession *ss = data->ob->sculpt;
750  const Brush *brush = data->brush;
751  const float *area_no = data->area_no;
752  const float *area_co = data->area_co;
753 
754  PBVHVertexIter vd;
755  float(*proxy)[3];
756  const float bstrength = ss->cache->bstrength;
757 
758  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
759 
760  SculptBrushTest test;
762  ss, &test, data->brush->falloff_shape);
763  const int thread_id = BLI_task_parallel_thread_id(tls);
764 
765  plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
766 
767  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
768  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
769  continue;
770  }
771  float intr[3];
772  float val[3];
773 
775 
776  sub_v3_v3v3(val, intr, vd.co);
777 
778  if (SCULPT_plane_trim(ss->cache, brush, val)) {
779  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
780  brush,
781  vd.co,
782  sqrtf(test.dist),
783  vd.no,
784  vd.fno,
785  vd.mask ? *vd.mask : 0.0f,
786  vd.index,
787  thread_id);
788 
789  mul_v3_v3fl(proxy[vd.i], val, fade);
790 
791  if (vd.mvert) {
793  }
794  }
795  }
797 }
798 
799 void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
800 {
801  SculptSession *ss = ob->sculpt;
802  Brush *brush = BKE_paint_brush(&sd->paint);
803 
804  const float radius = ss->cache->radius;
805 
806  float area_no[3];
807  float area_co[3];
808 
809  float offset = SCULPT_brush_plane_offset_get(sd, ss);
810  float displace;
811  float temp[3];
812 
813  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
814 
816 
817  displace = radius * offset;
818 
819  mul_v3_v3v3(temp, area_no, ss->cache->scale);
820  mul_v3_fl(temp, displace);
821  add_v3_v3(area_co, temp);
822 
824  .sd = sd,
825  .ob = ob,
826  .brush = brush,
827  .nodes = nodes,
828  .area_no = area_no,
829  .area_co = area_co,
830  };
831 
832  TaskParallelSettings settings;
833  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
834  BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings);
835 }
836 
839 /* -------------------------------------------------------------------- */
843 typedef struct ClaySampleData {
844  float plane_dist[2];
846 
847 static void calc_clay_surface_task_cb(void *__restrict userdata,
848  const int n,
849  const TaskParallelTLS *__restrict tls)
850 {
851  SculptThreadedTaskData *data = userdata;
852  SculptSession *ss = data->ob->sculpt;
853  const Brush *brush = data->brush;
854  ClaySampleData *csd = tls->userdata_chunk;
855  const float *area_no = data->area_no;
856  const float *area_co = data->area_co;
857  float plane[4];
858 
859  PBVHVertexIter vd;
860 
861  SculptBrushTest test;
863  ss, &test, brush->falloff_shape);
864 
865  /* Apply the brush normal radius to the test before sampling. */
866  float test_radius = sqrtf(test.radius_squared);
867  test_radius *= brush->normal_radius_factor;
868  test.radius_squared = test_radius * test_radius;
869  plane_from_point_normal_v3(plane, area_co, area_no);
870 
871  if (is_zero_v4(plane)) {
872  return;
873  }
874 
875  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
876  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
877  continue;
878  }
879 
880  float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
881  float plane_dist_abs = fabsf(plane_dist);
882  if (plane_dist > 0.0f) {
883  csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
884  }
885  else {
886  csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
887  }
889  }
890 }
891 
892 static void calc_clay_surface_reduce(const void *__restrict UNUSED(userdata),
893  void *__restrict chunk_join,
894  void *__restrict chunk)
895 {
896  ClaySampleData *join = chunk_join;
897  ClaySampleData *csd = chunk;
898  join->plane_dist[0] = MIN2(csd->plane_dist[0], join->plane_dist[0]);
899  join->plane_dist[1] = MIN2(csd->plane_dist[1], join->plane_dist[1]);
900 }
901 
902 static void do_clay_brush_task_cb_ex(void *__restrict userdata,
903  const int n,
904  const TaskParallelTLS *__restrict tls)
905 {
906  SculptThreadedTaskData *data = userdata;
907  SculptSession *ss = data->ob->sculpt;
908  const Brush *brush = data->brush;
909  const float *area_no = data->area_no;
910  const float *area_co = data->area_co;
911 
912  PBVHVertexIter vd;
913  float(*proxy)[3];
914  const float bstrength = fabsf(ss->cache->bstrength);
915 
916  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
917 
918  SculptBrushTest test;
920  ss, &test, data->brush->falloff_shape);
921  const int thread_id = BLI_task_parallel_thread_id(tls);
922 
923  plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
924 
925  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
926  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
927  continue;
928  }
929 
930  float intr[3];
931  float val[3];
933 
934  sub_v3_v3v3(val, intr, vd.co);
935 
936  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
937  brush,
938  vd.co,
939  sqrtf(test.dist),
940  vd.no,
941  vd.fno,
942  vd.mask ? *vd.mask : 0.0f,
943  vd.index,
944  thread_id);
945 
946  mul_v3_v3fl(proxy[vd.i], val, fade);
947 
948  if (vd.mvert) {
950  }
951  }
953 }
954 
955 void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
956 {
957  SculptSession *ss = ob->sculpt;
958  Brush *brush = BKE_paint_brush(&sd->paint);
959 
960  const float radius = fabsf(ss->cache->radius);
961  const float initial_radius = fabsf(ss->cache->initial_radius);
962  bool flip = ss->cache->bstrength < 0.0f;
963 
964  float offset = SCULPT_brush_plane_offset_get(sd, ss);
965  float displace;
966 
967  float area_no[3];
968  float area_co[3];
969  float temp[3];
970 
971  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
972 
973  SculptThreadedTaskData sample_data = {
974  .sd = NULL,
975  .ob = ob,
976  .brush = brush,
977  .nodes = nodes,
978  .totnode = totnode,
979  .area_no = area_no,
980  .area_co = ss->cache->location,
981  };
982 
983  ClaySampleData csd = {{0}};
984 
985  TaskParallelSettings sample_settings;
986  BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
987  sample_settings.func_reduce = calc_clay_surface_reduce;
988  sample_settings.userdata_chunk = &csd;
989  sample_settings.userdata_chunk_size = sizeof(ClaySampleData);
990 
991  BLI_task_parallel_range(0, totnode, &sample_data, calc_clay_surface_task_cb, &sample_settings);
992 
993  float d_offset = (csd.plane_dist[0] + csd.plane_dist[1]);
994  d_offset = min_ff(radius, d_offset);
995  d_offset = d_offset / radius;
996  d_offset = 1.0f - d_offset;
997  displace = fabsf(initial_radius * (0.25f + offset + (d_offset * 0.15f)));
998  if (flip) {
999  displace = -displace;
1000  }
1001 
1002  mul_v3_v3v3(temp, area_no, ss->cache->scale);
1003  mul_v3_fl(temp, displace);
1004  copy_v3_v3(area_co, ss->cache->location);
1005  add_v3_v3(area_co, temp);
1006 
1008  .sd = sd,
1009  .ob = ob,
1010  .brush = brush,
1011  .nodes = nodes,
1012  .area_no = area_no,
1013  .area_co = area_co,
1014  };
1015 
1016  TaskParallelSettings settings;
1017  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1018  BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings);
1019 }
1020 
1021 static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
1022  const int n,
1023  const TaskParallelTLS *__restrict tls)
1024 {
1025  SculptThreadedTaskData *data = userdata;
1026  SculptSession *ss = data->ob->sculpt;
1027  const Brush *brush = data->brush;
1028  float(*mat)[4] = data->mat;
1029  const float *area_no_sp = data->area_no_sp;
1030  const float *area_co = data->area_co;
1031 
1032  PBVHVertexIter vd;
1033  SculptBrushTest test;
1034  float(*proxy)[3];
1035  const bool flip = (ss->cache->bstrength < 0.0f);
1036  const float bstrength = flip ? -ss->cache->bstrength : ss->cache->bstrength;
1037 
1038  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1039 
1040  SCULPT_brush_test_init(ss, &test);
1041  plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp);
1042  const int thread_id = BLI_task_parallel_thread_id(tls);
1043 
1044  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1045  if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
1046  continue;
1047  }
1048 
1049  if (!plane_point_side_flip(vd.co, test.plane_tool, flip)) {
1050  continue;
1051  }
1052 
1053  float intr[3];
1054  float val[3];
1056  sub_v3_v3v3(val, intr, vd.co);
1057 
1058  if (!SCULPT_plane_trim(ss->cache, brush, val)) {
1059  continue;
1060  }
1061  /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
1062  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1063  brush,
1064  vd.co,
1065  ss->cache->radius * test.dist,
1066  vd.no,
1067  vd.fno,
1068  vd.mask ? *vd.mask : 0.0f,
1069  vd.index,
1070  thread_id);
1071 
1072  mul_v3_v3fl(proxy[vd.i], val, fade);
1073 
1074  if (vd.mvert) {
1076  }
1077  }
1079 }
1080 
1081 void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1082 {
1083  SculptSession *ss = ob->sculpt;
1084  Brush *brush = BKE_paint_brush(&sd->paint);
1085 
1086  const bool flip = (ss->cache->bstrength < 0.0f);
1087  const float radius = flip ? -ss->cache->radius : ss->cache->radius;
1088  const float offset = SCULPT_brush_plane_offset_get(sd, ss);
1089  const float displace = radius * (0.18f + offset);
1090 
1091  /* The sculpt-plane normal (whatever its set to). */
1092  float area_no_sp[3];
1093 
1094  /* Geometry normal */
1095  float area_no[3];
1096  float area_co[3];
1097 
1098  float temp[3];
1099  float mat[4][4];
1100  float scale[4][4];
1101  float tmat[4][4];
1102 
1103  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
1104  SCULPT_tilt_apply_to_normal(area_no_sp, ss->cache, brush->tilt_strength_factor);
1105 
1106  if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
1107  SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
1108  }
1109  else {
1110  copy_v3_v3(area_no, area_no_sp);
1111  }
1112 
1113  /* Delay the first daub because grab delta is not setup. */
1115  return;
1116  }
1117 
1118  if (is_zero_v3(ss->cache->grab_delta_symmetry)) {
1119  return;
1120  }
1121 
1122  mul_v3_v3v3(temp, area_no_sp, ss->cache->scale);
1123  mul_v3_fl(temp, displace);
1124  add_v3_v3(area_co, temp);
1125 
1126  /* Clay Strips uses a cube test with falloff in the XY axis (not in Z) and a plane to deform the
1127  * vertices. When in Add mode, vertices that are below the plane and inside the cube are move
1128  * towards the plane. In this situation, there may be cases where a vertex is outside the cube
1129  * but below the plane, so won't be deformed, causing artifacts. In order to prevent these
1130  * artifacts, this displaces the test cube space in relation to the plane in order to
1131  * deform more vertices that may be below it. */
1132  /* The 0.7 and 1.25 factors are arbitrary and don't have any relation between them, they were set
1133  * by doing multiple tests using the default "Clay Strips" brush preset. */
1134  float area_co_displaced[3];
1135  madd_v3_v3v3fl(area_co_displaced, area_co, area_no, -radius * 0.7f);
1136 
1137  /* Initialize brush local-space matrix. */
1138  cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
1139  mat[0][3] = 0.0f;
1140  cross_v3_v3v3(mat[1], area_no, mat[0]);
1141  mat[1][3] = 0.0f;
1142  copy_v3_v3(mat[2], area_no);
1143  mat[2][3] = 0.0f;
1144  copy_v3_v3(mat[3], area_co_displaced);
1145  mat[3][3] = 1.0f;
1146  normalize_m4(mat);
1147 
1148  /* Scale brush local space matrix. */
1149  scale_m4_fl(scale, ss->cache->radius);
1150  mul_m4_m4m4(tmat, mat, scale);
1151 
1152  /* Deform the local space in Z to scale the test cube. As the test cube does not have falloff in
1153  * Z this does not produce artifacts in the falloff cube and allows to deform extra vertices
1154  * during big deformation while keeping the surface as uniform as possible. */
1155  mul_v3_fl(tmat[2], 1.25f);
1156 
1157  invert_m4_m4(mat, tmat);
1158 
1160  .sd = sd,
1161  .ob = ob,
1162  .brush = brush,
1163  .nodes = nodes,
1164  .area_no_sp = area_no_sp,
1165  .area_co = area_co,
1166  .mat = mat,
1167  };
1168 
1169  TaskParallelSettings settings;
1170  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1172 }
1173 
1174 static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
1175  const int n,
1176  const TaskParallelTLS *__restrict tls)
1177 {
1178  SculptThreadedTaskData *data = userdata;
1179  SculptSession *ss = data->ob->sculpt;
1180  const Brush *brush = data->brush;
1181  SculptProjectVector *spvc = data->spvc;
1182  const float *grab_delta = data->grab_delta;
1183 
1184  PBVHVertexIter vd;
1185  float(*proxy)[3];
1186  const float bstrength = ss->cache->bstrength;
1187  const bool do_rake_rotation = ss->cache->is_rake_rotation_valid;
1188  const bool do_pinch = (brush->crease_pinch_factor != 0.5f);
1189  const float pinch = do_pinch ? (2.0f * (0.5f - brush->crease_pinch_factor) *
1190  (len_v3(grab_delta) / ss->cache->radius)) :
1191  0.0f;
1192 
1193  const bool do_elastic = brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC;
1194 
1195  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1196 
1197  SculptBrushTest test;
1199  ss, &test, data->brush->falloff_shape);
1200  const int thread_id = BLI_task_parallel_thread_id(tls);
1201 
1203  BKE_kelvinlet_init_params(&params, ss->cache->radius, bstrength, 1.0f, 0.4f);
1204 
1205  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1206  if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) {
1207  continue;
1208  }
1209 
1210  float fade;
1211  if (do_elastic) {
1212  fade = 1.0f;
1213  }
1214  else {
1215  fade = bstrength * SCULPT_brush_strength_factor(ss,
1216  brush,
1217  vd.co,
1218  sqrtf(test.dist),
1219  vd.no,
1220  vd.fno,
1221  vd.mask ? *vd.mask : 0.0f,
1222  vd.index,
1223  thread_id);
1224  }
1225 
1226  mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
1227 
1228  /* Negative pinch will inflate, helps maintain volume. */
1229  if (do_pinch) {
1230  float delta_pinch_init[3], delta_pinch[3];
1231 
1232  sub_v3_v3v3(delta_pinch, vd.co, test.location);
1233  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
1234  project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
1235  }
1236 
1237  /* Important to calculate based on the grabbed location
1238  * (intentionally ignore fade here). */
1239  add_v3_v3(delta_pinch, grab_delta);
1240 
1241  sculpt_project_v3(spvc, delta_pinch, delta_pinch);
1242 
1243  copy_v3_v3(delta_pinch_init, delta_pinch);
1244 
1245  float pinch_fade = pinch * fade;
1246  /* When reducing, scale reduction back by how close to the center we are,
1247  * so we don't pinch into nothingness. */
1248  if (pinch > 0.0f) {
1249  /* Square to have even less impact for close vertices. */
1250  pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
1251  }
1252  mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
1253  sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
1254  add_v3_v3(proxy[vd.i], delta_pinch);
1255  }
1256 
1257  if (do_rake_rotation) {
1258  float delta_rotate[3];
1259  sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
1260  add_v3_v3(proxy[vd.i], delta_rotate);
1261  }
1262 
1263  if (do_elastic) {
1264  float disp[3];
1265  BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
1266  mul_v3_fl(disp, bstrength * 20.0f);
1267  if (vd.mask) {
1268  mul_v3_fl(disp, 1.0f - *vd.mask);
1269  }
1271  copy_v3_v3(proxy[vd.i], disp);
1272  }
1273 
1274  if (vd.mvert) {
1276  }
1277  }
1279 }
1280 
1281 void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1282 {
1283  SculptSession *ss = ob->sculpt;
1284  Brush *brush = BKE_paint_brush(&sd->paint);
1285  const float bstrength = ss->cache->bstrength;
1286  float grab_delta[3];
1287 
1288  SculptProjectVector spvc;
1289 
1290  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
1291 
1292  if (bstrength < 0.0f) {
1293  negate_v3(grab_delta);
1294  }
1295 
1296  if (ss->cache->normal_weight > 0.0f) {
1297  sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
1298  }
1299 
1300  /* Optionally pinch while painting. */
1301  if (brush->crease_pinch_factor != 0.5f) {
1302  sculpt_project_v3_cache_init(&spvc, grab_delta);
1303  }
1304 
1306  .sd = sd,
1307  .ob = ob,
1308  .brush = brush,
1309  .nodes = nodes,
1310  .spvc = &spvc,
1311  .grab_delta = grab_delta,
1312  };
1313 
1314  TaskParallelSettings settings;
1315  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1317 }
1318 
1319 static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
1320  const int n,
1321  const TaskParallelTLS *__restrict tls)
1322 {
1323  SculptThreadedTaskData *data = userdata;
1324  SculptSession *ss = data->ob->sculpt;
1325  const Brush *brush = data->brush;
1326  const float *cono = data->cono;
1327 
1328  PBVHVertexIter vd;
1329  SculptOrigVertData orig_data;
1330  float(*proxy)[3];
1331  const float bstrength = ss->cache->bstrength;
1332 
1333  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
1334 
1335  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1336 
1337  SculptBrushTest test;
1339  ss, &test, data->brush->falloff_shape);
1340  const int thread_id = BLI_task_parallel_thread_id(tls);
1341 
1342  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1343  SCULPT_orig_vert_data_update(&orig_data, &vd);
1344 
1345  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
1346  continue;
1347  }
1348  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1349  brush,
1350  orig_data.co,
1351  sqrtf(test.dist),
1352  orig_data.no,
1353  NULL,
1354  vd.mask ? *vd.mask : 0.0f,
1355  vd.index,
1356  thread_id);
1357 
1358  mul_v3_v3fl(proxy[vd.i], cono, fade);
1359 
1360  if (vd.mvert) {
1362  }
1363  }
1365 }
1366 
1367 void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1368 {
1369  SculptSession *ss = ob->sculpt;
1370  Brush *brush = BKE_paint_brush(&sd->paint);
1371  float grab_delta[3];
1372  float tmp[3], cono[3];
1373 
1374  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
1375 
1376  cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
1377  cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
1378 
1380  .sd = sd,
1381  .ob = ob,
1382  .brush = brush,
1383  .nodes = nodes,
1384  .cono = cono,
1385  };
1386 
1387  TaskParallelSettings settings;
1388  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1389  BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings);
1390 }
1391 
1392 static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
1393  const int n,
1394  const TaskParallelTLS *__restrict tls)
1395 {
1396  SculptThreadedTaskData *data = userdata;
1397  SculptSession *ss = data->ob->sculpt;
1398  const Brush *brush = data->brush;
1399  const float angle = data->angle;
1400 
1401  PBVHVertexIter vd;
1402  SculptOrigVertData orig_data;
1403  float(*proxy)[3];
1404  const float bstrength = ss->cache->bstrength;
1405 
1406  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
1407 
1408  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1409 
1410  SculptBrushTest test;
1412  ss, &test, data->brush->falloff_shape);
1413  const int thread_id = BLI_task_parallel_thread_id(tls);
1414 
1415  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1416  SCULPT_orig_vert_data_update(&orig_data, &vd);
1417 
1418  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
1419  continue;
1420  }
1421  float vec[3], rot[3][3];
1422  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1423  brush,
1424  orig_data.co,
1425  sqrtf(test.dist),
1426  orig_data.no,
1427  NULL,
1428  vd.mask ? *vd.mask : 0.0f,
1429  vd.index,
1430  thread_id);
1431 
1432  sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
1434  mul_v3_m3v3(proxy[vd.i], rot, vec);
1435  add_v3_v3(proxy[vd.i], ss->cache->location);
1436  sub_v3_v3(proxy[vd.i], orig_data.co);
1437 
1438  if (vd.mvert) {
1440  }
1441  }
1443 }
1444 
1445 void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1446 {
1447  SculptSession *ss = ob->sculpt;
1448  Brush *brush = BKE_paint_brush(&sd->paint);
1449 
1450  static const int flip[8] = {1, -1, -1, 1, -1, 1, 1, -1};
1451  const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
1452 
1454  .sd = sd,
1455  .ob = ob,
1456  .brush = brush,
1457  .nodes = nodes,
1458  .angle = angle,
1459  };
1460 
1461  TaskParallelSettings settings;
1462  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1463  BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings);
1464 }
1465 
1466 static void do_layer_brush_task_cb_ex(void *__restrict userdata,
1467  const int n,
1468  const TaskParallelTLS *__restrict tls)
1469 {
1470  SculptThreadedTaskData *data = userdata;
1471  SculptSession *ss = data->ob->sculpt;
1472  Sculpt *sd = data->sd;
1473  const Brush *brush = data->brush;
1474 
1475  const bool use_persistent_base = ss->persistent_base && brush->flag & BRUSH_PERSISTENT;
1476 
1477  PBVHVertexIter vd;
1478  SculptOrigVertData orig_data;
1479  const float bstrength = ss->cache->bstrength;
1480  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
1481 
1482  SculptBrushTest test;
1484  ss, &test, data->brush->falloff_shape);
1485  const int thread_id = BLI_task_parallel_thread_id(tls);
1486 
1487  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1488  SCULPT_orig_vert_data_update(&orig_data, &vd);
1489 
1490  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
1491  continue;
1492  }
1493  const float fade = SCULPT_brush_strength_factor(ss,
1494  brush,
1495  vd.co,
1496  sqrtf(test.dist),
1497  vd.no,
1498  vd.fno,
1499  vd.mask ? *vd.mask : 0.0f,
1500  vd.index,
1501  thread_id);
1502 
1503  const int vi = vd.index;
1504  float *disp_factor;
1505  if (use_persistent_base) {
1506  disp_factor = &ss->persistent_base[vi].disp;
1507  }
1508  else {
1509  disp_factor = &ss->cache->layer_displacement_factor[vi];
1510  }
1511 
1512  /* When using persistent base, the layer brush (holding Control) invert mode resets the
1513  * height of the layer to 0. This makes possible to clean edges of previously added layers
1514  * on top of the base. */
1515  /* The main direction of the layers is inverted using the regular brush strength with the
1516  * brush direction property. */
1517  if (use_persistent_base && ss->cache->invert) {
1518  (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
1519  ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
1520  }
1521  else {
1522  (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
1523  }
1524  if (vd.mask) {
1525  const float clamp_mask = 1.0f - *vd.mask;
1526  *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
1527  }
1528  else {
1529  *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
1530  }
1531 
1532  float final_co[3];
1533  float normal[3];
1534 
1535  if (use_persistent_base) {
1537  mul_v3_fl(normal, brush->height);
1538  madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
1539  }
1540  else {
1541  copy_v3_v3(normal, orig_data.no);
1542  mul_v3_fl(normal, brush->height);
1543  madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
1544  }
1545 
1546  float vdisp[3];
1547  sub_v3_v3v3(vdisp, final_co, vd.co);
1548  mul_v3_fl(vdisp, fabsf(fade));
1549  add_v3_v3v3(final_co, vd.co, vdisp);
1550 
1551  SCULPT_clip(sd, ss, vd.co, final_co);
1552 
1553  if (vd.mvert) {
1555  }
1556  }
1558 }
1559 
1560 void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1561 {
1562  SculptSession *ss = ob->sculpt;
1563  Brush *brush = BKE_paint_brush(&sd->paint);
1564 
1565  if (ss->cache->layer_displacement_factor == NULL) {
1567  "layer displacement factor");
1568  }
1569 
1571  .sd = sd,
1572  .ob = ob,
1573  .brush = brush,
1574  .nodes = nodes,
1575  };
1576 
1577  TaskParallelSettings settings;
1578  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1579  BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
1580 }
1581 
1582 static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
1583  const int n,
1584  const TaskParallelTLS *__restrict tls)
1585 {
1586  SculptThreadedTaskData *data = userdata;
1587  SculptSession *ss = data->ob->sculpt;
1588  const Brush *brush = data->brush;
1589 
1590  PBVHVertexIter vd;
1591  float(*proxy)[3];
1592  const float bstrength = ss->cache->bstrength;
1593 
1594  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1595 
1596  SculptBrushTest test;
1598  ss, &test, data->brush->falloff_shape);
1599  const int thread_id = BLI_task_parallel_thread_id(tls);
1600 
1601  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1602  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
1603  continue;
1604  }
1605  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1606  brush,
1607  vd.co,
1608  sqrtf(test.dist),
1609  vd.no,
1610  vd.fno,
1611  vd.mask ? *vd.mask : 0.0f,
1612  vd.index,
1613  thread_id);
1614  float val[3];
1615 
1616  if (vd.fno) {
1617  copy_v3_v3(val, vd.fno);
1618  }
1619  else {
1620  copy_v3_v3(val, vd.no);
1621  }
1622 
1623  mul_v3_fl(val, fade * ss->cache->radius);
1624  mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
1625 
1626  if (vd.mvert) {
1628  }
1629  }
1631 }
1632 
1633 void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1634 {
1635  Brush *brush = BKE_paint_brush(&sd->paint);
1636 
1638  .sd = sd,
1639  .ob = ob,
1640  .brush = brush,
1641  .nodes = nodes,
1642  };
1643 
1644  TaskParallelSettings settings;
1645  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1646  BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings);
1647 }
1648 
1649 static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
1650  const int n,
1651  const TaskParallelTLS *__restrict tls)
1652 {
1653  SculptThreadedTaskData *data = userdata;
1654  SculptSession *ss = data->ob->sculpt;
1655  const Brush *brush = data->brush;
1656  const float *cono = data->cono;
1657 
1658  PBVHVertexIter vd;
1659  float(*proxy)[3];
1660  const float bstrength = ss->cache->bstrength;
1661 
1662  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1663 
1664  SculptBrushTest test;
1666  ss, &test, data->brush->falloff_shape);
1667  const int thread_id = BLI_task_parallel_thread_id(tls);
1668 
1669  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1670  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
1671  continue;
1672  }
1673  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1674  brush,
1675  vd.co,
1676  sqrtf(test.dist),
1677  vd.no,
1678  vd.fno,
1679  vd.mask ? *vd.mask : 0.0f,
1680  vd.index,
1681  thread_id);
1682 
1683  mul_v3_v3fl(proxy[vd.i], cono, fade);
1684 
1685  if (vd.mvert) {
1687  }
1688  }
1690 }
1691 
1692 void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1693 {
1694  SculptSession *ss = ob->sculpt;
1695  Brush *brush = BKE_paint_brush(&sd->paint);
1696  float grab_delta[3];
1697  float tmp[3], cono[3];
1698 
1699  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
1700 
1701  cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
1702  cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
1703 
1705  .sd = sd,
1706  .ob = ob,
1707  .brush = brush,
1708  .nodes = nodes,
1709  .cono = cono,
1710  };
1711 
1712  TaskParallelSettings settings;
1713  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1714  BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings);
1715 }
1716 
1719 /* -------------------------------------------------------------------- */
1726 static void do_crease_brush_task_cb_ex(void *__restrict userdata,
1727  const int n,
1728  const TaskParallelTLS *__restrict tls)
1729 {
1730  SculptThreadedTaskData *data = userdata;
1731  SculptSession *ss = data->ob->sculpt;
1732  const Brush *brush = data->brush;
1733  SculptProjectVector *spvc = data->spvc;
1734  const float flippedbstrength = data->flippedbstrength;
1735  const float *offset = data->offset;
1736 
1737  PBVHVertexIter vd;
1738  float(*proxy)[3];
1739 
1740  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1741 
1742  SculptBrushTest test;
1744  ss, &test, data->brush->falloff_shape);
1745  const int thread_id = BLI_task_parallel_thread_id(tls);
1746 
1747  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1748  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
1749  continue;
1750  }
1751  /* Offset vertex. */
1752  const float fade = SCULPT_brush_strength_factor(ss,
1753  brush,
1754  vd.co,
1755  sqrtf(test.dist),
1756  vd.no,
1757  vd.fno,
1758  vd.mask ? *vd.mask : 0.0f,
1759  vd.index,
1760  thread_id);
1761  float val1[3];
1762  float val2[3];
1763 
1764  /* First we pinch. */
1765  sub_v3_v3v3(val1, test.location, vd.co);
1766  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
1767  project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
1768  }
1769 
1770  mul_v3_fl(val1, fade * flippedbstrength);
1771 
1772  sculpt_project_v3(spvc, val1, val1);
1773 
1774  /* Then we draw. */
1775  mul_v3_v3fl(val2, offset, fade);
1776 
1777  add_v3_v3v3(proxy[vd.i], val1, val2);
1778 
1779  if (vd.mvert) {
1781  }
1782  }
1784 }
1785 
1786 void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1787 {
1788  SculptSession *ss = ob->sculpt;
1789  const Scene *scene = ss->cache->vc->scene;
1790  Brush *brush = BKE_paint_brush(&sd->paint);
1791  float offset[3];
1792  float bstrength = ss->cache->bstrength;
1793  float flippedbstrength, crease_correction;
1794  float brush_alpha;
1795 
1796  SculptProjectVector spvc;
1797 
1798  /* Offset with as much as possible factored in already. */
1800  mul_v3_v3(offset, ss->cache->scale);
1801  mul_v3_fl(offset, bstrength);
1802 
1803  /* We divide out the squared alpha and multiply by the squared crease
1804  * to give us the pinch strength. */
1805  crease_correction = brush->crease_pinch_factor * brush->crease_pinch_factor;
1806  brush_alpha = BKE_brush_alpha_get(scene, brush);
1807  if (brush_alpha > 0.0f) {
1808  crease_correction /= brush_alpha * brush_alpha;
1809  }
1810 
1811  /* We always want crease to pinch or blob to relax even when draw is negative. */
1812  flippedbstrength = (bstrength < 0.0f) ? -crease_correction * bstrength :
1813  crease_correction * bstrength;
1814 
1815  if (brush->sculpt_tool == SCULPT_TOOL_BLOB) {
1816  flippedbstrength *= -1.0f;
1817  }
1818 
1819  /* Use surface normal for 'spvc', so the vertices are pinched towards a line instead of a single
1820  * point. Without this we get a 'flat' surface surrounding the pinch. */
1822 
1823  /* Threaded loop over nodes. */
1825  .sd = sd,
1826  .ob = ob,
1827  .brush = brush,
1828  .nodes = nodes,
1829  .spvc = &spvc,
1830  .offset = offset,
1831  .flippedbstrength = flippedbstrength,
1832  };
1833 
1834  TaskParallelSettings settings;
1835  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1836  BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings);
1837 }
1838 
1839 static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
1840  const int n,
1841  const TaskParallelTLS *__restrict tls)
1842 {
1843  SculptThreadedTaskData *data = userdata;
1844  SculptSession *ss = data->ob->sculpt;
1845  const Brush *brush = data->brush;
1846  float(*stroke_xz)[3] = data->stroke_xz;
1847 
1848  PBVHVertexIter vd;
1849  float(*proxy)[3];
1850  const float bstrength = ss->cache->bstrength;
1851 
1852  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1853 
1854  SculptBrushTest test;
1856  ss, &test, data->brush->falloff_shape);
1857  const int thread_id = BLI_task_parallel_thread_id(tls);
1858 
1859  float x_object_space[3];
1860  float z_object_space[3];
1861  copy_v3_v3(x_object_space, stroke_xz[0]);
1862  copy_v3_v3(z_object_space, stroke_xz[1]);
1863 
1864  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1865  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
1866  continue;
1867  }
1868  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
1869  brush,
1870  vd.co,
1871  sqrtf(test.dist),
1872  vd.no,
1873  vd.fno,
1874  vd.mask ? *vd.mask : 0.0f,
1875  vd.index,
1876  thread_id);
1877  float disp_center[3];
1878  float x_disp[3];
1879  float z_disp[3];
1880  /* Calculate displacement from the vertex to the brush center. */
1881  sub_v3_v3v3(disp_center, test.location, vd.co);
1882 
1883  /* Project the displacement into the X vector (aligned to the stroke). */
1884  mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
1885 
1886  /* Project the displacement into the Z vector (aligned to the surface normal). */
1887  mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
1888 
1889  /* Add the two projected vectors to calculate the final displacement.
1890  * The Y component is removed. */
1891  add_v3_v3v3(disp_center, x_disp, z_disp);
1892 
1893  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
1894  project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
1895  }
1896  mul_v3_v3fl(proxy[vd.i], disp_center, fade);
1897 
1898  if (vd.mvert) {
1900  }
1901  }
1903 }
1904 
1905 void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1906 {
1907  SculptSession *ss = ob->sculpt;
1908  Brush *brush = BKE_paint_brush(&sd->paint);
1909 
1910  float area_no[3];
1911  float area_co[3];
1912 
1913  float mat[4][4];
1914  calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co);
1915 
1916  /* delay the first daub because grab delta is not setup */
1918  return;
1919  }
1920 
1921  if (is_zero_v3(ss->cache->grab_delta_symmetry)) {
1922  return;
1923  }
1924 
1925  /* Initialize `mat`. */
1926  cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
1927  mat[0][3] = 0.0f;
1928  cross_v3_v3v3(mat[1], area_no, mat[0]);
1929  mat[1][3] = 0.0f;
1930  copy_v3_v3(mat[2], area_no);
1931  mat[2][3] = 0.0f;
1932  copy_v3_v3(mat[3], ss->cache->location);
1933  mat[3][3] = 1.0f;
1934  normalize_m4(mat);
1935 
1936  float stroke_xz[2][3];
1937  normalize_v3_v3(stroke_xz[0], mat[0]);
1938  normalize_v3_v3(stroke_xz[1], mat[2]);
1939 
1941  .sd = sd,
1942  .ob = ob,
1943  .brush = brush,
1944  .nodes = nodes,
1945  .stroke_xz = stroke_xz,
1946  };
1947 
1948  TaskParallelSettings settings;
1949  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1950  BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
1951 }
1952 
1953 static void do_grab_brush_task_cb_ex(void *__restrict userdata,
1954  const int n,
1955  const TaskParallelTLS *__restrict tls)
1956 {
1957  SculptThreadedTaskData *data = userdata;
1958  SculptSession *ss = data->ob->sculpt;
1959  const Brush *brush = data->brush;
1960  const float *grab_delta = data->grab_delta;
1961 
1962  PBVHVertexIter vd;
1963  SculptOrigVertData orig_data;
1964  float(*proxy)[3];
1965  const float bstrength = ss->cache->bstrength;
1966 
1967  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
1968 
1969  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
1970 
1971  SculptBrushTest test;
1973  ss, &test, data->brush->falloff_shape);
1974  const int thread_id = BLI_task_parallel_thread_id(tls);
1975 
1976  const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE;
1977 
1978  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
1979  SCULPT_orig_vert_data_update(&orig_data, &vd);
1980 
1981  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
1982  continue;
1983  }
1984  float fade = bstrength * SCULPT_brush_strength_factor(ss,
1985  brush,
1986  orig_data.co,
1987  sqrtf(test.dist),
1988  orig_data.no,
1989  NULL,
1990  vd.mask ? *vd.mask : 0.0f,
1991  vd.index,
1992  thread_id);
1993 
1994  if (grab_silhouette) {
1995  float silhouette_test_dir[3];
1996  normalize_v3_v3(silhouette_test_dir, grab_delta);
1997  if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
1998  mul_v3_fl(silhouette_test_dir, -1.0f);
1999  }
2000  float vno[3];
2001  copy_v3_v3(vno, orig_data.no);
2002  fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
2003  }
2004 
2005  mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
2006 
2007  if (vd.mvert) {
2009  }
2010  }
2012 }
2013 
2014 void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2015 {
2016  SculptSession *ss = ob->sculpt;
2017  Brush *brush = BKE_paint_brush(&sd->paint);
2018  float grab_delta[3];
2019 
2020  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
2021 
2022  if (ss->cache->normal_weight > 0.0f) {
2023  sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
2024  }
2025 
2027  .sd = sd,
2028  .ob = ob,
2029  .brush = brush,
2030  .nodes = nodes,
2031  .grab_delta = grab_delta,
2032  };
2033 
2034  TaskParallelSettings settings;
2035  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2036  BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
2037 }
2038 
2039 static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
2040  const int n,
2041  const TaskParallelTLS *__restrict UNUSED(tls))
2042 {
2043  SculptThreadedTaskData *data = userdata;
2044  SculptSession *ss = data->ob->sculpt;
2045  const Brush *brush = data->brush;
2046  const float *grab_delta = data->grab_delta;
2047  const float *location = ss->cache->location;
2048 
2049  PBVHVertexIter vd;
2050  SculptOrigVertData orig_data;
2051  float(*proxy)[3];
2052 
2053  const float bstrength = ss->cache->bstrength;
2054 
2055  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
2056 
2057  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
2058 
2059  float dir;
2060  if (ss->cache->mouse[0] > ss->cache->initial_mouse[0]) {
2061  dir = 1.0f;
2062  }
2063  else {
2064  dir = -1.0f;
2065  }
2066 
2068  int symm = ss->cache->mirror_symmetry_pass;
2069  if (ELEM(symm, 1, 2, 4, 7)) {
2070  dir = -dir;
2071  }
2072  }
2073 
2075  float force = len_v3(grab_delta) * dir * bstrength;
2077  &params, ss->cache->radius, force, 1.0f, brush->elastic_deform_volume_preservation);
2078 
2079  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2080  SCULPT_orig_vert_data_update(&orig_data, &vd);
2081  float final_disp[3];
2082  switch (brush->elastic_deform_type) {
2084  BKE_kelvinlet_grab(final_disp, &params, orig_data.co, location, grab_delta);
2085  mul_v3_fl(final_disp, bstrength * 20.0f);
2086  break;
2088  BKE_kelvinlet_grab_biscale(final_disp, &params, orig_data.co, location, grab_delta);
2089  mul_v3_fl(final_disp, bstrength * 20.0f);
2090  break;
2091  }
2093  BKE_kelvinlet_grab_triscale(final_disp, &params, orig_data.co, location, grab_delta);
2094  mul_v3_fl(final_disp, bstrength * 20.0f);
2095  break;
2096  }
2099  final_disp, &params, orig_data.co, location, ss->cache->sculpt_normal_symm);
2100  break;
2103  final_disp, &params, orig_data.co, location, ss->cache->sculpt_normal_symm);
2104  break;
2105  }
2106 
2107  if (vd.mask) {
2108  mul_v3_fl(final_disp, 1.0f - *vd.mask);
2109  }
2110 
2111  mul_v3_fl(final_disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
2112 
2113  copy_v3_v3(proxy[vd.i], final_disp);
2114 
2115  if (vd.mvert) {
2117  }
2118  }
2120 }
2121 
2122 void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2123 {
2124  SculptSession *ss = ob->sculpt;
2125  Brush *brush = BKE_paint_brush(&sd->paint);
2126  float grab_delta[3];
2127 
2128  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
2129 
2130  if (ss->cache->normal_weight > 0.0f) {
2131  sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
2132  }
2133 
2135  .sd = sd,
2136  .ob = ob,
2137  .brush = brush,
2138  .nodes = nodes,
2139  .grab_delta = grab_delta,
2140  };
2141 
2142  TaskParallelSettings settings;
2143  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2145 }
2146 
2149 /* -------------------------------------------------------------------- */
2153 static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
2154  const int n,
2155  const TaskParallelTLS *__restrict tls)
2156 {
2157  SculptThreadedTaskData *data = userdata;
2158  SculptSession *ss = data->ob->sculpt;
2159  const Brush *brush = data->brush;
2160  const float *offset = data->offset;
2161 
2162  PBVHVertexIter vd;
2163  SculptOrigVertData orig_data;
2164  float(*proxy)[3];
2165 
2166  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
2167 
2168  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
2169 
2170  SculptBrushTest test;
2172  ss, &test, data->brush->falloff_shape);
2173  const int thread_id = BLI_task_parallel_thread_id(tls);
2174 
2175  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2176  SCULPT_orig_vert_data_update(&orig_data, &vd);
2177  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
2178  continue;
2179  }
2180  /* Offset vertex. */
2181  const float fade = SCULPT_brush_strength_factor(ss,
2182  brush,
2183  orig_data.co,
2184  sqrtf(test.dist),
2185  orig_data.no,
2186  NULL,
2187  vd.mask ? *vd.mask : 0.0f,
2188  vd.index,
2189  thread_id);
2190 
2191  mul_v3_v3fl(proxy[vd.i], offset, fade);
2192 
2193  if (vd.mvert) {
2195  }
2196  }
2198 }
2199 
2200 void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2201 {
2202  SculptSession *ss = ob->sculpt;
2203  Brush *brush = BKE_paint_brush(&sd->paint);
2204  float offset[3];
2205  const float bstrength = ss->cache->bstrength;
2206 
2207  /* Offset with as much as possible factored in already. */
2208  float effective_normal[3];
2209  SCULPT_tilt_effective_normal_get(ss, brush, effective_normal);
2210  mul_v3_v3fl(offset, effective_normal, ss->cache->radius);
2211  mul_v3_v3(offset, ss->cache->scale);
2212  mul_v3_fl(offset, bstrength);
2213 
2214  /* XXX: this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
2215  * initialize before threads so they can do curve mapping. */
2216  BKE_curvemapping_init(brush->curve);
2217 
2218  /* Threaded loop over nodes. */
2220  .sd = sd,
2221  .ob = ob,
2222  .brush = brush,
2223  .nodes = nodes,
2224  .offset = offset,
2225  };
2226 
2227  TaskParallelSettings settings;
2228  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2230 }
2231 
2234 /* -------------------------------------------------------------------- */
2238 static void do_topology_slide_task_cb_ex(void *__restrict userdata,
2239  const int n,
2240  const TaskParallelTLS *__restrict tls)
2241 {
2242  SculptThreadedTaskData *data = userdata;
2243  SculptSession *ss = data->ob->sculpt;
2244  const Brush *brush = data->brush;
2245 
2246  PBVHVertexIter vd;
2247  SculptOrigVertData orig_data;
2248  float(*proxy)[3];
2249 
2250  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
2251 
2252  proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
2253 
2254  SculptBrushTest test;
2256  ss, &test, data->brush->falloff_shape);
2257  const int thread_id = BLI_task_parallel_thread_id(tls);
2258 
2259  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2260  SCULPT_orig_vert_data_update(&orig_data, &vd);
2261  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
2262  continue;
2263  }
2264  const float fade = SCULPT_brush_strength_factor(ss,
2265  brush,
2266  orig_data.co,
2267  sqrtf(test.dist),
2268  orig_data.no,
2269  NULL,
2270  vd.mask ? *vd.mask : 0.0f,
2271  vd.index,
2272  thread_id);
2273  float current_disp[3];
2274  float current_disp_norm[3];
2275  float final_disp[3] = {0.0f, 0.0f, 0.0f};
2276 
2277  switch (brush->slide_deform_type) {
2279  sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
2280  break;
2282  sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
2283  break;
2285  sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
2286  break;
2287  }
2288 
2289  normalize_v3_v3(current_disp_norm, current_disp);
2290  mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
2291 
2294  float vertex_disp[3];
2295  float vertex_disp_norm[3];
2296  sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
2297  normalize_v3_v3(vertex_disp_norm, vertex_disp);
2298  if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
2299  madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
2300  }
2301  }
2303 
2304  mul_v3_v3fl(proxy[vd.i], final_disp, fade);
2305 
2306  if (vd.mvert) {
2308  }
2309  }
2311 }
2312 
2314  PBVHVertexIter *vd,
2315  float factor,
2316  bool filter_boundary_face_sets,
2317  float *r_final_pos)
2318 {
2319  float smooth_pos[3];
2320  float final_disp[3];
2321  float boundary_normal[3];
2322  int avg_count = 0;
2323  int neighbor_count = 0;
2324  zero_v3(smooth_pos);
2325  zero_v3(boundary_normal);
2326  const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->index);
2327 
2330  neighbor_count++;
2331  if (!filter_boundary_face_sets ||
2332  (filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.index))) {
2333 
2334  /* When the vertex to relax is boundary, use only connected boundary vertices for the average
2335  * position. */
2336  if (is_boundary) {
2337  if (!SCULPT_vertex_is_boundary(ss, ni.index)) {
2338  continue;
2339  }
2340  add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
2341  avg_count++;
2342 
2343  /* Calculate a normal for the constraint plane using the edges of the boundary. */
2344  float to_neighbor[3];
2345  sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
2346  normalize_v3(to_neighbor);
2347  add_v3_v3(boundary_normal, to_neighbor);
2348  }
2349  else {
2350  add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
2351  avg_count++;
2352  }
2353  }
2354  }
2356 
2357  /* Don't modify corner vertices. */
2358  if (neighbor_count <= 2) {
2359  copy_v3_v3(r_final_pos, vd->co);
2360  return;
2361  }
2362 
2363  if (avg_count > 0) {
2364  mul_v3_fl(smooth_pos, 1.0f / avg_count);
2365  }
2366  else {
2367  copy_v3_v3(r_final_pos, vd->co);
2368  return;
2369  }
2370 
2371  float plane[4];
2372  float smooth_closest_plane[3];
2373  float vno[3];
2374 
2375  if (is_boundary && avg_count == 2) {
2376  normalize_v3_v3(vno, boundary_normal);
2377  }
2378  else {
2379  SCULPT_vertex_normal_get(ss, vd->index, vno);
2380  }
2381 
2382  if (is_zero_v3(vno)) {
2383  copy_v3_v3(r_final_pos, vd->co);
2384  return;
2385  }
2386 
2387  plane_from_point_normal_v3(plane, vd->co, vno);
2388  closest_to_plane_v3(smooth_closest_plane, plane, smooth_pos);
2389  sub_v3_v3v3(final_disp, smooth_closest_plane, vd->co);
2390 
2391  mul_v3_fl(final_disp, factor);
2392  add_v3_v3v3(r_final_pos, vd->co, final_disp);
2393 }
2394 
2395 static void do_topology_relax_task_cb_ex(void *__restrict userdata,
2396  const int n,
2397  const TaskParallelTLS *__restrict tls)
2398 {
2399  SculptThreadedTaskData *data = userdata;
2400  SculptSession *ss = data->ob->sculpt;
2401  const Brush *brush = data->brush;
2402  const float bstrength = ss->cache->bstrength;
2403 
2404  PBVHVertexIter vd;
2405  SculptOrigVertData orig_data;
2406 
2407  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
2408 
2409  BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n]);
2410 
2411  SculptBrushTest test;
2413  ss, &test, data->brush->falloff_shape);
2414  const int thread_id = BLI_task_parallel_thread_id(tls);
2415 
2416  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2417  SCULPT_orig_vert_data_update(&orig_data, &vd);
2418  if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
2419  continue;
2420  }
2421  const float fade = SCULPT_brush_strength_factor(ss,
2422  brush,
2423  orig_data.co,
2424  sqrtf(test.dist),
2425  orig_data.no,
2426  NULL,
2427  vd.mask ? *vd.mask : 0.0f,
2428  vd.index,
2429  thread_id);
2430 
2431  SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
2432  if (vd.mvert) {
2434  }
2435  }
2437 }
2438 
2439 void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2440 {
2441  SculptSession *ss = ob->sculpt;
2442  Brush *brush = BKE_paint_brush(&sd->paint);
2443 
2445  return;
2446  }
2447 
2448  BKE_curvemapping_init(brush->curve);
2449 
2451  .sd = sd,
2452  .ob = ob,
2453  .brush = brush,
2454  .nodes = nodes,
2455  };
2456 
2457  TaskParallelSettings settings;
2458  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2459  if (ss->cache->alt_smooth) {
2461  for (int i = 0; i < 4; i++) {
2462  BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings);
2463  }
2464  }
2465  else {
2466  BLI_task_parallel_range(0, totnode, &data, do_topology_slide_task_cb_ex, &settings);
2467  }
2468 }
2469 
2472 /* -------------------------------------------------------------------- */
2476 static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
2477  const int n,
2478  const TaskParallelTLS *__restrict tls)
2479 {
2480  SculptThreadedTaskData *data = userdata;
2481  SculptSession *ss = data->ob->sculpt;
2482  const Brush *brush = data->brush;
2483  const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
2484 
2485  float(*proxy)[3] = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
2486 
2487  SculptBrushTest test;
2489  ss, &test, data->brush->falloff_shape);
2490  const int thread_id = BLI_task_parallel_thread_id(tls);
2491 
2492  PBVHVertexIter vd;
2493  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2494  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
2495  continue;
2496  }
2497  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
2498  brush,
2499  vd.co,
2500  sqrtf(test.dist),
2501  vd.no,
2502  vd.fno,
2503  vd.mask ? *vd.mask : 0.0f,
2504  vd.index,
2505  thread_id);
2506 
2507  float limit_co[3];
2508  float disp[3];
2509  SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
2510  sub_v3_v3v3(disp, limit_co, vd.co);
2511  mul_v3_v3fl(proxy[vd.i], disp, fade);
2512 
2513  if (vd.mvert) {
2515  }
2516  }
2518 }
2519 
2520 void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2521 {
2522  Brush *brush = BKE_paint_brush(&sd->paint);
2523  BKE_curvemapping_init(brush->curve);
2524 
2525  /* Threaded loop over nodes. */
2527  .sd = sd,
2528  .ob = ob,
2529  .brush = brush,
2530  .nodes = nodes,
2531  };
2532 
2533  TaskParallelSettings settings;
2534  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2536 }
2537 
2540 /* -------------------------------------------------------------------- */
2544 static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata,
2545  const int n,
2546  const TaskParallelTLS *__restrict tls)
2547 {
2548  SculptThreadedTaskData *data = userdata;
2549  SculptSession *ss = data->ob->sculpt;
2550  const Brush *brush = data->brush;
2551  const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
2552 
2553  SculptBrushTest test;
2555  ss, &test, data->brush->falloff_shape);
2556  const int thread_id = BLI_task_parallel_thread_id(tls);
2557 
2558  PBVHVertexIter vd;
2559  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2560  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
2561  continue;
2562  }
2563  const float fade = bstrength * SCULPT_brush_strength_factor(ss,
2564  brush,
2565  vd.co,
2566  sqrtf(test.dist),
2567  vd.no,
2568  vd.fno,
2569  vd.mask ? *vd.mask : 0.0f,
2570  vd.index,
2571  thread_id);
2572 
2573  float current_disp[3];
2574  float current_disp_norm[3];
2575  float interp_limit_surface_disp[3];
2576 
2577  copy_v3_v3(interp_limit_surface_disp, ss->cache->prev_displacement[vd.index]);
2578 
2579  switch (brush->smear_deform_type) {
2581  sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
2582  break;
2584  sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
2585  break;
2587  sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
2588  break;
2589  }
2590 
2591  normalize_v3_v3(current_disp_norm, current_disp);
2592  mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
2593 
2594  float weights_accum = 1.0f;
2595 
2598  float vertex_disp[3];
2599  float vertex_disp_norm[3];
2600  float neighbor_limit_co[3];
2601  SCULPT_vertex_limit_surface_get(ss, ni.index, neighbor_limit_co);
2602  sub_v3_v3v3(vertex_disp,
2603  ss->cache->limit_surface_co[ni.index],
2604  ss->cache->limit_surface_co[vd.index]);
2605  const float *neighbor_limit_surface_disp = ss->cache->prev_displacement[ni.index];
2606  normalize_v3_v3(vertex_disp_norm, vertex_disp);
2607 
2608  if (dot_v3v3(current_disp_norm, vertex_disp_norm) >= 0.0f) {
2609  continue;
2610  }
2611 
2612  const float disp_interp = clamp_f(
2613  -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
2614  madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp);
2615  weights_accum += disp_interp;
2616  }
2618 
2619  mul_v3_fl(interp_limit_surface_disp, 1.0f / weights_accum);
2620 
2621  float new_co[3];
2622  add_v3_v3v3(new_co, ss->cache->limit_surface_co[vd.index], interp_limit_surface_disp);
2623  interp_v3_v3v3(vd.co, vd.co, new_co, fade);
2624 
2625  if (vd.mvert) {
2627  }
2628  }
2630 }
2631 
2633  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
2634 {
2635  SculptThreadedTaskData *data = userdata;
2636  SculptSession *ss = data->ob->sculpt;
2637 
2638  PBVHVertexIter vd;
2639  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2641  SCULPT_vertex_co_get(ss, vd.index),
2642  ss->cache->limit_surface_co[vd.index]);
2643  }
2645 }
2646 
2647 void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2648 {
2649  Brush *brush = BKE_paint_brush(&sd->paint);
2650  SculptSession *ss = ob->sculpt;
2651 
2652  BKE_curvemapping_init(brush->curve);
2653 
2654  const int totvert = SCULPT_vertex_count_get(ss);
2655  if (!ss->cache->prev_displacement) {
2657  totvert, sizeof(float[3]), "prev displacement");
2658  ss->cache->limit_surface_co = MEM_malloc_arrayN(totvert, sizeof(float[3]), "limit surface co");
2659  for (int i = 0; i < totvert; i++) {
2662  SCULPT_vertex_co_get(ss, i),
2663  ss->cache->limit_surface_co[i]);
2664  }
2665  }
2666  /* Threaded loop over nodes. */
2668  .sd = sd,
2669  .ob = ob,
2670  .brush = brush,
2671  .nodes = nodes,
2672  };
2673 
2674  TaskParallelSettings settings;
2675  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2677  0, totnode, &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings);
2679 }
2680 
2683 /* -------------------------------------------------------------------- */
2687 static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
2688  const int n,
2689  const TaskParallelTLS *__restrict tls)
2690 {
2691  SculptThreadedTaskData *data = userdata;
2692  SculptSession *ss = data->ob->sculpt;
2693  Sculpt *sd = data->sd;
2694  const Brush *brush = data->brush;
2695 
2696  float direction[3];
2697  copy_v3_v3(direction, ss->cache->grab_delta_symmetry);
2698 
2699  float tmp[3];
2700  mul_v3_v3fl(
2701  tmp, ss->cache->sculpt_normal_symm, dot_v3v3(ss->cache->sculpt_normal_symm, direction));
2702  sub_v3_v3(direction, tmp);
2703  normalize_v3(direction);
2704 
2705  /* Cancel if there's no grab data. */
2706  if (is_zero_v3(direction)) {
2707  return;
2708  }
2709 
2710  const float bstrength = clamp_f(data->strength, 0.0f, 1.0f);
2711 
2712  SculptBrushTest test;
2714  ss, &test, data->brush->falloff_shape);
2715  const int thread_id = BLI_task_parallel_thread_id(tls);
2716 
2717  PBVHVertexIter vd;
2718  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2719  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
2720  continue;
2721  }
2722  const float fade =
2723  bstrength *
2725  ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
2726  ss->cache->pressure;
2727 
2728  float avg[3], val[3];
2729 
2730  SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
2731 
2732  sub_v3_v3v3(val, avg, vd.co);
2733 
2734  madd_v3_v3v3fl(val, vd.co, val, fade);
2735 
2736  SCULPT_clip(sd, ss, vd.co, val);
2737 
2738  if (vd.mvert) {
2740  }
2741  }
2743 }
2744 
2746  Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength)
2747 {
2748  Brush *brush = BKE_paint_brush(&sd->paint);
2749  const float strength = clamp_f(bstrength, 0.0f, 1.0f);
2750 
2751  /* Interactions increase both strength and quality. */
2752  const int iterations = 3;
2753 
2754  int iteration;
2755  const int count = iterations * strength + 1;
2756  const float factor = iterations * strength / count;
2757 
2758  for (iteration = 0; iteration <= count; iteration++) {
2759 
2761  .sd = sd,
2762  .ob = ob,
2763  .brush = brush,
2764  .nodes = nodes,
2765  .strength = factor,
2766  };
2767  TaskParallelSettings settings;
2768  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2769 
2771  }
2772 }
2773 
2776 /* -------------------------------------------------------------------- */
2780 static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
2781  const int n,
2782  const TaskParallelTLS *__restrict tls)
2783 {
2784  SculptThreadedTaskData *data = userdata;
2785  SculptSession *ss = data->ob->sculpt;
2786  const Brush *brush = data->brush;
2787  const float bstrength = ss->cache->bstrength;
2788 
2789  PBVHVertexIter vd;
2790 
2791  SculptBrushTest test;
2793  ss, &test, data->brush->falloff_shape);
2794  const int thread_id = BLI_task_parallel_thread_id(tls);
2795 
2796  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
2797  if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
2798  continue;
2799  }
2800 
2801  const float fade = SCULPT_brush_strength_factor(
2802  ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
2803 
2804  if (bstrength > 0.0f) {
2805  (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
2806  }
2807  else {
2808  (*vd.mask) += fade * bstrength * (*vd.mask);
2809  }
2810  *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
2811  }
2813 }
2814 
2815 void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2816 {
2817  Brush *brush = BKE_paint_brush(&sd->paint);
2818 
2819  /* Threaded loop over nodes. */
2821  .sd = sd,
2822  .ob = ob,
2823  .brush = brush,
2824  .nodes = nodes,
2825  };
2826 
2827  TaskParallelSettings settings;
2828  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2830 }
2831 
2832 void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2833 {
2834  SculptSession *ss = ob->sculpt;
2835  Brush *brush = BKE_paint_brush(&sd->paint);
2836 
2837  switch ((BrushMaskTool)brush->mask_tool) {
2838  case BRUSH_MASK_DRAW:
2839  SCULPT_do_mask_brush_draw(sd, ob, nodes, totnode);
2840  break;
2841  case BRUSH_MASK_SMOOTH:
2842  SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true);
2843  break;
2844  }
2845 }
2846 
typedef float(TangentPoint)[2]
float BKE_brush_alpha_get(const struct Scene *scene, const struct Brush *brush)
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
void BKE_kelvinlet_grab(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float brush_delta[3])
Definition: kelvinlet.c:51
void BKE_kelvinlet_grab_triscale(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float brush_delta[3])
Definition: kelvinlet.c:87
void BKE_kelvinlet_init_params(KelvinletParams *params, float radius, float force, float shear_modulus, float poisson_ratio)
Definition: kelvinlet.c:13
void BKE_kelvinlet_grab_biscale(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float brush_delta[3])
Definition: kelvinlet.c:68
void BKE_kelvinlet_scale(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float surface_normal[3])
Definition: kelvinlet.c:163
void BKE_kelvinlet_twist(float radius_elem_disp[3], const KelvinletParams *params, const float elem_orig_co[3], const float brush_location[3], const float surface_normal[3])
Definition: kelvinlet.c:191
General operations, lookup, etc. for blender objects.
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:607
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:439
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:509
void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
Definition: pbvh.c:1967
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:391
PBVHProxyNode * BKE_pbvh_node_add_proxy(PBVH *pbvh, PBVHNode *node)
Definition: pbvh.c:3016
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3211
MINLINE float max_ff(float a, float b)
MINLINE float pow2f(float x)
MINLINE float clamp_f(float value, float min, float max)
MINLINE float min_ff(float a, float b)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:408
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
Definition: math_geom.c:461
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:401
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2297
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:897
void normalize_m4(float R[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1945
void pow_qt_fl_normalized(float q[4], float f)
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle)
#define DEG2RADF(_deg)
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:59
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:33
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], float angle)
Definition: math_vector.c:800
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3(float r[3])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool is_zero_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
Definition: math_vector.c:638
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
#define ARRAY_SET_ITEMS(...)
#define UNUSED(x)
#define ELEM(...)
#define MIN2(a, b)
@ BRUSH_SMEAR_DEFORM_PINCH
@ BRUSH_SMEAR_DEFORM_EXPAND
@ BRUSH_SMEAR_DEFORM_DRAG
@ SCULPT_DISP_DIR_VIEW
@ SCULPT_DISP_DIR_X
@ SCULPT_DISP_DIR_Z
@ SCULPT_DISP_DIR_Y
@ SCULPT_DISP_DIR_AREA
@ BRUSH_ORIGINAL_NORMAL
@ BRUSH_ORIGINAL_PLANE
@ BRUSH_PERSISTENT
@ BRUSH_SNAKE_HOOK_DEFORM_ELASTIC
@ SCULPT_TOOL_BLOB
@ BRUSH_ELASTIC_DEFORM_SCALE
@ BRUSH_ELASTIC_DEFORM_GRAB
@ BRUSH_ELASTIC_DEFORM_TWIST
@ BRUSH_ELASTIC_DEFORM_GRAB_BISCALE
@ BRUSH_ELASTIC_DEFORM_GRAB_TRISCALE
@ PAINT_FALLOFF_SHAPE_TUBE
@ BRUSH_GRAB_SILHOUETTE
BrushMaskTool
@ BRUSH_MASK_DRAW
@ BRUSH_MASK_SMOOTH
@ BRUSH_SLIDE_DEFORM_DRAG
@ BRUSH_SLIDE_DEFORM_EXPAND
@ BRUSH_SLIDE_DEFORM_PINCH
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
Platform independent time functions.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
Scene scene
#define rot(x, k)
IconTextureDrawCall normal
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
int count
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: noise.h:15
BLI_INLINE void flip_v3(float v[3], const ePaintSymmetryFlags symm)
Definition: paint_intern.h:437
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:125
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:111
void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
Definition: sculpt.c:1300
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt.c:1290
void SCULPT_boundary_info_ensure(Object *object)
Definition: sculpt.c:5848
int SCULPT_plane_point_side(const float co[3], const float plane[4])
Definition: sculpt.c:2996
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:239
bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
Definition: sculpt.c:662
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss, SculptBrushTest *test, char falloff_shape)
Definition: sculpt.c:1686
void SCULPT_tilt_effective_normal_get(const SculptSession *ss, const Brush *brush, float r_no[3])
Definition: sculpt.c:2767
void SCULPT_calc_area_normal_and_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
Definition: sculpt.c:2151
float SCULPT_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], const float len, const float vno[3], const float fno[3], const float mask, const int vertex_index, const int thread_id)
Definition: sculpt.c:2370
bool SCULPT_brush_test_cube(SculptBrushTest *test, const float co[3], const float local[4][4], const float roundness)
Definition: sculpt.c:1639
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:171
void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3])
Definition: sculpt.c:218
bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index)
Definition: sculpt.c:865
float SCULPT_brush_plane_offset_get(Sculpt *sd, SculptSession *ss)
Definition: sculpt.c:3002
bool SCULPT_stroke_is_main_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:906
void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test)
Definition: sculpt.c:1532
void SCULPT_tilt_apply_to_normal(float r_normal[3], StrokeCache *cache, const float tilt_strength)
Definition: sculpt.c:2751
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:918
int SCULPT_plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3])
Definition: sculpt.c:2990
void SCULPT_calc_brush_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
Definition: sculpt.c:2901
void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
Definition: sculpt.c:2103
const float * SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
Definition: sculpt.c:193
void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
Definition: sculpt.c:2540
void SCULPT_calc_area_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3])
Definition: sculpt.c:2054
float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert)
static void sculpt_project_v3_normal_align(SculptSession *ss, const float normal_weight, float grab_delta[3])
void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3], float r_vec[3])
static void do_fill_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip)
void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_clay_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_relax_vertex(SculptSession *ss, PBVHVertexIter *vd, float factor, bool filter_boundary_face_sets, float *r_final_pos)
static void do_topology_slide_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void sculpt_project_v3_cache_init(SculptProjectVector *spvc, const float plane[3])
static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_rotate_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_displacement_smear_store_prev_disp_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
static void do_pinch_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void sculpt_rake_rotate(const SculptSession *ss, const float sculpt_co[3], const float v_co[3], float factor, float r_delta[3])
static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
static void do_crease_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_nudge_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
struct SculptProjectVector SculptProjectVector
void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void calc_clay_surface_reduce(const void *__restrict UNUSED(userdata), void *__restrict chunk_join, void *__restrict chunk)
static void do_scrape_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_grab_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_layer_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
static void do_thumb_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_topology_relax_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_inflate_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void do_draw_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_bmesh_topology_rake(Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength)
float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache)
static void do_flatten_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void calc_clay_surface_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
struct ClaySampleData ClaySampleData
void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
bool(* SculptBrushTestFn)(SculptBrushTest *test, const float co[3])
#define SCULPT_CLAY_STABILIZER_LEN
void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], struct BMVert *v)
Definition: sculpt_smooth.c:89
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
void SCULPT_smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength, bool smooth_mask)
@ SCULPT_UNDO_COORDS
int sculpt_plane
int snake_hook_deform_type
int slide_deform_type
int elastic_deform_type
float normal_radius_factor
float elastic_deform_volume_preservation
struct CurveMapping * curve
char falloff_shape
float tilt_strength_factor
float height
float crease_pinch_factor
char mask_tool
char sculpt_tool
int smear_deform_type
float tip_roundness
struct SculptSession * sculpt
float(* co)[3]
Definition: BKE_pbvh.h:47
struct MVert * mvert
Definition: BKE_pbvh.h:428
float * co
Definition: BKE_pbvh.h:430
float * fno
Definition: BKE_pbvh.h:432
float * no
Definition: BKE_pbvh.h:431
struct BMVert * bm_vert
Definition: BKE_pbvh.h:429
float * mask
Definition: BKE_pbvh.h:433
float plane_tool[4]
const float * co
Definition: sculpt_intern.h:87
const float * no
Definition: sculpt_intern.h:88
struct StrokeCache * cache
Definition: BKE_paint.h:563
SculptPersistentBase * persistent_base
Definition: BKE_paint.h:606
struct PBVH * pbvh
Definition: BKE_paint.h:550
struct Sculpt * sd
Paint paint
float initial_radius
float initial_mouse[2]
float sculpt_normal[3]
float mouse[2]
float scale[3]
float plane_offset[3]
float true_view_normal[3]
float last_location[3]
float initial_normal[3]
int mirror_symmetry_pass
float view_normal[3]
struct ViewContext * vc
float sculpt_normal_symm[3]
float(* limit_surface_co)[3]
float last_center[3]
float grab_delta_symmetry[3]
float location[3]
AutomaskingCache * automasking
float(* prev_displacement)[3]
bool is_rake_rotation_valid
float normal_weight
float vertex_rotation
float * layer_displacement_factor
float clay_pressure_stabilizer[SCULPT_CLAY_STABILIZER_LEN]
float clay_thumb_front_angle
float rake_rotation_symmetry[4]
float symm_rot_mat[4][4]
TaskParallelReduceFunc func_reduce
Definition: BLI_task.h:181
size_t userdata_chunk_size
Definition: BLI_task.h:169
struct Scene * scene
Definition: ED_view3d.h:65